加密算法详解
一、加密算法分为对称加密、非对称加密和散列算法
1.对称加密算法:加密与解密的密钥相同,算法主要有DES、3DES、AES;AES、DES、3DES都是对称的块加密算法,加解密的过程是可逆的 a.数据加密过程:在对称加密算法中,数据发送方将明文(原始数据)和加密密钥一起经过特殊加密处理,生成复杂的加密密文进行发送 b.据解密过程:数据接收方收到密文后,若想读取原数据,则需要使用加密使用的密钥及相同算法的逆算法 对加密的密文进行解密,才能使其恢复成可读明文 2.非对称加密算法:加密与解密的密钥不同,算法主要有RSA、DSA a.如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密 b.如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密 3.散列算法:不需要密钥,算法主要有SHA-1、MD5
二、md5算法(不可逆)
md5用的是哈希函数,它的典型应用是对一段信息产生信息摘要,所以严格来说md5是摘要算法。无论有多长的输入,md5的输出长度为128bits消息摘要(通常用16进制表示,16进制占4位,即128/4=32个字符)
例子:
import hashlib 1.第一种 m=hashlib.md5() m.update(‘nba‘.encode(encoding=‘utf-8‘)) n = m.hexdigest() 2.第二种 hashlib.md5(‘nba‘.encode(encoding=‘utf-8‘)).hexdigest() 3.第三种 hashlib.new(‘md5‘, ‘nba‘.encode(encoding=‘utf-8‘)).hexdigest()
三、sha1算法(不可逆)
sha1是和md5一样的摘要算法,然而sha1比md5的安全性更强。对于长度小于 2^64 位的输入,sha1的输出长度为160位的消息摘要 (通常用16进制表示,16进制占4位,即160/4=40个字符)
例子:
import hashlib 1.第一种 s=hashlib.sha1() s.update(‘nba‘.encode(encoding=‘utf-8‘)) n = s.hexdigest() 2.第二种 hashlib.sha1(‘nba‘.encode(encoding=‘utf-8‘)).hexdigest() 3.第三种 hashlib.new(‘sha1‘, ‘nba‘.encode(encoding=‘utf-8‘)).hexdigest()
四、base64算法
Base64是一种基于64个可打印字符("A-Z、a-z、0-9、+、/")来表示二进制数据的表示方法。64个字符都用6个bit位表示,一个字节有8个bit位,剩下两个bit就浪费掉了,这样就不得不牺牲一部分空间了
8和6的最小公倍数是24,也就是说3个传统字节可以由4个Base64字符来表示,保证有效位数是一样的,这样就多了1/3的字节数来弥补Base64只有6个有效bit不足。你也可以说用两个Base64字符也能表示一个传统字符,但是采用最小公倍数的方案其实是最减少浪费的。 结合下边的图比较容易理解。Man是三个字符,一共24个有效bit,只好用4个Base64字符来凑齐24个有效位。红框表示的是对应的Base64,6个有效位转化成相应的索引值再对应 Base64字符表,查出"Man"对应的Base64字符是"TWFU"。说到这里有个原则不知道你发现了没有,要转 换成Base64的最小单位就是三个字节,对一个字符串来说每次都是三个字节三个字节的转换,对应的是Base64的四个字节。这个搞清楚了其实就差不多了
但是转换到最后你发现不够三个字节了怎么办呢?我们可以用两个Base64来表示一个字符或用三个Base64表示两个字符,像下图的A对应的第二个Base64的二进制位只有两个,把后边的四个补0就是了。所以 A对应的Base64字符就是QQ。上边已经说过了,原则是Base64字符的最小单位是四个字符一组,那这才两个字符,后边补两个"="吧。其实不用"="也不耽误解码,之所以用"=",可能是考虑到多段编码 后的Base64字符串拼起来也不会引起混淆。由此可见 Base64字符串只可能最后出现一个或两个"=",中间是不可能出现"="的
例子:
import base64 base64.b64encode(‘nbawnba‘.encode(encoding=‘utf-8‘)) base64.b64decode(b‘bmJhd25iYQ==‘).decode(‘utf-8‘)
五、AES算法(可逆)
AES 加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为128 位、192 位、256 位,分组长度为128位
例子:
pip install pycryptodome -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com from Crypto.Cipher import AES def aes_encrypt(key, value): """ aes加密 :param key:open_key :param value:加密的data :return: """ # 补足字符串长度为16的倍数 def add_to_16(s): while len(s) % 16 != 0: s += (16 - len(s) % 16) * chr(16 - len(s) % 16) return str.encode(s) # 返回bytes aes = AES.new(str.encode(key), AES.MODE_ECB) encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(value))), encoding=‘utf8‘).replace(‘\n‘, ‘‘) #加密明文,并将返回的字节型数据转进行base64编码,并将字节型数据转换成python中的字符串类型 return encrypted_text def aes_decrypt(key, value): """ aes解密 :param key: open_key :param value: 需要解密的data :return: """ aes = AES.new(str.encode(key), AES.MODE_ECB) decrypted_text = aes.decrypt(base64.decodebytes(bytes(value, encoding=‘utf8‘))).decode("utf8") # 解密 decrypted_text = decrypted_text[:-ord(decrypted_text[-1])] # 去除多余补位 return decrypted_text
六、RSA算法
加密是为了防止信息被泄露,而签名是为了防止信息被篡改。总之,公钥加密、私钥解密、私钥签名、公钥验签
RSA的加密过程如下:
(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取
(2)A传递自己的公钥给B,B用A的公钥对消息进行加密
(3)A接收到B加密的消息,利用A自己的私钥对消息进行解密
RSA签名的过程如下:
(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取
(2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B
(3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的
#生成公私钥 import rsa # 生成密钥 (pubkey, privkey) = rsa.newkeys(1024) # 保存密钥 with open(‘public.pem‘ ,‘w+‘) as f: f.write(pubkey.save_pkcs1().decode()) with open(‘private.pem‘ ,‘w+‘) as f: f.write(privkey.save_pkcs1().decode()) #导入密钥 with open(‘public.pem‘ ,‘r‘) as f: pubkey = rsa.PublicKey.load_pkcs1(f.read().encode()) with open(‘private.pem‘ ,‘r‘) as f: privkey = rsa.PrivateKey.load_pkcs1(f.read().encode()) #加密rsa def rsa_encrypt(message): crypto_email_text = rsa.encrypt(message.encode(), pubkey) return crypto_email_text text = rsa_encrypt("hello world") #解密rsa def rsa_decrypt(message): message_str = rsa.decrypt(message,privkey).decode() return message_str rsa_decrypt(text) #签名 message = ‘这是重要指令:...‘ crypto_email_text = rsa.sign(message.encode(), privkey, ‘SHA-1‘) #验签 rsa.verify(message.encode(), crypto_email_text, pubkey)