使用 RSA 在 JS 中加密消息并在 Python 中解密
Using RSA to encrypt a message in JS and decrypt in Python
我想使用 RSA 和 Javascript 中提供的 PEM public 密钥加密消息,使用 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)
上面的代码所做的是转换 public 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)
直接来自 Crypto.Cipher.PKCS1_OAEP.new(key, hashAlgo=None, mgfunc=None, label='', randfunc=None)
的文档:
...
hashAlgo
(hash object) - The hash function to use. This can be a module under Crypto.Hash or an existing hash object created from any of such modules. If not specified, Crypto.Hash.SHA1 is used.
...
我想使用 RSA 和 Javascript 中提供的 PEM public 密钥加密消息,使用 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)
上面的代码所做的是转换 public 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)
直接来自 Crypto.Cipher.PKCS1_OAEP.new(key, hashAlgo=None, mgfunc=None, label='', randfunc=None)
的文档:
...
hashAlgo
(hash object) - The hash function to use. This can be a module under Crypto.Hash or an existing hash object created from any of such modules. If not specified, Crypto.Hash.SHA1 is used....