python RSA rsa 加密、解密、签名、验签 密钥文件讲解说明

RSA公私钥生成地址

http://www.metools.info/code/c80.html

 

在线RSA PKCS#1、PKCS#8公钥格式转换工具

http://www.metools.info/code/c85.html

 

1.从PFX文件 提取 公钥、私钥 方法一

pkg文件导出私钥:
openssl pkcs12 -in /tmp/nonghang/应用测试证书.pfx -out privatekey.pem -nocerts
输入pkg文件的密码:111111
输入待到出的密钥文件的密码,最少长度为4个字符,比如输入:2222
 
导出的privatekey.pem文件是一个加密后的私钥,可以对它进行解密,保存一个不加密的私钥文件:
openssl rsa -in privatekey.pem -out privatekey_plain.pem
输入上一步设置的密码:2222 
 
x509.cer 提取公钥
openssl  x509 -nocert  -inform der -pubkey -in TrustPay.cer -out nh_release_public_key.pem 
 

2.从PFX文件 提取 公钥、私钥 方法二

1、提取密钥对(如果pfx证书已加密,会提示输入密码。)
openssl pkcs12 -in 1.pfx -nocerts -nodes -out 1.key

2、从密钥对提取私钥
openssl rsa -in 1.key -out 1_pri.key

3、从密钥对提取公钥
openssl rsa -in 1.key -pubout -out 1_pub.key

3.使用openssl将RSA的X.509公钥转成PKCS#1标准

  3.1 确定RSA公钥标准

假如公钥是以X.509标准导出,以PEM格式存储,那么形式如下:

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

假如公钥是以PKCS#1标准导出,以PEM格式存储,那么形式如下:

-----BEGIN RSA PRIVATE KEY----- 
...
-----END RSA PRIVATE KEY-----

  3.2使用openssl将X.509转成PKCS#1

openssl rsa -pubin -in x509_public.key  -RSAPublicKey_out > rsa_public.key

 

 

 

4.Python RAS 加密、解密、签名、验签

python中用于RSA加解密的库有好久个,本文主要讲解rsa 库对于RSA加密、解密、签名、验签的知识点。 

推荐使用rsa库

 

加密是为了保证传输内容隐私,签名是为了保证消息真实性。

服务器存私钥,客户端存公钥。(服务器和客户端关系可以考虑为 1:N)

客户端往服务器传输内容,更多考虑是隐私性,所以公钥签名、私钥解密。

服务器往客户端传输内容,更多考虑真实性,所以私钥签名,公钥验签。

消息的摘要生的算法常用的是MD5或者SHA1,消息内容不一样,生成的摘要信息一定不一样。

真实性的考虑一方面是内容由私钥拥有者发出,另一方面内容在传输过程中没有改变过,所以签名的对象是传输信息生成的消息摘要(摘要内容短,签名也会快些)。

每次加密的长度需要小于密钥长度-特殊位(128位公钥,最长可加密128-11=117位明文)。

每次解密的长度需要小于密钥的长度(128位私钥解密,解密密文长度需要小于等于128位)。

如果加解密内容过长,就需要分段加密、解密。

PEM格式的密钥为base64位文本格式。

 

# -*- coding: UTF-8 -*-
# ! /usr/bin/env python
import base64
import rsa
from rsa import common


# 使用 rsa库进行RSA签名和加解密
class RsaUtil(object):
    PUBLIC_KEY_PATH = '/tmp/gbzj/public_key.pem'  # 公钥
    PRIVATE_KEY_PATH = '/tmp/gbzj/private_key.pem'  # 私钥

    # 初始化key
    def __init__(self,
                 company_pub_file=PUBLIC_KEY_PATH,
                 company_pri_file=PRIVATE_KEY_PATH):

        if company_pub_file:
            self.company_public_key = rsa.PublicKey.load_pkcs1_openssl_pem(open(company_pub_file).read())
        if company_pri_file:
            self.company_private_key = rsa.PrivateKey.load_pkcs1(open(company_pri_file).read())

    def get_max_length(self, rsa_key, encrypt=True):
        """加密内容过长时 需要分段加密 换算每一段的长度.
            :param rsa_key: 钥匙.
            :param encrypt: 是否是加密.
        """
        blocksize = common.byte_size(rsa_key.n)
        reserve_size = 11  # 预留位为11
        if not encrypt:  # 解密时不需要考虑预留位
            reserve_size = 0
        maxlength = blocksize - reserve_size
        return maxlength

    # 加密 支付方公钥
    def encrypt_by_public_key(self, message):
        """使用公钥加密.
            :param message: 需要加密的内容.
            加密之后需要对接过进行base64转码
        """
        encrypt_result = b''
        max_length = self.get_max_length(self.company_public_key)
        while message:
            input = message[:max_length]
            message = message[max_length:]
            out = rsa.encrypt(input, self.company_public_key)
            encrypt_result += out
        encrypt_result = base64.b64encode(encrypt_result)
        return encrypt_result

    def decrypt_by_private_key(self, message):
        """使用私钥解密.
            :param message: 需要加密的内容.
            解密之后的内容直接是字符串,不需要在进行转义
        """
        decrypt_result = b""

        max_length = self.get_max_length(self.company_private_key, False)
        decrypt_message = base64.b64decode(message)
        while decrypt_message:
            input = decrypt_message[:max_length]
            decrypt_message = decrypt_message[max_length:]
            out = rsa.decrypt(input, self.company_private_key)
            decrypt_result += out
        return decrypt_result

    # 签名 商户私钥 base64转码
    def sign_by_private_key(self, data):
        """私钥签名.
            :param data: 需要签名的内容.
            使用SHA-1 方法进行签名(也可以使用MD5)
            签名之后,需要转义后输出
        """
        signature = rsa.sign(data, priv_key=self.company_private_key,
                             hash_method='SHA-256')  # 加密方式Use 'MD5', 'SHA-1', 'SHA-224', SHA-256', 'SHA-384' or 'SHA-512'
        return base64.b64encode(signature)

    def verify_by_public_key(self, message, signature):
        """公钥验签.
            :param message: 验签的内容.
            :param signature: 对验签内容签名的值(签名之后,会进行b64encode转码,所以验签前也需转码).
        """
        signature = base64.b64decode(signature)
        return rsa.verify(message, signature, self.company_public_key)


message = 'appId=f334fdgd&bizContent={"authCode":"4196a49571e747259028fa25df330604b4f6d301"}&timestamp=2022-08-01 10:20:08'
print("明文内容:>>> ")
print(message)
rsaUtil = RsaUtil()
encrypy_result = rsaUtil.encrypt_by_public_key(message)
print("加密结果:>>> ")
print(encrypy_result)
decrypt_result = rsaUtil.decrypt_by_private_key(encrypy_result)
print("解密结果:>>> ")
print(decrypt_result)

sign = rsaUtil.sign_by_private_key(message)
print("签名结果:>>> ")
print(sign)
print("验签结果:>>> ")
print(rsaUtil.verify_by_public_key(message, sign))

 



posted on 2022-08-01 14:46  星河赵  阅读(2458)  评论(0编辑  收藏  举报

导航