python RSA 加密(前后端模式)

前言:

python环境:python3.7_64 

python rsa 加密。首先在python里面,有rsa包、pycrypto包、pycryptodome包。(包版本在代码头部注释中

说一下这个三个包的区别,rsa包是一个pkcs1格式的,后面两个时pkcs8格式。并且pycrypto和pycryptodome是一样的,但是pycrypto安装复杂(需要安装c++等什么组件)所以建议使用pycryptodome包(本文也是使用这个包)。

格式区别如下:

pkcs1格式的pem长这样(头尾有RSA):

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC5BW6T9GVaaG/epGDjPpY3wN0DrBt+NojvxkEgpUdOAxgAepqe
GbSqtXAd+MOOBbHxIOEwrFC9stkypQgxrB49tXDI+4Jj8MuKI15HEmI8k7+tRDOl
J5TFSL2J9KA3GuQbyVAhlpxl+YnV7yjxP9l1dkbApg1ixSd5KOPbaQ00WQIDAQAB
AoGAYiqzpOTC8dj/og1tKqUGZsZ5fX1PiQO+XBnAbGXFE2sozPhAGSpiZUCnH//h
IfV7mAht8rk6java+bf+RPyhfg0zW7oXy0pm8DwoW7+0fOzQ4sEYeoqza/VrkYwR
5BxBa+KyT1HCi4uXogyDlQT1p0ZT0iaqZBfTApdyVkmcQEECQQDhfPl+ILl0bh0H
8ORoMmmxAZMn293+de441OlAjL3CsF4yhUUdavAYWM0RAV5MJtKUTR4ZpRXkB/pq
kgyTxpr9AkEA0g6pQRpcGxulr2758ZlOLdL8B1n1ubre464IKQ0zNfERKhR/j7U8
LGF+3mhZuoSEdklwLCJ8ZMvIhkV0v8JjjQJBANtqXOyas1vUenNruRabV7ViLuuu
S0p9Px4WMBMb4Ns9+6t1e1ew44kNgB54EmZPsMGWeR/DQJXwHYDuNUbnD5ECQA7S
Gf8N7RG8kaQfIGN7fZieGkoqfrvsA23tCYZb+BEGQT/G0nlBQE2hU2I92pbeYro1
1ERI6p3yAuP2YpZlEMECQGNzhqshYfDiWwU4Q3aZWkRrv74uIXk1HQoFH1BthzQJ
TbzKH/LEqZN8WVau3bf41yAx2YoaOsIJJtOUTYcfh14=
-----END RSA PRIVATE KEY-----

pkcs8格式pem长这样(头尾无RSA):

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALkFbpP0ZVpob96k
YOM+ljfA3QOsG342iO/GQSClR04DGAB6mp4ZtKq1cB34w44FsfEg4TCsUL2y2TKl
CDGsHj21cMj7gmPwy4ojXkcSYjyTv61EM6UnlMVIvYn0oDca5BvJUCGWnGX5idXv
KPE/2XV2RsCmDWLFJ3ko49tpDTRZAgMBAAECgYBiKrOk5MLx2P+iDW0qpQZmxnl9
fU+JA75cGcBsZcUTayjM+EAZKmJlQKcf/+Eh9XuYCG3yuTqNq9r5t/5E/KF+DTNb
uhfLSmbwPChbv7R87NDiwRh6irNr9WuRjBHkHEFr4rJPUcKLi5eiDIOVBPWnRlPS
JqpkF9MCl3JWSZxAQQJBAOF8+X4guXRuHQfw5GgyabEBkyfb3f517jjU6UCMvcKw
XjKFRR1q8BhYzREBXkwm0pRNHhmlFeQH+mqSDJPGmv0CQQDSDqlBGlwbG6Wvbvnx
mU4t0vwHWfW5ut7jrggpDTM18REqFH+PtTwsYX7eaFm6hIR2SXAsInxky8iGRXS/
wmONAkEA22pc7JqzW9R6c2u5FptXtWIu665LSn0/HhYwExvg2z37q3V7V7DjiQ2A
HngSZk+wwZZ5H8NAlfAdgO41RucPkQJADtIZ/w3tEbyRpB8gY3t9mJ4aSip+u+wD
be0Jhlv4EQZBP8bSeUFATaFTYj3alt5iujXUREjqnfIC4/ZilmUQwQJAY3OGqyFh
8OJbBThDdplaRGu/vi4heTUdCgUfUG2HNAlNvMof8sSpk3xZVq7dt/jXIDHZiho6
wgkm05RNhx+HXg==
-----END PRIVATE KEY-----

好,格式搞清楚后就直接上代码(pkcs1格式的代码):

"""
python3.7_64
rsa==4.7.2
"""

import base64
import json
import re
import rsa


# 生成密钥
def create_pem_key():
    """
    生成密钥
    :return: 公钥、私钥
    """
    (pubkey, privkey) = rsa.newkeys(1024)
    return pubkey.save_pkcs1().decode(), privkey.save_pkcs1().decode()


# 公钥加密
def rsadecrypt(pubkey, msg):
    """
    公钥加密
    :param pubkey: 公钥
    :param msg: 需要加密的字符串
    :return: 加密后的字符串
    """
    msg = json.dumps({"data": msg})
    pubkey = rsa.PublicKey.load_pkcs1(pubkey)
    data = ''
    msglen = len(msg)
    # 最大加密长度为:密钥长度/8-11  例如:1024/8-11=117
    list = cut_text(msg, 117)  # 切片
    for item in list:
        crypto = rsa.encrypt(item.encode(), pubkey)
        crypto = base64.b64encode(crypto).decode()
        data = data + crypto + " "
    data = data[0:len(data) - 1]
    return data


# 私钥解密
def rsacrypto(privkey, data):
    """
    私钥解密
    :param privkey: 私钥
    :param data: 密文
    :return: 明文
    """
    privkey = rsa.PrivateKey.load_pkcs1(privkey)
    list = data.split(' ')
    message = ''
    for item in list:
        if item:
            tempmsg = base64.decodebytes(item.encode())
            tempmsg = rsa.decrypt(tempmsg, privkey).decode()
            message = message + tempmsg
    message = json.loads(message)['data']
    return message


# 私钥签名
def sign(privkey, data):
    """
    私钥签名
    :param privkey: 私钥
    :param data: 密文
    :return: 签名
    """
    privkey = rsa.PrivateKey.load_pkcs1(privkey)
    signature = rsa.sign(data.encode(), privkey, 'SHA-256')
    signature = base64.b64encode(signature).decode()
    return signature


# 公钥验证
def checksign(pubkey, sign, data):
    """
    公钥验证
    :param pubkey: 公钥
    :param sign: 签名
    :param data: 密文
    :return: Ture、False
    """
    try:
        pubkey = rsa.PublicKey.load_pkcs1(pubkey)
        rsa.verify(data.encode(), base64.decodebytes(sign.encode()), pubkey)
        return True
    except:
        return False


# 字符串切割
def cut_text(text, lenth):
    textArr = re.findall('.{' + str(lenth) + '}', text)
    textArr.append(text[(len(textArr) * lenth):])
    return textArr


if __name__ == '__main__':
    pubkey, prikey = create_pem_key()
    r = rsadecrypt(pubkey, "我的世界12go")
    print("加密数据:", r)
    msg = rsacrypto(prikey, r)
    print('解密数据:', msg)
    signstr = sign(prikey, r)
    print('签名:', signstr)
    result = checksign(pubkey, signstr, r)
    print('验证:', result)

pkcs8格式的代码如下:

"""
python3.7_64
pycryptodome==3.10.1
"""

import base64
import json
import re
from Crypto import Random
import Crypto.PublicKey.RSA
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


# 生成密钥
def create_pem_key():
    """
    生成密钥
    :return: 公钥、私钥
    """
    # 伪随机数生成器
    random_generator = Crypto.Random.new().read
    # rsa算法生成实例
    rsa = RSA.generate(1024, random_generator)
    # master的秘钥对的生成
    prikey = rsa.exportKey().decode()
    pubkey = rsa.publickey().exportKey().decode()
    return (pubkey, prikey)


# 公钥加密
def rsadecrypt(pubkey, msg):
    """
    公钥加密
    :param pubkey: 公钥
    :param msg: 需要加密的字符串
    :return: 加密后的字符串
    """
    msg = json.dumps({"data": msg})
    data = ''
    # 最大加密长度为:密钥长度/8-11  例如:1024/8-11=117
    list = cut_text(msg, 117)  # 切片
    for item in list:
        rsakey = RSA.importKey(pubkey)
        cipher = Cipher_pkcs1_v1_5.new(rsakey)
        cipher_text = base64.b64encode(cipher.encrypt(item.encode())).decode()
        data = data + cipher_text + " "
    data = data[0:len(data) - 1]
    return data


# 私钥解密
def rsacrypto(prikey, data):
    """
    私钥解密
    :param privkey: 私钥
    :param data: 密文
    :return: 明文
    """
    random_generator = Crypto.Random.new().read
    list = data.split(' ')
    message = ''
    for item in list:
        if item:
            rsakey = RSA.importKey(prikey)
            cipher = Cipher_pkcs1_v1_5.new(rsakey)
            text = cipher.decrypt(base64.b64decode(item), random_generator).decode()
            message = message + text
    message = json.loads(message)['data']
    return message


# 私钥签名
def sign(prikey, data):
    """
    私钥签名
    :param privkey: 私钥
    :param data: 密文
    :return: 签名
    """
    rsakey = RSA.importKey(prikey)
    signer = Signature_pkcs1_v1_5.new(rsakey)
    digest = SHA.new()
    digest.update(data.encode())
    sign = signer.sign(digest)
    signature = base64.b64encode(sign).decode()
    return signature


# 公钥验证
def checksign(pubkey, sign, data):
    """
    公钥验证
    :param pubkey: 公钥
    :param sign: 签名
    :param data: 密文
    :return: Ture、False
    """
    try:
        rsakey = RSA.importKey(pubkey)
        verifier = Signature_pkcs1_v1_5.new(rsakey)
        digest = SHA.new()
        # Assumes the data is base64 encoded to begin with
        digest.update(data.encode())
        is_verify = verifier.verify(digest, base64.b64decode(sign))
        return is_verify
    except:
        return False


# 字符串切割
def cut_text(text, lenth):
    textArr = re.findall('.{' + str(lenth) + '}', text)
    textArr.append(text[(len(textArr) * lenth):])
    return textArr


if __name__ == '__main__':
    pubkey, prikey = create_pem_key()
    r = rsadecrypt(pubkey, "我的世界12go")
    print("加密数据:", r)
    msg = rsacrypto(prikey, r)
    print('解密数据:', msg)
    signstr = sign(prikey, r)
    print('签名:', signstr)
    result = checksign(pubkey, signstr, r)
    print('验证:', result)

python后端rsa加密完成后,js前端rsa加密下期更新!

你可能感兴趣的:(Python,python,rsa)