加密和解密的总结
Posted chenxi67
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了加密和解密的总结相关的知识,希望对你有一定的参考价值。
一.加密算法的分类
1.对称加密算法具有更高的加密速度,但双方都需要事先知道秘钥,秘钥在传输过程中可能会被窃取,因此安全性没有非对称加密高
常见的对称加密算法:DES, AES, 3DES等等
2.非对称加密算法的加密速度低于对称加密算法,但是安全性更高
非对称加密算法:RSA, DSA, ECC 等算法
3.利用字典的格式转换加密
MAKETRANS()
二.详细分析
1.DES加密
即数据加密标准,是一种使用秘钥加密的块算法
入口参数有三个:key, Data, Mode
key为7个字节共56位,是DES算法的工作秘钥;
Data为DES的工作方式,有两种:加密和解密
3DES是DES向AES过渡的加密算法,使用两个秘钥,执行三次DES算法,
加密的过程是加密-解密-加密
解密的过程是解密-加密-解密
1 from Crypto.Cipher import DES 2 key = b‘abcdefgh‘ # 密钥 8位或16位,必须为bytes 3 4 def pad(text): 5 """ 6 # 加密函数,如果text不是8的倍数【加密文本text必须为8的倍数!】,那就补足为8的倍数 7 :param text: 8 :return: 9 """ 10 while len(text) % 8 != 0: 11 text += ‘ ‘ 12 return text 13 14 15 des = DES.new(key, DES.MODE_ECB) # 创建一个DES实例 16 text = ‘Python rocks!‘ 17 padded_text = pad(text) 18 encrypted_text = des.encrypt(padded_text.encode(‘utf-8‘)) # 加密 19 print(encrypted_text) 20 # rstrip(‘ ‘)返回从字符串末尾删除所有字符串的字符串(默认空白字符)的副本 21 plain_text = des.decrypt(encrypted_text).decode().rstrip(‘ ‘) # 解密 22 print(plain_text)
2.AES加密
高级加密标准(英语:Advanced EncryptionStandard,缩写:AES),这个标准用来替代原先的DES
AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特(16、24和32字节)
大致步骤:
1、密钥扩展(KeyExpansion),
2、初始轮(Initial Round),
3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,
4、最终轮(Final Round),最终轮没有MixColumns。
普通方式
1 from Cryptodome.Cipher import AES 2 from binascii import b2a_hex, a2b_hex 3 #秘钥,此处需要将字符串转为字节 4 key = ‘abcdefgh‘ 5 #加密内容需要长达16位字符,所以进行空格拼接 6 def pad(text): 7 while len(text) % 16 != 0: 8 text += ‘ ‘ 9 return text 10 #加密秘钥需要长达16位字符,所以进行空格拼接 11 def pad_key(key): 12 while len(key) % 16 != 0: 13 key += ‘ ‘ 14 return key 15 #进行加密算法,模式ECB模式,把叠加完16位的秘钥传进来 16 aes = AES.new(pad_key(key).encode(), AES.MODE_ECB) 17 #加密内容,此处需要将字符串转为字节 18 text = ‘hello‘ 19 #进行内容拼接16位字符后传入加密类中,结果为字节类型 20 encrypted_text = aes.encrypt(pad(text).encode()) 21 encrypted_text_hex = b2a_hex(encrypted_text) 22 print(encrypted_text_hex) 23 24 25 # #此处是为了验证是否能将字节转为字符串后,进行解密成功 26 # #实际上a 就是 encrypted_text ,也就是加密后的内容 27 # #用aes对象进行解密,将字节类型转为str类型,错误编码忽略不计 28 de = str(aes.decrypt(a2b_hex(encrypted_text_hex)), encoding=‘utf-8‘,errors="ignore") 29 # #获取str从0开始到文本内容的字符串长度。 30 print(de[:len(text)])
面向对象方式
1 from Cryptodome.Cipher import AES 2 from binascii import b2a_hex, a2b_hex 3 4 AES_LENGTH = 16 5 6 class prpcrypt(): 7 def __init__(self, key): 8 self.key = key 9 self.mode = AES.MODE_ECB 10 self.cryptor = AES.new(self.pad_key(self.key).encode(), self.mode) 11 12 # 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数 13 # 加密内容需要长达16位字符,所以进行空格拼接 14 def pad(self,text): 15 while len(text) % AES_LENGTH != 0: 16 text += ‘ ‘ 17 return text 18 19 # 加密密钥需要长达16位字符,所以进行空格拼接 20 def pad_key(self,key): 21 while len(key) % AES_LENGTH != 0: 22 key += ‘ ‘ 23 return key 24 25 def encrypt(self, text): 26 27 # 这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用 28 # 加密的字符需要转换为bytes 29 # print(self.pad(text)) 30 self.ciphertext = self.cryptor.encrypt(self.pad(text).encode()) 31 # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题 32 # 所以这里统一把加密后的字符串转化为16进制字符串 33 return b2a_hex(self.ciphertext) 34 35 # 解密后,去掉补足的空格用strip() 去掉 36 37 def decrypt(self, text): 38 plain_text = self.cryptor.decrypt(a2b_hex(text)).decode() 39 return plain_text.rstrip(‘ ‘) 40 41 42 if __name__ == ‘__main__‘: 43 pc = prpcrypt(‘abcdef‘) # 初始化密钥 44 e = pc.encrypt("0123456789ABCDEF") 45 d = pc.decrypt(e) 46 print(e, d) 47 e = pc.encrypt("00000000000000000000000000") 48 d = pc.decrypt(e) 49 print(e, d)
3.RSA加密
公钥加密算法,一种非对称密码算法
公钥加密,私钥解密
公有三个参数:rsa_n, rsa_e, message
rsa_n, rsa_e 用于生成公钥
message:需要加密的消息
1 import rsa 2 from binascii import b2a_hex, a2b_hex 3 4 5 6 class rsacrypt(): 7 def __init__(self, pubkey, prikey): 8 self.pubkey = pubkey 9 self.prikey = prikey 10 11 def encrypt(self, text): 12 self.ciphertext = rsa.encrypt(text.encode(), self.pubkey) 13 # 因为rsa加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题 14 # 所以这里统一把加密后的字符串转化为16进制字符串 15 return b2a_hex(self.ciphertext) 16 17 def decrypt(self, text): 18 decrypt_text = rsa.decrypt(a2b_hex(text), prikey) 19 return decrypt_text 20 21 22 if __name__ == ‘__main__‘: 23 pubkey, prikey = rsa.newkeys(256) 24 rs_obj = rsacrypt(pubkey,prikey) 25 text=‘hello‘ 26 ency_text = rs_obj.encrypt(text) 27 print(ency_text) 28 print(rs_obj.decrypt(ency_text)) 29 30 """ 31 b‘7cb319c67853067abcd16aad25b3a8658e521f83b1e6a6cf0c4c2e9303ad3e14‘ 32 b‘hello‘ 33 """
4.使用base64或pycrypto模块
1.使用base64
1 s1 = base64.encodestring(‘hello world‘) 2 s2 = base64.decodestring(s1) 3 print s1, s2 4 5 # 结果 6 # aGVsbG8gd29ybGQ= 7 # hello world
优点:方法简单
缺点:不保险,别人拿到密文可以解密出明文
编码原理:将3个字节转换成4个字节((3 X 8)=24=(4X6)),先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了。
解密原理:将4个字节转换成3个字节,先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位,这样就还原了。
2.使用pycrypto模块
1 from Crypto.Cipher import AES 2 obj = AES.new(‘This is a key123‘, AES.MODE_CBC, ‘This is an IV456‘) 3 message = "The answer is no" 4 ciphertext = obj.encrypt(message) 5 print(ciphertext) 6 # ‘xd6x83x8dd!VTx92xaa`Ax05xe0x9bx8bxf1‘ 7 obj2 = AES.new(‘This is a key123‘, AES.MODE_CBC, ‘This is an IV456‘) 8 decryptext = obj2.decrypt(ciphertext) 9 print(decryptext) 10 # ‘The answer is no‘
AES只是个基本算法,实现AES有若干模式。其中的CBC模式因为其安全性而被TLS(就是https的加密标准)和IPSec(win采用的)作为技术标准。
简单地说,CBC使用密码和salt(起扰乱作用)按固定算法(md5)产生key和iv。然后用key和iv(初始向量,加密第一块明文)加密(明文)和解密(密文)。
1 import sys 2 from Crypto.Cipher import AES 3 from binascii import b2a_hex, a2b_hex 4 5 class prpcrypt(): 6 def __init__(self, key): 7 self.key = key 8 self.mode = AES.MODE_CBC 9 10 #加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数 11 def encrypt(self, text): 12 cryptor = AES.new(self.key, self.mode, self.key) 13 #这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用 14 length = 16 15 count = len(text) 16 add = length - (count % length) 17 text = text + (‘