阮一峰的网络日志:RSA算法原理(一)
阮一峰的网络日志:RSA算法原理(二)
RSA加密算法
是一种
非对称加密算法
,在
公开密钥加密
和电子商业中被广泛使用。RSA是1977年由
罗纳德·李维斯特
(Ron Rivest)、
阿迪·萨莫尔
(Adi Shamir)和
伦纳德·阿德曼
(Leonard Adleman)一起提出的。当时他们三人都在
麻省理工学院
工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
1973年,在英国政府通讯总部工作的数学家克利福德·柯克斯(Clifford Cocks)在一个内部文件中提出了一个与之等效的算法,但该算法被列入机密,直到1997年才得到公开。
RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
所以对极大整数做
因数分解
的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式破解。到当前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被破解的。
Python RSA文件加密
Python Cryptography Toolkit
签名与验签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import MD5 import base64
def RSA_sign(data): privateKey = ''' MIGvAgEAAiIMzxsBkAn8f9vA5z8phs0z5JT9d9xWS+9hnrMurYY7yySRAgMBAAEC IgTmnOudI+UDOp51G/qUhCDtkYhYKvTgENlK1DsroFYXtN0CET4oCSZvz+1GEKsQ bE4Ny7y7AhE0wXdLJpQgJnD4cmGmQo8VIwIRNghBpAsw+nedB8gYDmZJxP8CEStE eQiDrXzoykKZ3Qi1EhCtAhE20ZvBe0I1fj48Pryi+0gtVA==''' private_keyBytes = base64.b64decode(privateKey) priKey = RSA.importKey(private_keyBytes) signer = PKCS1_v1_5.new(priKey) hash_obj = MD5.new(data.encode('utf-8')) signature = base64.b64encode(signer.sign(hash_obj)) return signature
def verify(signature, data): publicKey = ''' MD0wDQYJKoZIhvcNAQEBBQADLAAwKQIiDM8bAZAJ/H/bwOc/KYbNM+SU/XfcVkvv YZ6zLq2GO8skkQIDAQAB''' public_keyBytes = base64.b64decode(publicKey) pubKey = RSA.importKey(public_keyBytes) hash_obj = MD5.new(data.encode('utf-8')) verifier = PKCS1_v1_5.new(pubKey) return verifier.verify(hash_obj, base64.b64decode(signature))
|
上面的签名代码做了如下几件事:
它将Base64解码为PKCS#8
它将PKCS#8解码为内存中的实际密钥(请注意,可能需要在此处提供密码)
它使用所述密钥将数据(使用SHA-1或者MD5等算法进行hash)执行PKCS#1 v1.5签名
它使用Base64将签名进行编码
segmentfault:Crypto算法库详解
该模块和上面的pycrypto很像,但pycrypto最后一次更新是在13年,安装后引用方式是一样的,api也非常相似,安装其中一个就好了。
加密与解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 import base64
def create_new_keys(len): rsa = RSA.generate(2048)
public_pem = rsa.publickey().exportKey('PEM') private_pem = rsa.exportKey('PEM')
with open('public.pem','wb') as f: f.write(public_pem) with open('private.pem','wb') as f: f.write(private_pem)
def rsa_encrypt(plain): with open('public.pem','rb') as f: key = RSA.importKey(f.read()) rsa = PKCS1_v1_5.new(key) cipher = rsa.encrypt(plain) return base64.b64encode(cipher)
def rsa_decrypt(cipher): with open('private.pem','rb') as f: key = RSA.importKey(f.read()) rsa = PKCS1_v1_5.new(key) plain = rsa.decrypt(base64.b64decode(cipher),'ERROR') return plain
|
签名与验签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
from Crypto.Signature import pkcs1_15 from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA
def sign(data): key = RSA.import_key(open('private_key.pem').read()) h = SHA256.new(data) rsa = pkcs1_15.new(key) signature = rsa.sign(h)
def verify(signature, data): key = RSA.import_key(open('public_key.pem').read()) hash_obj = SHA256.new(data) rsa = pkcs1_15.new(key) return rsa.verify(hash_obj, signature):
|