python中AES(適配java版本)

     python自己本身的AES解密實現起來沒有問題,但是跟java適配就會出現問題,下面整理一下實現過程中出現的幾個問題和代碼:

一. 字符串

1.1 加密

1. 使用的是Crypto.Cipher.AES的加密包,
iv = b’1234567890123456’,secret_key = b"0(^v91195]'C6_8]h>1[:P<,}dm
#"
2. 加密前需要補全16位,比如字符串13位,後面補的就是“\03\03\03”
3. 加密是需要是bytes,cipher0.encrypt(fdata),fdata是bytes
4. 加密後需要用base64編碼:base64.b64encode(enc_bytes)
代碼如下:

	def encrypt_str(self, src_str, secret_key):
		"""encrypt string function.
		
		 Args:
		     src_str: plaintext string, bytes/str
		     public_key: AES public key, bytes
		     secret_key: AES secret key, bytes
		 Reutrns:
		     enc_str: encrypted string, bytes
		 """
		 if isinstance(src_str, str):
		     src_str = src_str.encode('utf-8')
		 assert isinstance(src_str, bytes)
		 public_key = self.PUBLIC_KEY
		 # instantiate AES cipher
		 cipher0 = AES.new(secret_key, AES.MODE_CFB, public_key, segment_size=128)
		
		 fdata = self.__pad(src_str)
		
		 enc_bytes = cipher0.encrypt(fdata)
		 enc_bytes = base64.b64encode(enc_bytes)
		 return enc_bytes

1.2 解密

1. 使用的是Crypto.Cipher.AES的加密包,
iv = b’1234567890123456’,secret_key = b"0(^v91195]'C6_8]h>1[:P<,}dm
#"
2. 用base64解碼,base64.b64decode(enc_bytes)
3. 解密是需要是bytes,cipher0.decrypt(fdata),fdata是bytes
4. 解密是需要將加密時補的內容去除:src_data[:-ord(src_data[-1:])]
代碼如下:

	def decrypt_str(self, enc_bytes, secret_key):
	    """decrypt string function.
	
	    Args:
	        enc_bytes: plaintext string, bytes
	        secret_key: AES secret key, bytes
	    Return:
	        dec_bytes: decrypted string, bytes
	    """
	    if isinstance(enc_bytes, str):
	        enc_bytes = enc_bytes.encode('utf-8')
	    assert isinstance(enc_bytes, bytes)
	    aes_public_key = self.AES_PUBLIC_KEY
	    decipher0 = AES.new(secret_key, AES.MODE_CFB, aes_public_key, segment_size=128)
	
	    enc_bytes = base64.b64decode(enc_bytes)
	    dec_bytes = decipher0.decrypt(enc_bytes)
	
	    dec_bytes = self.__unpad(dec_bytes)
	    return dec_bytes


二. 文件

2.1 加密

1. 加密的步驟如字符串
2. 文件存在讀取問題,如果文件過大,一次性將文件讀入內存會出現問題,
所以我們需要將文件分批讀取
3. 加密時buffer_size = 16 ×\times 3 ×\times 1024
16 AES加密需要;3 base64編碼需要;1024這個隨意設置即可
代碼如下:

    def __encrypt_stream_batchs(self, file_in, file_out, public_key, secret_key, input_length):
        """encrypt binary stream function.

        Args:
            file_in: input binary stream
            file_out: output binary stream
            public_key: AES public key
            secret_key: AES secret key
        """
        BUFFER_SIZE = self.ENCRYPT_BUFFER_SIZE
        AES_BLOCK_SIZE = self.AES_BLOCK_SIZE
        # validate bufferSize
        if BUFFER_SIZE % AES_BLOCK_SIZE != 0:
            raise ValueError("Buffer size must be a multiple of AES block size.")

        # instantiate AES cipher
        encryptor0 = AES.new(secret_key, AES.MODE_CFB, public_key, segment_size=128)

        # encrypt file while reading it
        read_file_size = 0
        while read_file_size < input_length:
            # try to read BUFFER_SIZE bytes
            fdata = file_in.read(BUFFER_SIZE)
            bytes_read = len(fdata)
            read_file_size += bytes_read

            if bytes_read < BUFFER_SIZE:
                fdata = self.__pad(fdata)

            cText = encryptor0.encrypt(fdata)
            cText = base64.b64encode(cText)
            file_out.write(cText)

1.2 解密

1. 解密的步驟如字符串解密
2. 文件存在讀取問題,需要將文件分批讀取
3. 加密時buffer_size = 16 ×\times 4 ×\times 1024
16 AES解密需要;4 base64解碼需要;1024這個隨意設置即可
代碼如下:

    def __decrypt_stream_batchs(self, file_in, file_out, public_key, secret_key, input_length):
        """encrypt binary stream function.

        Args:
            file_in: input binary stream,str
            file_out: output binary stream,str
            public_key: AES public key,16 bits
            secret_key: AES secret key,16 bits
            input_length: input stream length,int
        """
        BUFFER_SIZE = self.DECRYPT_BUFFER_SIZE
        AES_BLOCK_SIZE = self.AES_BLOCK_SIZE
        # validate bufferSize
        if BUFFER_SIZE % AES_BLOCK_SIZE != 0:
            raise ValueError("Buffer size must be a multiple of AES block size")

        # instantiate another AES cipher
        decryptor0 = AES.new(secret_key, AES.MODE_CFB, public_key, segment_size=128)

        # 處理BUFFER_SIZE數據
        while file_in.tell() < input_length - BUFFER_SIZE:
            cText = file_in.read(BUFFER_SIZE)
            cText = base64.b64decode(cText)
            file_out.write(decryptor0.decrypt(cText))

        # 處理剩餘數據
        cText = bytes()
        if file_in.tell() != input_length:
            cText = file_in.read(BUFFER_SIZE)
            cText = base64.b64decode(cText)
            if len(cText) % AES_BLOCK_SIZE != 0:
                raise ValueError("File is corrupted.")

        # decrypt last block
        de_text = decryptor0.decrypt(cText)
        de_text = self.__unpad(de_text)
        file_out.write(de_text)

完整代碼見我上傳的資源:
https://download.csdn.net/download/peach_orange/11824472

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章