使用 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 加密