使用 RSA 在 JS 中加密消息并在 Python 中解密

Posted

技术标签:

【中文标题】使用 RSA 在 JS 中加密消息并在 Python 中解密【英文标题】:Using RSA to encrypt a message in JS and decrypt in Python 【发布时间】:2021-12-28 12:59:26 【问题描述】:

我想使用 RSA 和 javascript 中提供的 PEM 公钥加密消息,使用 SubtleCrypto window.crypto.subtle,然后在后端使用 Python (PyCryptodome) 对其进行解码。但是,我得到了ValueError: Incorrect decryption.。我不确定数据是否得到正确处理。这是我的代码:

JavaScript:

var publicKey;
var pemPublicKey = `public.pem key with stripped header and footer and newlines (just the base64 data)`;

function base64ToArrayBuffer(b64) 
    var byteString = window.atob(b64);
    var byteArray = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++)  byteArray[i] = byteString.charCodeAt(i); 
    return byteArray;


function arrayBufferToBase64(buffer) 
    var binary = '';
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++)  binary += String.fromCharCode(bytes[i]); 
    return window.btoa(binary);


window.crypto.subtle.importKey(
    "spki",
    base64ToArrayBuffer(pemPublicKey),
     name: "RSA-OAEP", hash:  name: "SHA-256"  ,
    false,
    ["encrypt"])
    .then(function (key) 
        publicKey = key
    )

console.log(publicKey)

var enc = new TextEncoder()
var encmessage = enc.encode("test14")

var encryptedData;
window.crypto.subtle.encrypt(
    name: "RSA-OAEP"
, publicKey, encmessage).then(function (encrypted)  encryptedData = encrypted )

var encodedData = arrayBufferToBase64(encryptedData);
console.log(encodedData)

上面的代码所做的是转换公共 PEM 密钥,从中生成一个 CryptoKey 对象(使用 crypto.subtle.importKey),然后加密一个简单的消息“test14”。

Python 后端:

import base64
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import AES, PKCS1_OAEP

with open('private.pem', 'r') as f: keypair = RSA.import_key(f.read())
decryptor = PKCS1_OAEP.new(keypair)
decrypted = decryptor.decrypt(base64.b64decode(encrypted))  # encrypted is the data that is returned by JavaScript code
print(decrypted)

【问题讨论】:

【参考方案1】:

直接来自Crypto.Cipher.PKCS1_OAEP.new(key, hashAlgo=None, mgfunc=None, label='', randfunc=None)的文档:

...

hashAlgo(散列对象)- 要使用的散列函数。这可以是 Crypto.Hash 下的模块或从任何此类模块创建的现有哈希对象。如果未指定,则使用 Crypto.Hash.SHA1。

...

【讨论】:

出于某种原因,我认为 SHA-256 是默认值。在 Javascript 代码中更改为 SHA-1 修复了它,谢谢! SHA-1 是 PKCS#1 v2.x 标准中的(有点不幸)默认值。这种类型的函数是安全的,但 SHA-256 会是更好的选择。 我的一般建议是永远不要使用默认值总是定义它,尤其是在加密实现中。

以上是关于使用 RSA 在 JS 中加密消息并在 Python 中解密的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 和 webcrypto 之间的 RSA 加密

在 iOS 上加密和在 Node.js 上使用 RAW RSA 解密时遇到问题

Python中的RSA加密和解密

如何在python中加密和解密消息RSA?

Nodejs 使用node-rsa 加密数据

Nodejs 使用node-rsa 加密数据