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