前端JS与后端Python RSA-OAEP加密结果不一致问题求助
RSA-OAEP加密前后端结果不一致的原因及解决方法
核心问题:哈希算法不匹配
两段代码的哈希算法配置不一致,这是导致加密结果不同的根本原因:
- Python端使用PyCryptodome库时,
PKCS1_OAEP.new()默认采用SHA-1作为哈希算法 - JavaScript端的Web Crypto API明确指定了SHA-256作为哈希算法
RSA-OAEP的加密过程依赖哈希算法生成掩码,算法不一致会直接导致最终密文不同。
修正方案:统一哈希算法为SHA-256
将两端的哈希算法统一为SHA-256,即可保证加密结果一致。
修改后的Python代码
需要在创建PKCS1_OAEP cipher时显式指定SHA-256哈希算法:
import base64 from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Hash import SHA256 def check_key_pair_match(public_key_pem: str, plaintext: str): # 明文转UTF-8字节 plaintext_bytes = plaintext.encode('utf-8') # 导入公钥并指定SHA-256哈希算法 public_key = RSA.import_key(public_key_pem) cipher = PKCS1_OAEP.new(public_key, hashAlgo=SHA256.new()) encrypted_data = cipher.encrypt(plaintext_bytes) # 转Base64输出(解码为字符串,和JS输出格式统一) encrypted_data_base64 = base64.b64encode(encrypted_data).decode('utf-8') print("public_key:", public_key_pem) print("Plaintext:", plaintext_bytes) print("Encrypted:", encrypted_data_base64)
JavaScript代码(无需修改)
JS代码已经正确指定了SHA-256,保持原代码即可:
async function checkKeyPairMatch(publicKeyPem, plaintext) { const encoder = new TextEncoder(); const plaintextBytes = encoder.encode(plaintext); const publicKey = await importPublicKey(publicKeyPem); const encryptedData = await crypto.subtle.encrypt( { name: "RSA-OAEP", }, publicKey, plaintextBytes ); const encryptedBase64 = arrayBufferToBase64(encryptedData); console.log("public_key:", publicKeyPem); console.log("Plaintext:", plaintextBytes); console.log("Encrypted:", encryptedBase64); } async function importPublicKey(publicKeyPem) { const pemHeader = "-----BEGIN PUBLIC KEY-----"; const pemFooter = "-----END PUBLIC KEY-----"; const pemContents = publicKeyPem .replace(pemHeader, "") .replace(pemFooter, "") .trim(); const binaryDerString = atob(pemContents); const binaryDer = new Uint8Array(binaryDerString.length); for (let i = 0; i < binaryDerString.length; i++) { binaryDer[i] = binaryDerString.charCodeAt(i); } const publicKey = await crypto.subtle.importKey( "spki", binaryDer, { name: "RSA-OAEP", hash: "SHA-256", }, true, ["encrypt"] ); return publicKey; } function arrayBufferToBase64(buffer) { const binary = new Uint8Array(buffer); const base64 = btoa(String.fromCharCode.apply(null, binary)); return base64; }
验证说明
修改Python代码后,使用相同的公钥和明文abcd,两段代码输出的Base64密文将完全一致。
内容的提问来源于stack exchange,提问作者Dreamer
相关产品推荐
相关产品推荐

