Pycrypto与RSA密码技术

密码与通信

     密码技术是一门历史悠久的技术。信息传播离不开加密与解密。密码技术的用途主要源于两个方面,加密/解密和签名/验签。
 
pip install pycrypto

RSA 密码算法与签名

     RSA是一种公钥密码算法,RSA的密文是对代码明文的数字E次方求mod N的结果。也就是将明文和自己做E次乘法,然后再将其结果除以N求余数,余数就是密文。RSA也是一个简洁的加密算法。E和N的组合就是公钥(public key)
 
     对RSA的解密,即密文的数字的D次方求mod N即可,即密文和自己做D次乘法,在对结果除以N求余数即可得到明文。D和N的组合就是私钥(private key)
 
     算法的加密和解密还是很简单的,可是公钥和私钥的生成算法却不是随意的。使用Pucrypto生成秘钥对很简单,我们分别为Master和Ghost各生成一对属于自己的密钥对。
 
from Crypto import Random
from Crypto.PublicKey import RSA

# 伪随机数生成器
random_generator = Random.new().read
# rsa算法生成实例
rsa = RSA.generate(1024, random_generator)

# master的秘钥对的生成
private_pem = rsa.exportKey()
# 私钥
with open('master-private.pem', 'w') as f:
    f.write(private_pem)
# 公钥
public_pem = rsa.publickey().exportKey()
with open('master-public.pem', 'w') as f:
    f.write(public_pem)
 1 # master-private.pem
 2 -----BEGIN RSA PRIVATE KEY-----
 3 MIICXAIBAAKBgQCiVxAofpOL1lxbs2/66fXQksBd6Dc5PsB4vtpcBYbyxEp5CBCX
 4 5pN0/NbVFwiyg/aOv5vvBXUMTsQkhr6kJXLmM9chVuPkedwQ7FESe7oLFNxuaDjZ
 5 hYM9RasDJ4rE2NMwSN1M54mw6ZVpzPnRpnrawbZSzLkEOOvywmephmuHvwIDAQAB
 6 AoGAPi6ZGtm5DHQ0dk+aEgMxzA2aL542IPA/a0C3hU38rdqwKAIF0RlZ3BLI+2BS
 7 TYasl2sfgIOXnPpCuTb/qQJLKvP903yOjQDjnNAn2wp24FQKhhVzlaOwwiyHRN/U
 8 LoUhcaaGFnGNL6r4E4ZM9beBLVVdn+g1bJn2HQawlVlGw9ECQQDLcSrUgzbuQeRi
 9 HT3Q/HnDiVk7WXu4laJ/NRpTPj2HxjjaS2nI8IP/ndZvg7OU5Xc5tLkWh3b5RUgU
10 J7u6nJqJAkEAzEeUCJ0Df+i4zieu1ER9NUV6Ml9kFwCTAF7TzNAj5K1SZfSK9i1k
11 BbKxhEUdr8aYgReqhQkwqD6WEpI/Iv1eBwJAQF3Cvk/xjjpcxsoXp8ppv/rxt3xd
12 T45QRk0H0jSMBSwrCq33fzLRoItQsCGMLNzY9vH96Wncs4s+/dmAZM9teQJBAJjK
13 KMTQe5+d9yvqrm8B0wyXLLCkfH5f5ZNvWcdlHpOZt3mekJlUle1VHEUsVOn2Bnb3
14 tojOuN/9/81gKW0ISN0CQFMEyymdqARaTKrSpzYXkerE987TQJdaP6VVjNaBnbv+
15 VzAHW5qTJgcP/sABfw3dQ4+ocTU8yVTlBgtleeHmZxg=
16 -----END RSA PRIVATE KEY-----
17 
18 # master-public.pem
19 
20 -----BEGIN PUBLIC KEY-----
21 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiVxAofpOL1lxbs2/66fXQksBd
22 6Dc5PsB4vtpcBYbyxEp5CBCX5pN0/NbVFwiyg/aOv5vvBXUMTsQkhr6kJXLmM9ch
23 VuPkedwQ7FESe7oLFNxuaDjZhYM9RasDJ4rE2NMwSN1M54mw6ZVpzPnRpnrawbZS
24 zLkEOOvywmephmuHvwIDAQAB
25 -----END PUBLIC KEY-----
生成的私钥和公钥

 

加密与解密

     通常通信的时候,发送者使用接受者的公钥加密,接受者使用接受者秘钥进行解密。
     
     简而言之,Master给Ghost通信,需要加密内容,那么Ghost会生成一个秘钥对,Ghost的公钥ghost-public.pem和私钥ghost-private.pem 。 ghost把公钥公开给发送者,任何人都可以用来加密,然后Master使用ghost-public.pem 进行加密,然后把内容发送给Ghost,ghost再使用ghost-private.pem进行解密。
 
 
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5

# 加密内容
message = "hello"
# 加密
with open('master-public.pem', 'r') as f:
    key = f.read()
    rsakey = RSA.importKey(key)
    cipher = Cipher_pkcs1_v1_5.new(rsakey)
    cipher_text = base64.b64encode(cipher.encrypt(message))
    print(cipher_text)
    # IpAX4ZynawSsxI4/0RGEHpFT/U2E7VXDLN36+QONelxnid5jziq/Epk6Xsv3iBEWvRdmdcTYf/0zBHnnwg515K/
    # a45JeaKV/DQwc2Qeq+lsFBuDyUFN/RnC6zGTMUzkAzCmbVH3NPiX9UzZo6Rjr7y2Zm6zUWsLgL/D3/QDh/IU=


# 解密
with open('master-private.pem', 'r') as f:
    key = f.read()
    rsakey = RSA.importKey(key)
    cipher = Cipher_pkcs1_v1_5.new(rsakey)
    text = cipher.decrypt(base64.b64decode(cipher_text), random_generator)
    print(str(text))  # hello

签名与验签

当然,对于窃听者,有时候也可以对伪造Master给Ghost发送内容。为此出现了数字签名。也就是Master给Ghost发送消息的时候,先对消息进行签名,表明自己的身份,并且这个签名无法伪造。具体过程即Master使用自己的私钥对内容签名,然后Ghost使用Master的公钥进行验签。
 
import base64
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA, MD5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5

message = "hello"
# 签名
with open('master-private.pem', 'r') as f:
    key = f.read()
    rsakey = RSA.importKey(key)
    signer = Signature_pkcs1_v1_5.new(rsakey)
    digest = SHA.new()  # MD5.new()
    digest.update(message)
    sign = signer.sign(digest)
    signature = base64.b64encode(sign)
    print(signature)
    # JpDhJPGl1MG5T2l5aggPBMbIzjKqyYmB7Q3MkqbJtj1Z5FVSP6dTthspEVrFarNxA51hx5mLbbs9mLCFK++dy4z
    # QdpgkSjBgyisWBHCKDbgskvu8DZCn6STZ0o0Ml9r+h4Oj++JX3SwmUNjzEYIgdp3jTIh12bZzgfoJmY8k4Rk=

# 验签
with open('master-public.pem', 'r') as f:
    key = f.read()
    rsakey = RSA.importKey(key)
    verifier = Signature_pkcs1_v1_5.new(rsakey)
    digest = SHA.new()
    digest.update(message)
    is_verify = verifier.verify(digest, base64.b64decode(signature))
    print(is_verify)  # True

总结

rsa提供了比较完善的加密算法。RSA广泛用于加密与解密,还有数字签名通信领域。使用Publick/Private秘钥算法中,加密主要用对方的公钥,解密用自己的私钥。签名用自己的私钥,验签用对方的公钥。
 
加密解密:公钥加密,私钥解密
签名验签:私钥签名,公钥验签
无论是加密机密还是签名验签都使用同一对秘钥对
 
posted @ 2018-01-30 18:10  _Goku  阅读(890)  评论(0编辑  收藏  举报