本篇写一下python实现RSA的加密解密功能、私钥签名 公钥验签功能。
主要分三部分来介绍
- 生成私钥和公钥
脚本如下,运行后会生成public.pem(公钥) 和 private.pem(私钥)
def generateKeys():
print("generate priv key start.")
random_generator = Random.new().read
rsa = RSA.generate(2048, random_generator)
private_pem = rsa.exportKey()
with open('private.pem', 'w') as f:
f.write(private_pem)
public_pem = rsa.publickey().exportKey()
with open('public.pem', 'w') as f:
f.write(public_pem)
print("generate priv key done.")
生成的私钥内容如下:
$ cat private.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAm1dN6Ue55QXl+SaBZTDPN3CkQMx+tWMyWP41sk+5jHqSTZrb
4zLH7Tvw2YLlMVGJM83jWtpEl1VJTGuHl3J0N7ts3bg7rq3ffU9my7rIC2Lz812A
B1n39hp7FcDb/oEGbZnhQJasRVuJwglDrdgePY5hI/PI/mpBj3+tKpmRTU7wl5W5
8si9xzJnx4aCHgu8jKEQzF9J4wAeSsPHc7ajjDD0c7me1tqFXSXzRlUVUw0i2fT6
JmGyw9iNTeyRZ/xQIXq6OOyf+dxsETr1Lwe6ozsdmLU+2bx6ku2BzPc5jpxmTP2j
e+y1zb+NsEPQUfbeHRH6bFKKi8OwP61J4qMTtwIDAQABAoIBAA1h8hZc1YkDfxJ9
3Lvo/pEaJSxn8aqSxy2fiOS5tZSCosQIyVTDdTHc7hzvB+u9yIIsBKA5GZun/06U
HPRRKe37OZ/IVWvxEsXq50I57y378mRO886uU4xiL6RqHwnH99PNY/h6gpDfF/kd
bzU03zYSZBAC2pgAc3F3YGXBISF1vyBTqQTAhohhbVayYBdmOI5xdoRnLCeKsc86
mpzL4RIcWTlWTc/ehX7dTL17thozOMRwHgOUaT+bqtPXa4U1VtbInBoi/UdfZqPy
8fMUP8C9JobAbM/5fZ0/+uODh6xkwJuPzakKawMBYS/1PL4wOmTyNdXb/mjMFnIN
8KXqvBECgYEAvUwATtYDqrONbhXq0gCcNNCDQvmt2ENIbpztB4LM1QTEWcfnmBym
hpfOqAQXHzFLaa7sGDc1t7VSrH82tBoORcKI9ccx+0o2vUb16wQ9KLiE8Q6EVDpe
6QP7m+zSblx20YYWz29+fO2bIMvFnH1QIagLQ2ItoUuZZAvViGxmZJ0CgYEA0hQ7
II08/aJh4daevEbdKzUWakIoTgsjoRUb26B0YJ7wCPTuz8PkIbZAXnK8wYoS12GW
DnlDhVk0bKn46JyDfCxeL1OSlm6v1rhsfeDgBjgdUIuwhzcQxzWj0CJqHOfEUqeB
qR3tz8ygpztwejosSWrAZlP363tb75uoekgbZ2MCgYEAlVVApPDWwbKWLzNhJTxP
/qZD9vErgQFLQd/Qae15E8+H6t/2RxzLDkDySb+4UeY8fOn+3PepC/0idGyDRj+L
5OKb03DKcFhSqK0zUaztZpNyZQyzvhKyTxbSRmbkdyXAongqxIhLe9iiWZQHl/WP
4o1EHWt1Xdpa7v8a/F2vxU0CgYEAtEpQhBsyYKnfPyYljId0gARLfF3SoUfGCBRJ
mC8YMWO1tLofyYbgXl4+18+4VpDcoqNJWJqRa/umlis5Rsgrv4GEQzGB+EB9/9S+
pzk6iZvW7K01jpWffJd4QsOGNdBiGF1RVYYt9cwzg9HrMbqDD27iN++QMTPpLrVz
3Z3MhukCgYEAi6QSysyuCsC/3P5+xHDyWw1Z9A1rdz41GFNZslculiXBYCv7z7bk
obQ8CdaxB1CzPSZR00970ZvNByeKBPjFv2o432wW15SGyI61z0FLglZ6SDC9ytWA
4fzF8xbY2ZT9JSm+QaI652wdx4lDXAxvn01ztm56J7TTfS7qTdqBbig=
-----END RSA PRIVATE KEY-----
生成的公钥内容如下:
$ cat public.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm1dN6Ue55QXl+SaBZTDP
N3CkQMx+tWMyWP41sk+5jHqSTZrb4zLH7Tvw2YLlMVGJM83jWtpEl1VJTGuHl3J0
N7ts3bg7rq3ffU9my7rIC2Lz812AB1n39hp7FcDb/oEGbZnhQJasRVuJwglDrdge
PY5hI/PI/mpBj3+tKpmRTU7wl5W58si9xzJnx4aCHgu8jKEQzF9J4wAeSsPHc7aj
jDD0c7me1tqFXSXzRlUVUw0i2fT6JmGyw9iNTeyRZ/xQIXq6OOyf+dxsETr1Lwe6
ozsdmLU+2bx6ku2BzPc5jpxmTP2je+y1zb+NsEPQUfbeHRH6bFKKi8OwP61J4qMT
twIDAQAB
-----END PUBLIC KEY-----
- 公钥加密 私钥解密
下面是通过公钥加密,然后用公钥解密的实现:
def pubEncryAndprivDecry():
content_size = '10000'
#encrypt
with open("public.pem") as f:
key = f.read()
rsakey = RSA.importKey(key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(content_size))
print(cipher_text)
with open("encrypted_data", "wb") as f: ##save encrypted data to file
f.write(cipher_text)
#decrypt
with open("private.pem") as f:
key = f.read()
prikey = RSA.importKey(key)
cipher2 = Cipher_pkcs1_v1_5.new(prikey)
with open("encrypted_data") as f: ### read data from encrypted file
data = f.read()
text = cipher2.decrypt(base64.b64decode(data), random_generator)
print(text)
运行效果如下,解密后的text为1000,符合预期。
$ ./test.py
generate priv key start.
generate priv key done.
E25FkcAYB7XFil2sI3OvA4S6KnQppTPh7zIO3LgQKnBmLpQaQfdICwEuUEae1nNFntGdn5ahLou5VvyN/2s9TZgvkj5DcJzAlDRX2OZrllM4mbCeTLyWYVyGqTVZx0SIFtQG/F1053j5OTtv2xnlBaveiZasqFzrFtSuDwzgZxL0xKtBbI8GPUKAp/lq9UIHAqL0uewfdsOG6axus3zEnkfHJwIndBQ4Wu8ewDFXmGsD+XDUT/CgIBTMQILE9dxJG/CeoWWUBxJwepZ855zmvEkNSUDFhTEypatkW3DlKOfFEVERWztH0t/J7aRUVv2AaiE5t0iI3Y671MQPz7ytSg==
10000
- 私钥签名 公钥验签
下面是利用私钥进行签名,然后用公钥去验证签名的实现
def privSignAndPubAttesation():
print("privSignAndPubAttesation entry.")
#private key sign
with open("private.pem") as f:
key = f.read()
rsakey = RSA.importKey(key)
signer = Signature_pkcs1_v1_5.new(rsakey)
content_size = '3000'
digest = SHA.new()
digest.update(content_size)
sign_data = signer.sign(digest)
signature = base64.b64encode(sign_data)
print(signature)
#public key attesation
with open("public.pem") as f:
key = f.read()
rsakey = RSA.importKey(key)
verifier = Signature_pkcs1_v1_5.new(rsakey)
digest = SHA.new()
digest.update('3000')
is_matched = verifier.verify(digest, base64.b64decode(signature))
print(is_matched)
运行效果如下,返回True,验签正常。
$ ./test.py
generate priv key start.
generate priv key done.
privSignAndPubAttesation entry.
FBx2QUCHYZy1UU+AB30A7d/kJ3mUeOSSUNDfDQ2ecGK/ATVh8EWW1rQ6gTAOKkuAAd2ejNizC6DR/GvCflh3PnfcH0kGAkWW5M7rZJ0/VMmlx45AHYvstWZmC5fSEfAHLHa0PcR3Y7C7+EH+Bv90YlShghD3ONLAFXo+5hOtANkgJndAsmfYLsIbB2Ap4ikGRPazBU8Xwz4iZN2duyVwjuS1PZ0uXCNenjm+zYn8/Ot0kEsVpXzO8aZ0GDtu2rJbyOZSGLU2YMZ2ynzOwGcIO9Ng+wm/2FMfsEvRiLIQOQhWMMEYem+68d7B3/o4A8Hj4n0T1KJzlzraY4qpbrjT2A==
True
完整的python脚本内容如下,供参考:
#!/usr/bin/env python
import argparse
import sys
import base64
import hashlib
from Crypto import Random
from Crypto.Hash import SHA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.PublicKey import RSA
random_generator = ""
cipher_text = ""
content_size = ""
signature_data = ""
def generateKeys():
print("generate priv key start.")
random_generator = Random.new().read
rsa = RSA.generate(2048, random_generator)
private_pem = rsa.exportKey()
with open('private.pem', 'w') as f:
f.write(private_pem)
public_pem = rsa.publickey().exportKey()
with open('public.pem', 'w') as f:
f.write(public_pem)
print("generate priv key done.")
def pubEncryAndprivDecry():
content_size = '10000'
#encrypt
with open("public.pem") as f:
key = f.read()
rsakey = RSA.importKey(key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(content_size))
print(cipher_text)
with open("encrypted_data", "wb") as f: ##save encrypted data to file
f.write(cipher_text)
#decrypt
with open("private.pem") as f:
key = f.read()
prikey = RSA.importKey(key)
cipher2 = Cipher_pkcs1_v1_5.new(prikey)
with open("encrypted_data") as f: ### read data from encrypted file
data = f.read()
text = cipher2.decrypt(base64.b64decode(data), random_generator)
print(text)
def privSignAndPubAttesation():
print("privSignAndPubAttesation entry.")
#private key sign
with open("private.pem") as f:
key = f.read()
rsakey = RSA.importKey(key)
signer = Signature_pkcs1_v1_5.new(rsakey)
content_size = '3000'
digest = SHA.new()
digest.update(content_size)
sign_data = signer.sign(digest)
signature = base64.b64encode(sign_data)
print(signature)
#public key attesation
with open("public.pem") as f:
key = f.read()
rsakey = RSA.importKey(key)
verifier = Signature_pkcs1_v1_5.new(rsakey)
digest = SHA.new()
digest.update('3000')
is_matched = verifier.verify(digest, base64.b64decode(signature))
print(is_matched)
def main():
#generate priv and public key
generateKeys()
#1. public key encrypt,then priv key decrypt
#pubEncryAndprivDecry()
#2. privkey sign and publickey attestation
privSignAndPubAttesation()
return 0
if __name__ == '__main__':
sys.exit(main())