精华内容
下载资源
问答
  • php中关于AES加密对应Java中的SHA1PRNG方式加密的实例详解
    2021-03-23 19:48:01

    做对接的时候,服务商做的AES加密通过SHA1PRNG算法(只要password一样,每次生成的数组都是一样的,所以可以用来做加密解密的key)进行了又一次加密,搞了好几个小时,直接看对应的代码吧,可以参考一下,只有Java的加密源码

    private static byte[] encrypt(byte[] byteContent, byte[] password) throws Exception

    {

    KeyGenerator kgen = KeyGenerator.getInstance("AES");

    SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

    secureRandom.setSeed(password);

    kgen.init(128, secureRandom);

    SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded();

    SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

    Cipher cipher = Cipher.getInstance("AES");

    cipher.init(1, key); byte[] result = cipher.doFinal(byteContent); return result;

    }

    private function _pkcs5Pad($text, $blockSize)

    {

    $pad = $blockSize - (strlen($text) % $blockSize);

    return $text . str_repeat(chr($pad), $pad);

    }

    private function _pkcs5Unpad($text)

    {

    $end = substr($text, -1);

    $last = ord($end);

    $len = strlen($text) - $last;

    if(substr($text, $len) == str_repeat($end, $last))

    {

    return substr($text, 0, $len);

    }

    return false;

    }

    public function encrypt($encrypt, $key)

    {

    $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);

    $paddedData = $this->_pkcs5Pad($encrypt, $blockSize);

    $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);

    $iv = mcrypt_create_iv($ivSize, MCRYPT_RAND);

    $key2 = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16);

    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key2, $paddedData, MCRYPT_MODE_ECB, $iv);

    return base64_encode($encrypted);

    }

    public function decrypt($decrypt, $key)

    {

    $decoded = $this->hex2bin($decrypt);

    $blockSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);

    $iv = mcrypt_create_iv($blockSize, MCRYPT_RAND);

    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decoded, MCRYPT_MODE_ECB, $iv);

    return $this->_pkcs5Unpad($decrypted);

    }

    function hex2bin($str)

    {

    $sbin = "";

    $len = strlen($str);

    for($i = 0; $i < $len; $i += 2)

    {

    $sbin .= pack("H*", substr($str, $i, 2));

    }

    return $sbin;

    }

    更多相关内容
  • Python - AES SHA1PRNG 加密解密总结

    千次阅读 2020-11-12 16:17:36
    Python - AES sha1prng 加密解密总结 Max.Bai 2020-11 上篇文章是当时研究AES加密的时候的记录,来龙去脉可以取看这篇 python3 - AES 加密实现java中SHA1PRNG 算法 好多人回复并提问,我发现还有必要写这篇做...

    Python - AES SHA1PRNG 加密解密总结

    Max.Bai

    2020-11

     

    上篇文章是当时研究AES加密的时候的记录,来龙去脉可以取看这篇 python3 - AES 加密实现java中SHA1PRNG 算法

    好多人回复并提问,我发现还有必要写这篇做一个总结,并写成了一个开箱即用类,添加了ECB,CBC的加解密,当然也包含SHA1PRNG,如果其他类型可以参照里面代码添加其他加密模式。

    加解密的流程总结:

    0. 确认加密模式、ECB、CBC等

    1. key,看是否需要sha1prng, 看是否需要做padding,cbc的需要16的倍数,所有需要padding为16的倍数,或者你自己的padding方法。

    2. 加密内容确认填充模式,被加密内容当为CBC的时候必须16倍数,当然就涉及到了填充模式pkcs5/7, zero deng

    3. iv 只有CBC的时候需要, iv必须16倍数,要么填充,要么iv设置成16倍数

    4. 确认加密输出格式 base64、hexstr

    加密流程:

            key --> sha1prng encode | padding | customencode

            content --> padding --> transfer to bytes --> encrypt(ECB/CBC/...) --> transfer to format(base64/hexstr)

     

    解密流程:

            key --> sha1prng encode|padding|customencode

            encrypted(base64/hexstr) --> transfer to bytes --> decrypt(ECB/CBC/...) --> unpadding --> transfer to str

            codding by max.bai 2020-11

     

    开箱即用的完整的代码:

    包含了ECB、CBC的样例。

    # -*- coding: utf-8 -*-
    
    """
    AES crypt
    
    requirment mode:
    pycryptodome
    
    For Java SHA1PRNG KEY
    
    Max.Bai
    2020-11
    
    """
    import base64
    from Crypto.Util.Padding import pad, unpad
    from Crypto.Util.py3compat import bchr, bord
    import Crypto.Cipher.AES as AES
    import hashlib
    
    BS = AES.block_size
    
    
    class AES_Crypt:
        PADDING_PKCS5 = "PKCS5"
        PADDING_PKCS7 = "PKCS7"
        PADDING_ZERO = "ZEROPKCS"
        NO_PADDING = "NOPKCS"
    
        def __init__(self, key: bytes, mode: str = AES.MODE_ECB, padding: str = "NOPKCS") -> None:
            """AES crypt
    
            Encrypt fllow:
            key --> sha1prng encode|padding|customencode
            content --> padding --> transfer to bytes --> encrypt(ECB/CBC/...) --> transfer to format(base64/hexstr)
    
            Decrypt fllow:
            key --> sha1prng encode|padding|customencode
            encrypted(base64/hexstr) --> transfer to bytes --> decrypt(ECB/CBC/...) --> unpadding --> transfer to str
            codding by max.bai 2020-11
    
            Args:
                key (bytes): encrypt key, if mode is CBC, the key must be 16X len.
                mode (str, optional): AES mode. Defaults to AES.MODE_ECB.
                padding (str, optional): AES padding mode. Defaults to "NOPKCS".
            """
            self.key = key
            self.pkcs = padding
    
        @staticmethod
        def get_sha1prng_key(key: str, byte_len:int=128) -> bytes:
            """
            encrypt key with SHA1PRNG
            same as java AES crypto key generator SHA1PRNG
            key: encode/decode key
            byte_len: length of key gen,  same as java code kgen.init(128, secureRandom);
                     default is 128
            """
            signature = hashlib.sha1(key.encode()).digest()
            signature = hashlib.sha1(signature).digest()
            len = int(byte_len/8)
            return signature[:len]
    
        @staticmethod
        def padding_pkcs5(value: str) -> bytes:
            """padding pkcs5 mode
    
            Args:
                value (str): need padding data
    
            Returns:
                bytes: after padding data with bytes type
            """
            padding_len = BS - len(value.encode()) % BS
            return value.encode() + bchr(padding_len) * padding_len
    
        @staticmethod
        def padding_zero(value: str) -> bytes:
            """padding with zero
    
            Args:
                value (str): need padding data
    
            Returns:
                bytes: after padding data with zero with bytes type
            """
            while len(value) % 16 != 0:
                value += "\0"
            return str.encode(value)
    
        @staticmethod
        def unpadding_pkcs5(value: bytes) -> bytes:
            """unpadding pkcs5 mode
    
            Args:
                value (bytes): need unpadding data
    
            Returns:
                bytes: after unpadding
            """
            padding_len = bord(value[-1])
            return value[:-padding_len]
    
        @staticmethod
        def unpadding_zero(value: bytes) -> bytes:
            """unpadding zero mode
    
            Args:
                value (bytes): need unpadding data
    
            Returns:
                bytes: after unpadding
            """
            return value
    
        @staticmethod
        def bytes_to_base64(value: bytes) -> str:
            """
            bytes transfer to base64 format
            """
            return base64.b64encode(value).decode()
    
        @staticmethod
        def base64_to_bytes(value: str) -> bytes:
            """
            base64 transfer to bytes
            """
            return base64.b64decode(value)
    
        @staticmethod
        def bytes_to_hex(value: bytes) -> str:
            """
            bytes transfer to hex str format
            """
            return value.hex().upper()
    
        def _get_padding_value(self, content: str) -> bytes:
            """get padding value from padding data
            Only add pkcs5, pkcs7, zero, nopadding mode,
            you can add your padding mode and unpadding mode in this
            section
            Args:
                content (str): need padding data
    
            Raises:
                Exception: no supporting padding mode 
    
            Returns:
                bytes: padded data
            """
            if self.pkcs == AES_Crypt.PADDING_PKCS5:
                padding_value = self.padding_pkcs5(content)
            elif self.pkcs == AES_Crypt.PADDING_PKCS7:
                padding_value = pad(content.encode(), BS, style='pkcs7')
            elif self.pkcs == AES_Crypt.PADDING_ZERO:
                padding_value = self.padding_zero(content)
            elif self.pkcs == AES_Crypt.NO_PADDING:
                padding_value = str.encode(content)
            else:
                raise Exception("No supporting padding mode! Not implation padding mode!")
            return padding_value
    
        def _get_unpadding_value(self, content: bytes) -> bytes:
            """get unpadding value from padded data
            Only add pkcs5, pkcs7, zero, nopadding mode,
            you can add your padding mode and unpadding mode in this
            section
            Args:
                content (str): need unpadding data
    
            Raises:
                Exception: no supporting padding mode 
    
            Returns:
                bytes: unpadded data
            """
            if self.pkcs == AES_Crypt.PADDING_PKCS5:
                unpadding_value = self.unpadding_pkcs5(content)
            elif self.pkcs == AES_Crypt.PADDING_PKCS7:
                unpadding_value = unpad(content, BS, style='pkcs7')
            elif self.pkcs == AES_Crypt.PADDING_ZERO:
                unpadding_value = self.unpadding_zero(content)
            elif self.pkcs == AES_Crypt.NO_PADDING:
                unpadding_value = content
            else:
                raise Exception("No supporting padding mode! Not implation padding mode!")
    
            return unpadding_value
    
        # ECB encrypt
        def ECB_encrypt_to_bytes(self, content: str) -> bytes:
            """ECB encrypt to bytes type
    
            Args:
                content (str): need encrypt content
    
            Returns:
                bytes: encrypted content with bytes type
            """
            cryptor = AES.new(self.key, AES.MODE_ECB)
    
            padding_value = self._get_padding_value(content)
    
            ciphertext = cryptor.encrypt(padding_value)
            return ciphertext
    
        def ECB_encrypt_to_base64(self, content: str) -> str:
            """ECB encrypt to base64 format
    
            Args:
                content (str): need encrypt content
    
            Returns:
                str: encrypted content with base64 format
            """
            ciphertext = self.ECB_encrypt_to_bytes(content)
            return self.bytes_to_base64(ciphertext)
    
        def ECB_encrypt_to_hex(self, content: str) -> str:
            """ECB encrypt to hex str format
    
            Args:
                content (str): need encrypt content
    
            Returns:
                str: encrypted content with hex str format
            """
            ciphertext = self.ECB_encrypt_to_bytes(content)
            return self.bytes_to_hex(ciphertext)
    
        # ECB decrypt
        def ECB_decrypt_from_bytes(self, ciphertext: bytes) -> bytes:
            """ECB decrypt from bytes type
    
            Args:
                ciphertext (bytes): need decrypt data
    
            Returns:
                bytes: decrypted content with bytes type
            """
            cryptor = AES.new(self.key, AES.MODE_ECB)
            content = cryptor.decrypt(ciphertext)
    
            unpadding_value = self._get_unpadding_value(content)
            return unpadding_value
    
        def ECB_decrypt_from_base64(self, ciphertext: str) -> str:
            """ECB decrypt from base64 format
    
    
            Args:
                ciphertext (str): need decrypt data
    
            Returns:
                str: decrypted content
            """
            ciphertext_bytes = self.base64_to_bytes(ciphertext)
            content = self.ECB_decrypt_from_bytes(ciphertext_bytes)
            return content.decode()
    
        def ECB_decrypt_from_hex(self, ciphertext: str) -> str:
            """ECB decrypt from hex str format
    
    
            Args:
                ciphertext (str): need decrypt data
    
            Returns:
                str: decrypted content
            """
            content = self.ECB_decrypt_from_bytes(bytes.fromhex(ciphertext))
            return content.decode()
    
        # CBC encrypt
        def CBC_encrypt_to_bytes(self, content: str, iv: str) -> bytes:
            """CBC encrypt to bytes type
    
            Args:
                content (str): need encrypt content, must 16x length
                iv (str): iv, need 16X len
    
            Returns:
                bytes: encrypted data
            """        
            cryptor = AES.new(self.key, AES.MODE_CBC, iv=iv.encode())
    
            padding_value = self._get_padding_value(content)
    
            ciphertext = cryptor.encrypt(padding_value)
            return ciphertext
    
        def CBC_encrypt_to_base64(self, content: str, iv: str) -> str:
            """CBC encrypt to base64 format
    
            Args:
                content (str): need encrypt content, must 16x length
                iv (str): iv, need 16X len
    
            Returns:
                str: encrypted data with base64 format
            """
            ciphertext = self.CBC_encrypt_to_bytes(content, iv)
            return self.bytes_to_base64(ciphertext)
        
        def CBC_encrypt_to_hex(self, content: str, iv: str) -> str:
            """CBC encrypt to hex str format
    
            Args:
                content (str): need encrypt content, must 16x length
                iv (str): iv, need 16X len
    
            Returns:
                str: encrypted data with hex str format
            """
            ciphertext = self.CBC_encrypt_to_bytes(content, iv)
            return self.bytes_to_hex(ciphertext)
    
        # CBC decrypt
        def CBC_decrypt_from_bytes(self, ciphertext: bytes, iv: str) -> bytes:
            """ECB decrypt from bytes type
    
            Args:
                ciphertext (bytes): need decrypt data
                iv (str): iv, need 16X len
    
            Returns:
                bytes: decrypted content with bytes type
            """
            cryptor = AES.new(self.key, AES.MODE_CBC, iv=iv.encode())
            content = cryptor.decrypt(ciphertext)
    
            unpadding_value = self._get_unpadding_value(content)
            return unpadding_value
    
        def CBC_decrypt_from_base64(self, ciphertext: str, iv: str) -> str:
            """ECB decrypt from base64 format
    
            Args:
                ciphertext (str): need decrypt data
                iv (str): iv, need 16X len
    
            Returns:
                str: decrypted content
            """
            ciphertext_bytes = self.base64_to_bytes(ciphertext)
            content = self.CBC_decrypt_from_bytes(ciphertext_bytes, iv)
            return content.decode()
        
        def CBC_decrypt_from_hex(self, ciphertext: str, iv: str) -> str:
            """ECB decrypt from hex str format
    
            Args:
                ciphertext (str): need decrypt data
                iv (str): iv, need 16X len
    
            Returns:
                str: decrypted content
            """
            content = self.CBC_decrypt_from_bytes(bytes.fromhex(ciphertext), iv)
            return content.decode()
    
    
    if __name__ == "__main__":
        # AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demo
        print("----------- AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demo")
        key = "12532802"  # 加密key
        content = "405EE11002F3"  # 原文
        encrypt_res = "c1ee1f3f2d74e02706be9af78aa79ba4".upper()
        print("content:", content, "key:", key, "exepct:", encrypt_res)
        AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.PADDING_PKCS5)
        print("encrypt res", AES_Cryptor.ECB_encrypt_to_hex(content))
        print("decrypt content", AES_Cryptor.ECB_decrypt_from_hex(encrypt_res))
    
        # AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demo
        print("")
        print("----------- AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demo")
        key = "max.bai"  # 加密key
        content = "csdn博客"  # 原文
        encrypt_res = "97A1B39A480291AD5D38F603C169C644".upper()
        print("content:", content, "key:", key, "exepct:", encrypt_res)
        AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.PADDING_PKCS5)
        print("encrypt res", AES_Cryptor.ECB_encrypt_to_hex(content))
        print("decrypt content", AES_Cryptor.ECB_decrypt_from_hex(encrypt_res))
    
        # AES/ECB/nopkcs | no sha1prng key | hex format demo
        print("")   
        print("----------- AES/ECB/nopkcs | no sha1prng key | hex format demo")
        # 这个demo 有点绕,不看也行
        key = "43C8B53E236C4756B8FF24E5AA08A549"  # 加密key
        content = "0513011E0005016400000000000000000001000000000000000000000000000000770013011E0005026400000000000000000001000000000000000000000000000000770013011E0005036400000000000000000001000000000000000000000000000000770013011E0005046400000000000000000001000000000000000000000000000000770013011E000505640000000000000000000100000000000000000000000000000077000000000000"  # 原文
        # 我简单解释下,就是,加密的内容是已经转为16进制了, key也是转为16进制了,所以加密前和解密后都进行了相应的处理
        encrypt_res = "AB4F4686218A5FF9F07E5248E6B5525D140602A0FAA21176C9A158A010B1A7C0258E80667BF7DD3B6FF57707B373BF75F57AE634D9F1384002AA6B788F4C658DD77572C207AAE3134F91FB690A4F024EF428DE3E1C5F84D0EA9D01B8AB4ED9FE97D7C0D65D447D92F0E306573F30E1360B3DE999E952BAAB9B22E48B8C7B23DC5480027DEE44988F0E86F7A475EEF599C1D7D3331457E582558BC3447E644913ABD63FC221C2E0D49BD712879261FF5F"  # 加密结果
        print("content:", content, "key:", key, "exepct:", encrypt_res)
        AES_Cryptor = AES_Crypt(bytes.fromhex(key))
        content_from_hex = str(bytes.fromhex(content), encoding="utf-8")
        print("encrypt res", AES_Cryptor.ECB_encrypt_to_hex(content_from_hex))
        de_res = AES_Cryptor.ECB_decrypt_from_hex(encrypt_res)
        de_content_from_bytes_to_hex_str = bytes.fromhex(content).hex()
        print("decrypt content", de_content_from_bytes_to_hex_str)
    
        # AES/CBC/nopadding | sha1prng key | hex format encrypt result demo
        print("")
        print("----------- AES/CBC/nopadding | sha1prng key | hex format encrypt result demo")
        key = "max.bai"  # 加密key, 如果非sha1prng,必须16倍数
        content = "csdn博客文章csdn博客文章"  # 原文 必须16倍数
        iv = '1234567812345678'  # 必须16位
        encrypt_res = "D7DE3D8BBF560BE941EAAE9229879BD20A5ED24976ECCE96187EDC36D0EA0C56".upper()
        print("content:", content, "key:", key, "exepct:", encrypt_res)
        AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.NO_PADDING)
        print("encrypt res", AES_Cryptor.CBC_encrypt_to_hex(content, iv=iv))
        print("decrypt content", AES_Cryptor.CBC_decrypt_from_hex(encrypt_res, iv=iv))
    
        # AES/CBC/pkcs5 | sha1prng key | hex format encrypt result demo
        print("")
        print("----------- AES/CBC/pkcs5 | sha1prng key | hex format encrypt result demo")
        key = "max.bai"  # 加密key 如果非sha1prng,必须16倍数
        content = "csdn博客文章csdn博客文章"  # 原文 如果nopadding必须16倍数
        iv = '1234567812345678'  # 必须16位
        encrypt_res = "D7DE3D8BBF560BE941EAAE9229879BD20A5ED24976ECCE96187EDC36D0EA0C564BB4F1208BCDC202969709A5CC4543C7".upper()
        print("content:", content, "key:", key, "exepct:", encrypt_res)
        AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.PADDING_PKCS5)
        print("encrypt res", AES_Cryptor.CBC_encrypt_to_hex(content, iv=iv))
        print("decrypt content", AES_Cryptor.CBC_decrypt_from_hex(encrypt_res, iv=iv))
    
        # AES/CBC/pkcs5 | no sha1prng key | hex format encrypt result demo
        print("")
        print("----------- AES/CBC/pkcs5 | no sha1prng key | hex format encrypt result demo")
        key = "max.bai"  # 加密key 如果非sha1prng,必须16倍数
        content = "csdn博客文章csdn博客文章"  # 原文 必须16倍数
        iv = '1234567812345678'  # 必须16位
        encrypt_res = "1a9821e44e483f0a5c39cea0b7d5bd2a47e1b5dc00fd29cf4ddedf08e7931f567cec0d35f5d960967c7f7c066c09263d".upper()
        print("content:", content, "key:", key, "exepct:", encrypt_res)
        # key 不够16倍数,padding zero
        AES_Cryptor = AES_Crypt(AES_Crypt.padding_zero(key), padding=AES_Crypt.PADDING_PKCS5)
        print("encrypt res", AES_Cryptor.CBC_encrypt_to_hex(content, iv=iv))
        print("decrypt content", AES_Cryptor.CBC_decrypt_from_hex(encrypt_res, iv=iv))
    
        # AES/CBC/pkcs5 | no sha1prng key | bas64 format encrypt result demo
        print("")
        print("----------- AES/CBC/pkcs5 | no sha1prng key | bas64 format encrypt result demo")
        key = "max.bai"  # 加密key 如果非sha1prng,必须16倍数
        content = "csdn博客文章"  # 原文  如果nopadding必须16倍数
        iv = '1234567812345678'  # 必须16位
        encrypt_res = "Gpgh5E5IPwpcOc6gt9W9KimbhGPwnBRpSeA6kcZGN/g="
        print("content:", content, "key:", key, "exepct:", encrypt_res)
        # key 不够16倍数,padding zero
        AES_Cryptor = AES_Crypt(AES_Crypt.padding_zero(key), padding=AES_Crypt.PADDING_PKCS5)
        print("encrypt res", AES_Cryptor.CBC_encrypt_to_base64(content, iv=iv))
        print("decrypt content", AES_Cryptor.CBC_decrypt_from_base64(encrypt_res, iv=iv))

     

    展开全文
  • 本文主要介绍 java AES 中出现的随机算法SHA1PRNG 生成key,在 golang 中的实现方法 描述 先来看 java 代码 // java 代码 // content:test123 // encryptKey:123456 // 加密结果为:668C826342B8703D86E8BBF...

    前言

    和不同语言的第三方对接不可避免的遇到语言不一致的问题,比如加解密,有关于 golang 的 CBC/ECB/CFB 加密方法,这篇博客写的很全 传送门->

    本文主要介绍 java AES 中出现的随机算法 SHA1PRNG 生成key,在 golang 中的实现方法

    描述

    先来看 java 代码

    // java 代码
    // content:test123
    // encryptKey:123456
    // 加密结果为:668C826342B8703D86E8BBF404610499
    public static byte[] encrypt(String content, String encryptKey) {
        try {
          KeyGenerator kgen = KeyGenerator.getInstance("AES");
          SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
          secureRandom.setSeed(encryptKey.getBytes());
    
          kgen.init(128, secureRandom);
          SecretKey secretKey = kgen.generateKey();
          byte[] enCodeFormat = secretKey.getEncoded();
          SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
          Cipher cipher = Cipher.getInstance("AES"); // AES 和 AES/ECB/PKCS5Padding 等价
          byte[] byteContent = content.getBytes("utf-8");
          cipher.init(1, key);
          byte[] result = cipher.doFinal(byteContent);
          return result;
        } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
        } catch (NoSuchPaddingException e) {
          e.printStackTrace();
        } catch (InvalidKeyException e) {
          e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
          e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
          e.printStackTrace();
        } catch (BadPaddingException e) {
          e.printStackTrace();
        }
        return null;
      }

    然后来看 golang 代码,示例1:

    // go 代码
    // content:test123
    // encryptKey:123456
    // 加密结果为:A794E6B031BFA05023B8C4577CA60595
    // 如果直接用下面这个标准方法加密,得出来的结果和 java 中是不一致的,是因为对 key 缺少类似java SHA1PRNG的处理
    func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {
    	cipher, _ := aes.NewCipher(generateKey(key))
    	length := (len(origData) + aes.BlockSize) / aes.BlockSize
    	plain := make([]byte, length*aes.BlockSize)
    	copy(plain, origData)
    	pad := byte(len(plain) - len(origData))
    	for i := len(origData); i < len(plain); i++ {
    		plain[i] = pad
    	}
    	encrypted = make([]byte, len(plain))
    	// 分组分块加密
    	for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
    		cipher.Encrypt(encrypted[bs:be], plain[bs:be])
    	}
    
    	return encrypted
    }

    示例2:

    // content:test123
    // encryptKey:123456
    // 加密结果为:668C826342B8703D86E8BBF404610499
    // 此时就和 java 结果相对应了,解密也一样对 key 加一步处理就行
    func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {
    	key, _ = AesSha1prng(key, 128) // 比示例一多出这一步
    
    	cipher, _ := aes.NewCipher(generateKey(key))
    	length := (len(origData) + aes.BlockSize) / aes.BlockSize
    	plain := make([]byte, length*aes.BlockSize)
    	copy(plain, origData)
    	pad := byte(len(plain) - len(origData))
    	for i := len(origData); i < len(plain); i++ {
    		plain[i] = pad
    	}
    	encrypted = make([]byte, len(plain))
    	// 分组分块加密
    	for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
    		cipher.Encrypt(encrypted[bs:be], plain[bs:be])
    	}
    
    	return encrypted
    }
    
    // 模拟 java SHA1PRNG 处理
    func AesSha1prng(keyBytes []byte, encryptLength int) ([]byte, error) {
    	hashs := Sha1(Sha1(keyBytes))
    	maxLen := len(hashs)
    	realLen := encryptLength / 8
    	if realLen > maxLen {
    		return nil, errors.New("invalid length!")
    	}
    
    	return hashs[0:realLen], nil
    }
    
    func Sha1(data []byte) []byte {
    	h := sha1.New()
    	h.Write(data)
    	return h.Sum(nil)
    }
    
    func generateKey(key []byte) (genKey []byte) {
    	genKey = make([]byte, 16)
    	copy(genKey, key)
    	for i := 16; i < len(key); {
    		for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
    			genKey[j] ^= key[i]
    		}
    	}
    	return genKey
    }

    加解密完整demo(2021-08-26更新)

    有同学说示例不完整,在此补充一下吧 ~~

    package test
    
    import (
    	"crypto/aes"
    	"crypto/sha1"
    	"encoding/hex"
    	"errors"
    	"testing"
    )
    
    func Test_Crypto(t *testing.T) {
    	str := []byte("test123")
    	key := []byte("123456")
    	// 加密
    	res, err := AesEncryptECB(str, key)
    	if err != nil {
    		t.Fatal(err)
    	}
    	t.Log(hex.EncodeToString(res)) // 输出:668c826342b8703d86e8bbf404610499
    
    	// 解密
    	de, err := AesDecryptECB(res, key)
    	if err != nil {
    		t.Fatal(err)
    	}
    	t.Log(string(de))
    }
    
    // content:test123
    // encryptKey:123456
    // 加密结果为:668C826342B8703D86E8BBF404610499
    // 此时就和 java 结果相对应了,解密也一样对 key 加一步处理就行
    func AesEncryptECB(src []byte, key []byte) ([]byte, error) {
    	key, err := AesSha1prng(key, 128) // 比示例一多出这一步
    	if err != nil {
    		return nil, err
    	}
    
    	cipher, _ := aes.NewCipher(generateKey(key))
    	length := (len(src) + aes.BlockSize) / aes.BlockSize
    	plain := make([]byte, length*aes.BlockSize)
    	copy(plain, src)
    	pad := byte(len(plain) - len(src))
    	for i := len(src); i < len(plain); i++ {
    		plain[i] = pad
    	}
    	encrypted := make([]byte, len(plain))
    	// 分组分块加密
    	for bs, be := 0, cipher.BlockSize(); bs <= len(src); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
    		cipher.Encrypt(encrypted[bs:be], plain[bs:be])
    	}
    
    	return encrypted, nil
    }
    
    func AesDecryptECB(encrypted []byte, key []byte) ([]byte, error) {
    	key, err := AesSha1prng(key, 128) // 比示例一多出这一步
    	if err != nil {
    		return nil, err
    	}
    
    	cipher, _ := aes.NewCipher(generateKey(key))
    	decrypted := make([]byte, len(encrypted))
    	//
    	for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
    		cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
    	}
    
    	trim := 0
    	if len(decrypted) > 0 {
    		trim = len(decrypted) - int(decrypted[len(decrypted)-1])
    	}
    
    	return decrypted[:trim], nil
    }
    
    // 模拟 java SHA1PRNG 处理
    func AesSha1prng(keyBytes []byte, encryptLength int) ([]byte, error) {
    	hashs := Sha1(Sha1(keyBytes))
    	maxLen := len(hashs)
    	realLen := encryptLength / 8
    	if realLen > maxLen {
    		return nil, errors.New("invalid length!")
    	}
    
    	return hashs[0:realLen], nil
    }
    
    func Sha1(data []byte) []byte {
    	h := sha1.New()
    	h.Write(data)
    	return h.Sum(nil)
    }
    
    func generateKey(key []byte) (genKey []byte) {
    	genKey = make([]byte, 16)
    	copy(genKey, key)
    	for i := 16; i < len(key); {
    		for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
    			genKey[j] ^= key[i]
    		}
    	}
    	return genKey
    }
    

    总结

    总的来说两者差不多,但是直接使用 golang 中的 AES ECB来进行加解密是有问题的,这点从在线加解密网站也可以看出来,对于 java 中进行了 SHA1PRNG 处理数据是结果是对应不上的!

    参考博文:golang:实现Java 中的 AES SHA1PRNG算法_OceanStar的博客-CSDN博客

    感谢您的阅读,欢迎点赞、关注、收藏!如果文章中有任何错误,或者您有更好的理解和建议,也欢迎和我联系!

    展开全文
  • python3 - AES 加密实现java中SHA1PRNG 算法

    万次阅读 热门讨论 2019-02-18 20:39:49
    python3 - Java AES 加密实现java中SHA1PRNG 算法 Max.Bai 2019-02 0x00 事由 最近和java项目对接遇到AES加密算法,java代码有SecureRandom.getInstance("SHA1PRNG"); python实在找不到对应的方法,C#,php,...

    python3 - Java AES 加密实现java中SHA1PRNG 算法

    Max.Bai

    2019-02

    目录

    python3 - Java AES 加密实现java中SHA1PRNG 算法

    0x00 事由

    0x01 Java实现

    0x02 Python3实现

    0x03 总结

    0x04 完整代码


    0x00 事由

    最近和java项目对接遇到AES加密算法,java代码有SecureRandom.getInstance("SHA1PRNG"); python实在找不到对应的方法,C#,php,js代码各种查到,大家都有遇到,解决的不多,C# 直接用java算出key,然后用C#再算AES(https://blog.csdn.net/yunhua_lee/article/details/17226089),耗时差不多2天,最终在php代码中找到方法(https://github.com/myGGT/crypt_aes/blob/master/crypt_aes.php),相关JavaScript代码(https://github.com/bombworm/SHA1PRNG/blob/master/index.js),记录下来给大家使用。

    鉴于讨论的人多我在2020-11做一个总结,并写了一个开箱即用的类,可去这篇查看:Python - AES sha1prng 加密解密总结  更新于2020-11

     

    0x01 Java实现

    Java 加密参数说明(使用库)

    AES加密模式ECB/CBC/CTR/OFB/CFB
    填充pkcs5padding/pkcs7padding/zeropadding/iso10126/ansix923
    数据块128位/192位/256位

    我们就以java默认AES加密方法为例,其他加密模拟基本都是对key的处理一样。Java默认AES加密模式是"AES/ECB/PKCS5Padding"。

    java代码:

    
    public static String AES_Encode(String encodeRules,String content){
        try {
            //1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator keygen=KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            //keygen.init(128, new SecureRandom(encodeRules.getBytes()));
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(encodeRules.getBytes());
            keygen.init(128, secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key=keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte [] raw=original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key=new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher=Cipher.getInstance("AES");
            //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte [] byte_encode=content.getBytes("utf-8");
            //9.根据密码器的初始化方式--加密:将数据加密
            byte [] byte_AES=cipher.doFinal(byte_encode);
            //10.将加密后的数据转换为字符串
            //这里用Base64Encoder中会找不到包
            //解决办法:
            //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
    
            //String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
            String AES_encode = new String(bytesToHexString(byte_AES));
            //11.将字符串返回
            return AES_encode;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    
        //如果有错就返加nulll
        return null;
    }

    最主要的代码:

                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                secureRandom.setSeed(keyWord.getBytes());
                kgen.init(128, secureRandom);
                SecretKey secretKey = kgen.generateKey();

    这几行就是要把密码进行了别的加密。坑就在这里,stackoverflow上建议修改java代码,1.指明加密方式和填充 2.不要使用SecureRandom,这个是Oracle实现的,可能在不同版本会产生不同的值,特别是Android(https://blog.csdn.net/banking17173/article/details/8236028)。 stackoverflow(https://stackoverflow.com/questions/24124091/better-way-to-create-aes-keys-than-seeding-securerandom)。

    0x02 Python3实现

    安装AES相关库

    pip3 install pycryptodome

    实现代码:

    from base64 import b64encode, encodebytes
    from Crypto.Cipher import AES
    import binascii
    import hashlib
    
    BS = AES.block_size
    
    
    def padding_pkcs5(value):
        return str.encode(value + (BS - len(value) % BS) * chr(BS - len(value) % BS))
    
    
    def padding_zero(value):
        while len(value) % 16 != 0:
            value += '\0'
        return str.encode(value)
    
    def aes_ecb_encrypt(key, value):
        # AES/ECB/PKCS5padding
        # key is sha1prng encrypted before
        cryptor = AES.new(bytes.fromhex(key), AES.MODE_ECB)
        padding_value = padding_pkcs5(value)    # padding content with pkcs5
        ciphertext = cryptor.encrypt(padding_value)
        return ''.join(['%02x' % i for i in ciphertext]).upper()
    
    def get_sha1prng_key(key):
        '''[summary]
        encrypt key with SHA1PRNG
        same as java AES crypto key generator SHA1PRNG
        Arguments:
            key {[string]} -- [key]
        
        Returns:
            [string] -- [hexstring]
        '''
        signature = hashlib.sha1(key.encode()).digest()
        signature = hashlib.sha1(signature).digest()
        return ''.join(['%02x' % i for i in signature]).upper()[:32]
    
    
    
    hexstr_content = '405EE11002F3'    #content
    key = '12532802'  #keypassword
    expect_result = 'c1ee1f3f2d74e02706be9af78aa79ba4'.upper()
    aes128string = aes_ecb_encrypt(get_sha1png_key(key), hexstr_content)
    print(aes128string)
    

    关键代码:

    def get_sha1prng_key(key):
        '''[summary]
        encrypt key with SHA1PRNG
        same as java AES crypto key generator SHA1PRNG
        Arguments:
            key {[string]} -- [key]
        
        Returns:
            [string] -- [hexstring]
        '''
        signature = hashlib.sha1(key.encode()).digest()
        signature = hashlib.sha1(signature).digest()
        return ''.join(['%02x' % i for i in signature]).upper()[:32]

    实现key的转换,实现了java中关键代码的内容。这里返回的是16进制字符串,你可以修改代码返回想要的格式。

    实现了关键代码,其他CBC等加密方式都一样。

    0x03 总结

    看好多人问,我总结下步骤:

    1. 对key进行sha1prng加密,就是文中的get_sha1prng_key方法,拿到加密后的密文当做AES的key

    2.确定AES的加密方式ECB,CBC 等,

    3. 确定填充方式,0填充(文中padding_zero方法),pkcs5填充(文中padding_pkcs5方法),或者不填充

    4. 传入key, 原文,iv(CBC需要), 进行AES加密,获得结果

    CBC 还要传入iv 进行处理

    AES加密可以参照https://blog.csdn.net/max229max/article/details/70318782

    AES主要注意两个:

    1. 加密方法ECB,CBC等。

    2. 对key的处理,比如java的sha1prng,或者base64等。

    3. 填充,key和原始文本都有可能填充,NoPadding,不填充,0填充,还有pkcs5padding, 不填充就是不对内容填充,直接加密,上面代码实现了\0填充和pkcs5padding 。

    总的来说加密内容对不上基本是key处理不一样或者填充不对。

    0x04 完整代码

    完整代码包含了一点解密代码,不过解密代码没有填充,如果有填充的话,解密完内容需要去掉填充。

    from base64 import b64encode, encodebytes
    from Crypto.Cipher import AES
    import binascii
    import hashlib
    
    BS = AES.block_size
    
    
    def padding_pkcs5(value):
        return str.encode(value + (BS - len(value) % BS) * chr(BS - len(value) % BS))
    
    
    def padding_zero(value):
        while len(value) % 16 != 0:
            value += '\0'
        return str.encode(value)
        
        
    def aes_ecb_encrypt(key, value):
        ''' AES/ECB/NoPadding encrypt '''
        key = bytes.fromhex(key)
        cryptor = AES.new(key, AES.MODE_ECB)
        ciphertext = cryptor.encrypt(bytes.fromhex(value))
        return ''.join(['%02x' % i for i in ciphertext]).upper()
    
    def aes_ecb_decrypt(key:str, value:str) -> str:
        ''' AES/ECB/NoPadding decrypt '''
        key = bytes.fromhex(key)
        cryptor = AES.new(key, AES.MODE_ECB)
        ciphertext = cryptor.decrypt(bytes.fromhex(value))
        return ''.join(['%02x' % i for i in ciphertext]).upper()
    
    def get_userkey(key, value):
        ''' AES/ECB/PKCS5Padding encrypt 
        就是一个普通的AES ECB加密,填充方式是PKCS5Padding 
        '''
        cryptor = AES.new(bytes.fromhex(key), AES.MODE_ECB)
        padding_value = padding_pkcs5(value)
        ciphertext = cryptor.encrypt(padding_value)
        return ''.join(['%02x' % i for i in ciphertext]).upper()
    
    def get_sha1prng_key(key):
        '''[summary]
        encrypt key with SHA1PRNG
        same as java AES crypto key generator SHA1PRNG
        Arguments:
            key {[string]} -- [key]
        
        Returns:
            [string] -- [hexstring]
        '''
        signature = hashlib.sha1(key.encode()).digest()
        signature = hashlib.sha1(signature).digest()
        return ''.join(['%02x' % i for i in signature]).upper()[:32]
    
    
    # 普通AES ECB加解密
    data = '0513011E0005016400000000000000000001000000000000000000000000000000770013011E0005026400000000000000000001000000000000000000000000000000770013011E0005036400000000000000000001000000000000000000000000000000770013011E0005046400000000000000000001000000000000000000000000000000770013011E000505640000000000000000000100000000000000000000000000000077000000000000'   # 原文
    key = '43C8B53E236C4756B8FF24E5AA08A549'   #加密key
    aes_result = 'AB4F4686218A5FF9F07E5248E6B5525D140602A0FAA21176C9A158A010B1A7C0258E80667BF7DD3B6FF57707B373BF75F57AE634D9F1384002AA6B788F4C658DD77572C207AAE3134F91FB690A4F024EF428DE3E1C5F84D0EA9D01B8AB4ED9FE97D7C0D65D447D92F0E306573F30E1360B3DE999E952BAAB9B22E48B8C7B23DC5480027DEE44988F0E86F7A475EEF599C1D7D3331457E582558BC3447E644913ABD63FC221C2E0D49BD712879261FF5F'   #加密结果
    # 加密
    aes128string = aes_ecb_encrypt(key, data)
    print(aes128string)
    # 解密
    aes128string = aes_ecb_decrypt(key, aes_result)
    print(aes128string)
    
    # sha1prng 加密方式
    mac = '405EE11002F3'   #原文
    device_id = '12532802' #'12403492' #'12532802'  # 加密key
    user_key = 'c1ee1f3f2d74e02706be9af78aa79ba4'.upper()  # 加密结果
    
    # 加密  
    # 1.对key 进行sha1prng加密, 就是方法get_sha1png_key
    # 2.用加密后的key进行AES AES/ECB/PKCS5Padding 加密, 
    # 注意看你的java代码AES加密方式,填充方式,我这里是ECB加密,填充方式是PKCS5Padding 
    # get_userkey 方法就是普通的 AES/ECB/PKCS5Padding 加密
    # https://blog.csdn.net/max229max/article/details/70318782  这篇有AES的ECB和CBC加密
    aes128string = get_userkey(get_sha1png_key(device_id), mac)
    print(aes128string)
    
    
    # 58F7CD929BFAA0915032536FBA8D3281420E93E3
    # 58f7cd929bfaa0915032536fba8d3281
    # 58F7CD929BFAA0915032536FBA8D3281
    print(get_sha1png_key('12532802')) # 58f7cd929bfaa0915032536fba8d3281

    完整java代码:

    package javatest;
    
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.io.File; 
    import java.io.InputStreamReader; 
    import java.io.BufferedReader; 
    import java.io.BufferedWriter; 
    import java.io.FileInputStream; 
    import java.io.FileWriter; 
    import java.nio.charset.Charset;
    
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Base64;
    import java.util.Scanner;
    import java.util.Arrays;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.KeyGenerator;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    
    //import sun.misc.BASE64Decoder;
    //import sun.misc.BASE64Encoder;
    //import RC4;
    
    public class AESEncode {
    public static String bytesToHexString(byte[] src){
             StringBuilder stringBuilder = new StringBuilder("");
             if (src == null || src.length <= 0) {
                     return null;
             }
             for (int i = 0; i < src.length; i++) {
                     int v = src[i] & 0xFF;
                     String hv = Integer.toHexString(v);
                     if (hv.length() < 2) {
                             stringBuilder.append(0);
                     }
                     stringBuilder.append(hv);
             }
             return stringBuilder.toString();
    }
    
    public static byte[] hexStringToBytes(String hexString) {
    	if (hexString == null || hexString.equals("")) {
    		return null;
            }
            hexString = hexString.toUpperCase();
            int length = hexString.length() / 2;
            char[] hexChars = hexString.toCharArray();
            byte[] d = new byte[length];
            for (int i = 0; i < length; i++) {
                int pos = i * 2;
                d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
             }
             return d;
    }
    
    private static byte charToByte(char c) {
    	    return (byte) "0123456789ABCDEF".indexOf(c);
    }
    
    
    
    
    public static String AES_Encode(String encodeRules,String content){
        try {
            //1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator keygen=KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            //keygen.init(128, new SecureRandom(encodeRules.getBytes()));
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(encodeRules.getBytes());
            kgen.init(128, secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key=keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte [] raw=original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key=new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher=Cipher.getInstance("AES");
            //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte [] byte_encode=content.getBytes("utf-8");
            //9.根据密码器的初始化方式--加密:将数据加密
            byte [] byte_AES=cipher.doFinal(byte_encode);
            //10.将加密后的数据转换为字符串
            //这里用Base64Encoder中会找不到包
            //解决办法:
            //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
    
            //String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
            String AES_encode = new String(bytesToHexString(byte_AES));
            //11.将字符串返回
            return AES_encode;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    
        //如果有错就返加nulll
        return null;
    }
    /*
     * 解密
     * 解密过程:
     * 1.同加密1-4步
     * 2.将加密后的字符串反纺成byte[]数组
     * 3.将加密内容解密
     */
    public static String AES_Decode(String encodeRules,String content){
    	String ss;
        try {
            //1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator keygen=KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            //keygen.init(128, new SecureRandom(encodeRules.getBytes()));
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(encodeRules.getBytes());
            kgen.init(128, secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key=keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte [] raw=original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key=new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher=Cipher.getInstance("AES");
            //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);
            //8.将加密并编码后的内容解码成字节数组
            byte [] byte_content=hexStringToBytes(content);
            //byte [] byte_content= new BASE64Decoder().decodeBuffer(content);
            //System.out.println("ttttttttttttttttttttttttttt");
            //System.out.println(new String(byte_content, "UTF-8"));
            /*
             * 解密
             */
            byte [] byte_decode=cipher.doFinal(byte_content);
            String AES_decode=new String(byte_decode,"utf-8");
            return AES_decode;
        } catch (NoSuchAlgorithmException e) {
    		ss = "NoSuchAlgorithmException";
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
    		ss = "NoSuchPaddingException";
            e.printStackTrace();
        } catch (InvalidKeyException e) {
    		ss = "InvalidKeyException";
            e.printStackTrace();
        } catch (IOException e) {
    		ss = "IOException";
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
    		ss = "IllegalBlockSizeException";
            e.printStackTrace();
        } catch (BadPaddingException e) {
    		ss = "BadPaddingException";
            e.printStackTrace();
        }
    
        //如果有错就返加nulll
        return ss;
    }
    
    
    
    
    public static void main(String[] args) {
    	//MyClass se=new MyClass();
        //Scanner scanner=new Scanner(System.in);
        /*
         * 加密
         */
        System.out.println("使用AES对称加密,请输入加密的规则");
        //String encodeRules=scanner.next();
        System.out.println("请输入要加密的内容:");
        String encodeRules = "a02254eb247146dfa446c4b2795ebf90";
        String content = "32770";
        String outstr = AES_Encode(encodeRules, content);
        System.out.println("根据输入的规则"+encodeRules+"加密后的密文是:"+outstr);
    
    
        /*
         * 解密
        */
        System.out.println("使用AES对称解密,请输入加密的规则:(须与加密相同)");
        
        String  byte_str = "0212f41b372fe457c3f7df0757151615";
        outstr = AES_Decode(encodeRules, byte_str);
        System.out.println("根据输入的规则"+encodeRules+"解密后的明文是:"+outstr);
        
    }
    
    }
    

     

     

     

    展开全文
  • SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(strKey.getBytes("utf-8")); keygen.init(128, random); // keygen.init(128, new SecureRandom(strKey.getBytes())); desKey = ...
  • SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(key.getBytes()); kgen.init(128, secureRandom); SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded...
  • 因工作需要,需要对aes进行加解密,收集资料时从网上找到了核心写法代码,经小量修改满足了需求。...python3 - AES SHA1PRNG 算法 加密 解密 注,需安装以下依赖库: pip3 install pycryptodome pip3 install ...
  • 1. 启动项目java -jar xxxx.jar令楼主没有想到的是:程序卡主了,卡在了数据库建立连接的位置。(查看方法方式:jstack 即可)2. 堆栈信息由于是项目刚一启动,初始化数据库连接池,并没有太多的线程堆栈。这里我贴...
  • [导读]做对接的时候,服务商做的AES加密通过SHA1PRNG算法(只要password一样,每次生成的数组都是一样的,所以可以用来做加密解密的key)进行了又一次加密,搞了好几个小时,直接看对应的代码吧做对接的时候,服务商做...
  • SHA1PRNG 中,有一个种子产生器,它根据配置执行各种操作。 Linux 中的随机数可以从两个特殊的文件中产生,一个是 /dev/urandom,另外一个是 /dev/random。他们产生随机数的原理是利用当前系统的熵池来计算出...
  • Java中的AES加密(SHA1PRNG)转换为C#

    千次阅读 2019-09-28 18:16:44
    Java代码: 1 KeyGenerator aesGen = KeyGenerator.getInstance("AES");...2 SecureRandom secureRadmon= new SecureRandom().getInstance("SHA1PRNG"); 3 secureRadmon.setSeed(aesKey.getBytes()); 4 aesGen...
  • php7 aes 对接java aes SHA1PRNG算法

    千次阅读 2018-08-21 23:53:37
    "SHA1PRNG" ); secureRandom.setSeed(password.getBytes()); //AES 要求密钥长度为 128 // kg.init(128, new SecureRandom(password.getBytes())); kg.init( 128 , secureRandom); //生成一个密钥 ...
  • 1. 启动项目java -jar xxxx.jar令楼主没有想到的是:程序卡主了,卡在了数据库建立连接的位置。(查看方法方式: jstack 即可)2. 堆栈信息由于是项目刚一启动,初始化数据库连接池,并没有太多的线程堆栈。这里我贴...
  • golang:实现Java 中的 AES SHA1PRNG算法

    千次阅读 2019-04-13 15:55:33
    20byte 160bit // 所以 encryptLength 超过这个长度,就无法生成了 // 因为不知道 java 中 AES SHA1PRNG 的生成逻辑 func AESSHA1PRNG(keyBytes []byte, encryptLength int) ([]byte, *exterror.Error) { hashs := ...
  • <? class AES { /** * * @param string $string 需要加密的字符串 * @param string $key 密钥 ... // 对接java,服务商做的AES加密通过SHA1PRNG算法(只要password一样,每次生成的数组都是一样的..
  • The server program use the password as random seed to generate a 128 bits AES key with SHA1PRNG algorithm. The same password with gen the same key. Now i am coding the client program with golang. How...
  • 正常的启动tomcat7而且并没有报错,等待了很久终于看到日志打印出来启动成功了在这里等了4分钟Tomcat 7/8都使用org.apache.catalina.util.SessionIdGeneratorBase....有两种解决办法:1.在Tomcat环境中解...
  • } /** * SHA1PRNG算法 * @param [type] $key [description] * @return [type] [description] */ private static function _sha1prng($key) { return substr(openssl_digest(openssl_digest($key, 'sha1', true), '...
  • WARNING [main] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [1,139,942] milliseconds. ...
  • 刚部署好程序,第一次登录时,加载非常得慢,查看log日志发现:Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [33,755] milliseconds. 说什么创建用于会话ID生成的...
  • SEVERE: Cannot find message associated with key managerBase.digestjava.security.NoSuchAlgorithmException: MD5 MessageDigest not availableat sun.security.jca.GetInstance.getInstance(Unknown Source)at j...
  • secureRandom 实现 之 SHA1PRNG

    万次阅读 2015-09-07 08:58:24
    SecureRandom Implementation (sun.security.provider.SecureRandom – SHA1PRNG) January 15, 2014 Categories: Developer, Security Best Practices Tags: java, securerandom, software development ...
  • Tomcat 使用 SHA1PRNG 算法是基于 SHA-1 算法实现且保密性较强的伪随机数生成器。 在 SHA1PRNG 中,有一个种子产生器,它根据配置执行各种操作。 Linux 中的随机数可以从两个特殊的文件中产生,一个是 /dev/...
  • 节点sha1 为您提供方便的sha1函数,该函数在后台使用Node的加密模块。 安装 npm install node-sha1 --save 用法 var sha1 = require ( 'node-sha1' ) ; sha1 ( 'Hello World!' ) ; # 2 ef7bde608ce5404e97d5f042...
  • 基于cookie和session登录,启动springboot项目是抛出了一个奇怪的异常:Creation of SecureRandom instance for session ID generation using [SHA1PRNG] 原因分析: idea的jdk配置存在问题,截图如下: 解决...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,537
精华内容 1,814
关键字:

sha1prng