python实现RSA加密解密 及 签名验签功能

本篇写一下python实现RSA的加密解密功能、私钥签名 公钥验签功能。

主要分三部分来介绍

  1. 生成私钥和公钥
    脚本如下,运行后会生成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-----
  1. 公钥加密 私钥解密
    下面是通过公钥加密,然后用公钥解密的实现:
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
  1. 私钥签名 公钥验签
    下面是利用私钥进行签名,然后用公钥去验证签名的实现
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())
  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值