1、RSA加密算法概述
RSA加密算法是非对称加密算法中的一种,在1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的,并取三人名字的首字母命名该算法。
RSA加密算法因其可靠的安全性(目前看来是十分安全的),得到了广泛的认可和使用,ISO(国际标准化组织)、ITU(国际电信联盟)及SWIFT(环球同业银行金融电讯协会)等国际标准组织均采用RSA作为加密标准,PGP等协议也采用RSA算法来传输会话密钥和数字签名;在本篇文章中,将详细讲解RSA算法中的数学原理和加密本质;
rsa加密是非对称加密,常规方式是拿公钥进行加密 私钥进行解密的数据传输过程。
2.在java中 加密模式采用的是RSA/PKCSPadding对于比较长的字符串采用的是分段加密。python实现方式如下 (只针对加密模式是 RSA/PKCSPadding)
import base64
import json
import rsa
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA
from common.config import *
def get_encrypt_data(params):
"""
分段加密
:param params:
:return:
"""
params = json.dumps(params)
params = params.encode("utf-8")
length = len(params)
print(f"加密内容卫{params},加密的长度为{length}")
default_length = 117
if length < default_length: # 如果小于默认长度则不分段 默认加密
return base64.b64encode(encrypt_data(params))
offset = 0
params_list = []
while length - offset > 0:
if length - offset > default_length:
params_list.append(encrypt_data(params[offset:offset + default_length]))
else:
params_list.append(encrypt_data(params_list[offset:]))
offset += default_length
new_str = "".join(params_list) # 将列表的元素组成一个新的字符串
return base64.b64encode(new_str).decode("utf-8")
def encrypt_data(params):
"""
rsa 加密 是带有偏移量的 默认加密
:param params:
:return:
"""
key = f"""-----BEGIN RSA PUBLIC KEY-----\n{public_key}
\n-----END RSA PUBLIC KEY-----\n"""
rakes = RSA.import_key(key)
cipher = Cipher_pkcs1_v1_5.new(rakes)
text = cipher.encrypt(params)
return text
config.py来放我们的公钥
3.当java中或者采用的rsa加密 但是不带偏移量的时候,这时候 对于字符串的补位方式就会发现变化。我们自己补位。不用系统中自带补位、
from Crypto.PublicKey import RSA
import rsa
def Encarta_Nap(message):
"""
RSA 加密 NO PADDING
不带偏移量,每次加密的结果都一样
:return:
"""
key = f"""-----BEGIN RSA PUBLIC KEY-----\n{public_key}
\n-----END RSA PUBLIC KEY-----\n"""
pubkey = RSA.import_key(key)
lens = rsa.common.byte_size(pubkey.n)
b = bytes(message.encode())
for i in range(128 - len(b)):
b = b'\x00' + b # 对较短的加密字符串进行00补位
_b = rsa.transform.bytes2int(b)
_i = rsa.core.encrypt_int(_b, pubkey.e, pubkey.n)
result = rsa.transform.int2bytes(_i, lens)
result = base64.b16decode(result.hex().upper())
print(f"{message}的加密结果是\n{base64.b64encode(result)}")
return base64.b64encode(result)
文中的补位方式是字符串的后面加0,至于为什么不在前面加0,我对比了开发的nopadding加密方式 自己尝试出来的。
4.我还遇到过一次,java中采用的是oaep_padding的补位方式。下面给出详细代码。
不过这个是拿python2来写的,
RSA.pkcs1_oaep_padding 这个是可以更改的,记得里面就有2中的 nopadding方式 我们只需要在我们的加密字符串中的后面进行补位 补0即可 其他不变
import base64
import os
from M2Crypto import BIO, RSA
report_folder = os.path.normpath(os.path.join(os.path.dirname(os.path.dirname(__file__)),'common'))
with open(report_folder+"/rsa_public.pem", 'r') as f:
pubkey = f.read()
with open(report_folder+"/rsa_private_pkcs8.pem", 'r') as f:
prikey = f.read()
def sms_encrypt(message):
# 加密
pub_bio = BIO.MemoryBuffer(pubkey.encode('utf-8')) # 公钥字符串
pub_rsa = RSA.load_pub_key_bio(pub_bio) # 加载公钥
secret = pub_rsa.public_encrypt(message, RSA.pkcs1_oaep_padding) # 公钥加密 RSA/NONE/OAEPPadding 当选择的是NOPADDING的方式 需要队message进行补位。后面补0 其他不变
0
sign = base64.b64encode(secret) # 密文base64编码
return sign