python rsa加解密
今天要说的加密方式RSA,随笔简单记录下。
RSA加密是一种非对称加密
,通常使用公钥加密,私钥解密
,私钥签名,公钥验签
。而通常 公钥比较短,私钥比较长。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。 RSA算法通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开。
1.生成公钥&&私钥
from Crypto import Random
from Crypto.PublicKey import RSA
# 伪随机数生成器
random_generator = Random.new().read
# rsa算法生成实例
rsa = RSA.generate(1024, random_generator)
# 私钥的生成
private_pem = rsa.exportKey()
with open("private.pem", "wb") as f:
f.write(private_pem)
# 公钥的生成
public_pem = rsa.publickey().exportKey()
with open("public.pem", "wb") as f:
f.write(public_pem)
运行完以后会生成两个文件,private.pem
和 public.pem
。
生成的公钥私钥格式是固定的,秘钥中间无空格无换行,秘钥末尾也空格无换行。
公钥长这样,一般比较短。
私钥长这样,一般比较长。
2.使用公钥加密
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
# rsa加密
def rsa_encrypt(message):
public_key = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfgDPRwaAYZFyNg7EyjMZOnjIR
vPPPu4sC6Iu25SDK9z6aE/yKwNSXI4JF/7gsFlXpV8rjB/SfIjNAunHy0++2djAT
1aWJYZSTujBkPblqR/NxRTilTwoc/oRjLHLF3RuoPOIL4on303Uc9Jgzj1CKbIDU
SSk4+gy2rfs2SUZ/uwIDAQAB
-----END PUBLIC KEY-----"""
rsa_key = RSA.importKey(public_key)
cipher = Cipher_pkcs1_v1_5.new(rsa_key) # 创建用于执行pkcs1_v1_5加密或解密的密码
cipher_text = base64.b64encode(cipher.encrypt(message.encode("utf-8")))
return cipher_text.decode("utf-8")
if __name__ == "__main__":
message = "Hello, 你好, 这是一段RSA加密测试代码!"
result = rsa_encrypt(message)
print(result)
跑一下看看结果:
jVzxl5vJ9OsDHqii/uPTCoujxSNFQOBOIvPDno9er6OcMgPhnbqfjnoEfLCSndghPT9x5vUKTC/jy8MK8TezmUVJSho9AVRi/Z3GKGjMXWFRTOfe18K6Ml6U0GaZGiacHZkIG1XOKTQs0HDbY1WhBzeMIakpsqgBEAoU+9wmkpo=
再跑一下看看结果:
OdLiI6XPqXAQKbE9t3GX4NjFArQOp6winRSV8xVaEcKm5NstgFD+e+iTZUSLGJrrdys3Ah7+bMW2sa6R3s8Sly3JSDyHVae5fhsKQ7/ouYFFXZf6Umj3BbE5Mykf6L9DM5U4fp2z5ZJ9EyAfXel8t84xIWpRnt8Ym6UOg+JFW8A=
对比两次你会发现,这里每次使用公钥加密后的结果都不一致,跟对数据的padding即填充有关。
3.使用私钥解密
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
# rsa解密
def rsa_decrypt(cipher_text):
private_key = """-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCfgDPRwaAYZFyNg7EyjMZOnjIRvPPPu4sC6Iu25SDK9z6aE/yK
wNSXI4JF/7gsFlXpV8rjB/SfIjNAunHy0++2djAT1aWJYZSTujBkPblqR/NxRTil
Twoc/oRjLHLF3RuoPOIL4on303Uc9Jgzj1CKbIDUSSk4+gy2rfs2SUZ/uwIDAQAB
AoGAAiZ0zGGbWmjT9JZvZ5qNO9cXHrUY5laFZ7sh0wvgtsvBfMtDLs2tsAHrCi2J
2pJMgzJLSmc7jX+lCDzbN2ZTB3Gz57jhx8ytvOZQod2MlEA52oUQGWeIim91hWYW
TKF8EoaQMfjUGzKXcZHjkPbZbajRFoad9+8w779jpDVJ/QkCQQC3Gd+cR1d0PI3L
/roRRVJKessFk4upqxbRTvqbD5S0pPQjOmzHEUwhluyKJJXfdBuwMbZKfBhO/FdI
fpe+m375AkEA3wDtuuNuNVZoJIOdFP/QeglPx8vKyzNHqWHITRels+wyZRKIEJU0
QfseNa0s2egqSDCX7EdDZIuujO0ERDM9UwJAGcVCe7Ru0qVTL8sCVTv0gRcXTAmg
Npkl9P+wtfJTc7ljwzGN7da5aGDdmfPcRD8LRpk4lvMwWK2be1CV+vXXwQJAfKQy
O6DeemVfM/l0FMaeqXcG5m8bW9O/nAaRQ7WR4iyERkXDUzFx0ecfjXTLesfuygaP
A3sZSdtgplfbaJsTDQJAdg5IvgiGOksvjvOf5wr3vHy0v0na/pMJVLol7t0GXFtj
LHntk5bjwJVx/ltaFSR/zG8nM7zASpid3B9BH3H5qA==
-----END RSA PRIVATE KEY-----"""
decode_text = base64.b64decode(cipher_text)
cipher = Cipher_pkcs1_v1_5.new(RSA.importKey(private_key)) # 创建用于执行pkcs1_v1_5加密或解密的密码
decrypt_text = cipher.decrypt(decode_text, b"rsa")
return decrypt_text.decode("utf-8")
if __name__ == "__main__":
result = "OdLiI6XPqXAQKbE9t3GX4NjFArQOp6winRSV8xVaEcKm5NstgFD+e+iTZUSLGJrrdys3Ah7+bMW2sa6R3s8Sly3JSDyHVae5fhsKQ7/ouYFFXZf6Umj3BbE5Mykf6L9DM5U4fp2z5ZJ9EyAfXel8t84xIWpRnt8Ym6UOg+JFW8A="
message = rsa_decrypt(result)
print(message)
运行结果:
Hello, 你好, 这是一段RSA加密测试代码!
可以看到,和加密前的数据一模一样。
4.使用私钥加签
import base64
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
# 私钥加签名
def rsa_encrypt(message):
private_key = """-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCfgDPRwaAYZFyNg7EyjMZOnjIRvPPPu4sC6Iu25SDK9z6aE/yK
wNSXI4JF/7gsFlXpV8rjB/SfIjNAunHy0++2djAT1aWJYZSTujBkPblqR/NxRTil
Twoc/oRjLHLF3RuoPOIL4on303Uc9Jgzj1CKbIDUSSk4+gy2rfs2SUZ/uwIDAQAB
AoGAAiZ0zGGbWmjT9JZvZ5qNO9cXHrUY5laFZ7sh0wvgtsvBfMtDLs2tsAHrCi2J
2pJMgzJLSmc7jX+lCDzbN2ZTB3Gz57jhx8ytvOZQod2MlEA52oUQGWeIim91hWYW
TKF8EoaQMfjUGzKXcZHjkPbZbajRFoad9+8w779jpDVJ/QkCQQC3Gd+cR1d0PI3L
/roRRVJKessFk4upqxbRTvqbD5S0pPQjOmzHEUwhluyKJJXfdBuwMbZKfBhO/FdI
fpe+m375AkEA3wDtuuNuNVZoJIOdFP/QeglPx8vKyzNHqWHITRels+wyZRKIEJU0
QfseNa0s2egqSDCX7EdDZIuujO0ERDM9UwJAGcVCe7Ru0qVTL8sCVTv0gRcXTAmg
Npkl9P+wtfJTc7ljwzGN7da5aGDdmfPcRD8LRpk4lvMwWK2be1CV+vXXwQJAfKQy
O6DeemVfM/l0FMaeqXcG5m8bW9O/nAaRQ7WR4iyERkXDUzFx0ecfjXTLesfuygaP
A3sZSdtgplfbaJsTDQJAdg5IvgiGOksvjvOf5wr3vHy0v0na/pMJVLol7t0GXFtj
LHntk5bjwJVx/ltaFSR/zG8nM7zASpid3B9BH3H5qA==
-----END RSA PRIVATE KEY-----"""
rsa_key = RSA.importKey(private_key)
signer = Signature_pkcs1_v1_5.new(rsa_key)
digest = SHA.new()
digest.update(message.encode("utf-8"))
sign = signer.sign(digest)
signature = base64.b64encode(sign)
return signature.decode("utf-8")
if __name__ == "__main__":
message = "Hello, 你好, 这是一段RSA加密测试代码!"
signature = rsa_encrypt(message)
print(signature)
跑一次:
ai3x9IMY+UQysZ+KNlnXsUi29ykqvtOUue6kdysFXvdnviQXKKDb6phGzd1mZEHYOTh81HiB6kS/vN93PRRDpPwCsKxbkB3SPjQnM/we2cZnZGK/bFUXoulL/a0V86UKEwL8vqRMNyDn1zrv9YwhvblTzdu8ywkawXuH6O/8SRw=
再跑一次:
ai3x9IMY+UQysZ+KNlnXsUi29ykqvtOUue6kdysFXvdnviQXKKDb6phGzd1mZEHYOTh81HiB6kS/vN93PRRDpPwCsKxbkB3SPjQnM/we2cZnZGK/bFUXoulL/a0V86UKEwL8vqRMNyDn1zrv9YwhvblTzdu8ywkawXuH6O/8SRw=
然后你会很神奇的发现用私钥加签,每次签名是一致的。
5.使用公钥验签
import base64
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
def check_verify():
public_key = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfgDPRwaAYZFyNg7EyjMZOnjIR
vPPPu4sC6Iu25SDK9z6aE/yKwNSXI4JF/7gsFlXpV8rjB/SfIjNAunHy0++2djAT
1aWJYZSTujBkPblqR/NxRTilTwoc/oRjLHLF3RuoPOIL4on303Uc9Jgzj1CKbIDU
SSk4+gy2rfs2SUZ/uwIDAQAB
-----END PUBLIC KEY-----"""
message_verify = "Hello, 你好, 这是一段RSA加密测试代码!"
signature = "ai3x9IMY+UQysZ+KNlnXsUi29ykqvtOUue6kdysFXvdnviQXKKDb6phGzd1mZEHYOTh81HiB6kS/vN93PRRDpPwCsKxbkB3SPjQnM/we2cZnZGK/bFUXoulL/a0V86UKEwL8vqRMNyDn1zrv9YwhvblTzdu8ywkawXuH6O/8SRw="
rsa_key = RSA.importKey(public_key)
verifier = Signature_pkcs1_v1_5.new(rsa_key)
hsmsg = SHA.new()
hsmsg.update(message_verify.encode("utf-8"))
is_verify = verifier.verify(hsmsg, base64.b64decode(signature))
print(is_verify)
if __name__ == "__main__":
check_verify()
返回结果:
True
作者:埃菲尔没有塔尖