You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

前端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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:30:04