为什么要使用 Rsa

在前后端交互时,敏感信息需要加密,因为需要选择一种算法。那么要采用什么算法?

实战运用 Rsa

生成 rsa 密钥对

# 生成私钥
openssl genrsa -out live_rsa_private_key.pem 2048

# 生成公钥
openssl rsa -in live_rsa_private_key.pem -pubout -out live_rsa_public_key.pem

前端加密

安装加密模块

npm i jsencrypt

加密明文

import JSEncrypt from 'jsencrypt'

PublicKey = `MFwwDQYJKoZIhvcNAQEBBQADSwAwSslsld==`
const encrypt = new JSEncrypt()
encrypt.setPublicKey(PublicKey)

const raw_password = "123456"
const password = encrypt.encrypt(raw_password)

后端解密

设置私钥环境变量

image-20220105103427682

安装 rsa 依赖包

pip install rsa

读取私钥并解密

import base64
import binascii
import os

import rsa

from rsa import PrivateKey

# 自定义的公共模块
from common.exceptions import DecryptFailed, EncryptError

# 从环境变量中读取私钥
def read_private_key_from_env() -> PrivateKey:
    sep = '-----'
    # PRIVATE_KEY 环境变量名
    raw_key: str = os.getenv('PRIVATE_KEY')
    if not raw_key:
        raise ValueError('Private key not found in environment variable.')
    private_key_str_list = raw_key.split(sep=sep)
    if len(private_key_str_list) != 5:
        raise ValueError('Invalid private key format')
    _, begin, private_key_value, end, _ = private_key_str_list
    # reformat the key
    """
-----BEGIN RSA PRIVATE KEY-----
xxx
-----END RSA PRIVATE KEY-----
    """
    parsed_key = '\n'.join([f'{sep}{begin}{sep}', private_key_value.replace(" ", ""), f'{sep}{end}{sep}'])
    return PrivateKey.load_pkcs1(parsed_key.encode())

# 传入公钥加密后的字段和私钥
# 返回解密后字段
def decrypt(encrypted: str, pri_key: str) -> str:
    """Decrypts a message using the private key.
    """
    try:
        cipher_text: bytes = base64.b64decode(encrypted)
        b: bytes = rsa.decrypt(cipher_text, pri_key)
        s = b.decode()
        return s
    except rsa.pkcs1.DecryptionError:
        raise DecryptFailed(message='Password/token decrypt failed.')
    except binascii.Error:
        raise EncryptError(message='Password/token encrypted string should be base64 encoded')

Rsa“陷阱”

加密长度限制

image-20211231170031004

image-20211231170128168

image-20211231170222452

经过查阅资料得知,RSA 加密算法对明文长度是有限制。

具体计算公式:加密公钥/8 - 11 = 最长加密明文长度

套入公式,512bit 支持的最长明文长度是:512/8 - 11 = 53

也就是说 512bit 的公钥,最长只能加密长度为 53 的明文。

但如果超过了 53,怎么办?

那长度 245 还是还是不够?

总结


↙↙↙阅读原文可查看相关链接,并与作者交流