We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
上一篇是对AES的快速入门,这次通过和其他端的加解密来详细解说一下。 这一次用的模式为CBC模式
PS:其实最简单的应该是ECB模式,但是从安全性角度来说已经被判了死刑。
Warning The ECB mode should not be used because it is semantically insecure. For one, it exposes correlation between blocks.
IV 向量值和加密块的长度一致(16byte),如果不指定api会随机生成一个。
block size 加密块数据大小(16byte)
AES加密一次加密的数据量为16byte,如果不足16byte需要“凑整”,过大需要“切割”。 我们暂时不谈切割,我们说“凑整”padding
在ANSI X.923的方式下,先是填充00,最后一个字节填充padded的字节个数。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 00 00 00 00 05 |
在ISO 10126的方式下,先是填充随机值,最后一个字节填充padded的字节个数。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 95 81 28 A7 05 |
在PKCS7的方式下,如果一共需要padded多少个字节,所有填充的地方都填充这个值。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 05 05 05 05 05 |
在ISO/IEC 7816-4方式下,第一个填充的字节是80,后面的都填充00。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 80 00 00 00 00 |
在Zero padding方式下,每一个需要填充的字节都填00。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 00 00 00 00 00 |
我们默认使用PKCS7
不如写一个例子实验一下
from Crypto.Cipher import AES from Crypto.Util.Padding import pad,unpad import binascii keys = '30980f98296b77f00a55f3c92b35322d898ae2ffcdb906de40336d2cf3d556a0' iv = 'e5889166bb98ba01e1a6bc9b32dbf3e6' def aes_string( input:str ): cipher = AES.new(binascii.unhexlify(keys), AES.MODE_CBC,iv=binascii.unhexlify(iv)) decipher = AES.new(binascii.unhexlify(keys), AES.MODE_CBC,iv=binascii.unhexlify(iv)) message = input.encode() pad_message = pad(message, AES.block_size) print(f"message:{message},pad message{pad_message}") text_secret = cipher.encrypt(pad_message) print(f"text_secret:{text_secret}") original_message = unpad(decipher.decrypt(text_secret),AES.block_size) print("Decrypted original message:", original_message) aes_string('testtesttesttest')
可以看出补了16个0x10“废数据”,如果unpad,正好把整个数据块全部拿掉。
文件加密
from Crypto.Cipher import AES from Crypto.Util.Padding import pad,unpad import binascii import os import argparse parser = argparse.ArgumentParser(description='Process some files.') parser.add_argument('-f', '--input-file', required=True, help='The input file') args = parser.parse_args() print(f"Input file: {args.input_file}") keys = '30980f98296b77f00a55f3c92b35322d898ae2ffcdb906de40336d2cf3d556a0' iv = 'e5889166bb98ba01e1a6bc9b32dbf3e6' download_path = args.input_file output_filename = f"encrypt_{args.input_file}" #print(f"key lenght:{len(binascii.unhexlify(keys))}") cipher = AES.new(binascii.unhexlify(keys), AES.MODE_CBC,iv=binascii.unhexlify(iv)) in_file_length = os.path.getsize(download_path) block_count = in_file_length / AES.block_size print(in_file_length) count = 0 with open(download_path, 'rb') as in_file: with open(output_filename, 'wb') as out_file: while content := in_file.read(AES.block_size): if(len(content) < AES.block_size): content = pad(content,AES.block_size) hex_string = binascii.hexlify(content).decode() print(f"pad content:{hex_string}") crypted_chunk = cipher.encrypt(content) out_file.write(crypted_chunk) #print(f"计数{count}/总数{block_count},length:{len(crypted_chunk)}") out_file_length = os.path.getsize(output_filename) print(f"encrypt ok,size {out_file_length}")
注意这里最后一块数据块需要执行pad函数进行凑整处理
from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import binascii import os import argparse parser = argparse.ArgumentParser(description='Process some files.') parser.add_argument('-f', '--input-file', required=True, help='The input file') args = parser.parse_args() print(f"Input file: {args.input_file}") keys = '30980f98296b77f00a55f3c92b35322d898ae2ffcdb906de40336d2cf3d556a0' iv = 'e5889166bb98ba01e1a6bc9b32dbf3e6' download_path = args.input_file output_filename = f"restore_{download_path}" cipher = AES.new(binascii.unhexlify(keys), AES.MODE_CBC,iv=binascii.unhexlify(iv)) in_file_length = os.path.getsize(download_path) block_count = in_file_length / AES.block_size count = 0 with open(download_path, 'rb') as in_file: with open(output_filename, 'wb') as out_file: while content := in_file.read(AES.block_size): # 每次读取数据 count = count + 1 decrypted_chunk = cipher.decrypt(content) if(block_count == count): print(f"before pad content:{decrypted_chunk}") decrypted_chunk = unpad( decrypted_chunk,AES.block_size ) hex_string = binascii.hexlify(decrypted_chunk).decode() print(f"content:{hex_string}") out_file.write(decrypted_chunk) print(f"计数{count}/总数{block_count},length:{len(decrypted_chunk)}") print(f"decrypt {output_filename} OK") out_file_length = os.path.getsize(output_filename) print(f"in file size:{in_file_length},out file size{out_file_length}")
同样,解密最后一块数据块需要执行unpad。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
上一篇是对AES的快速入门,这次通过和其他端的加解密来详细解说一下。
这一次用的模式为CBC模式
PS:其实最简单的应该是ECB模式,但是从安全性角度来说已经被判了死刑。
关于CBC使用参数
IV
向量值和加密块的长度一致(16byte),如果不指定api会随机生成一个。
block size
加密块数据大小(16byte)
AES的padding
AES加密一次加密的数据量为16byte,如果不足16byte需要“凑整”,过大需要“切割”。
我们暂时不谈切割,我们说“凑整”padding
在ANSI X.923的方式下,先是填充00,最后一个字节填充padded的字节个数。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 00 00 00 00 05 |
在ISO 10126的方式下,先是填充随机值,最后一个字节填充padded的字节个数。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 95 81 28 A7 05 |
在PKCS7的方式下,如果一共需要padded多少个字节,所有填充的地方都填充这个值。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 05 05 05 05 05 |
在ISO/IEC 7816-4方式下,第一个填充的字节是80,后面的都填充00。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 80 00 00 00 00 |
在Zero padding方式下,每一个需要填充的字节都填00。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 00 00 00 00 00 |
我们默认使用PKCS7
如果最后一行数据正好是怎么样?
不如写一个例子实验一下
可以看出补了16个0x10“废数据”,如果unpad,正好把整个数据块全部拿掉。
加解密完整实现
文件加密
注意这里最后一块数据块需要执行pad函数进行凑整处理
同样,解密最后一块数据块需要执行unpad。
相关API参考链接
The text was updated successfully, but these errors were encountered: