我想创建一个执行以下操作的应用程序:
我能够完成前两个步骤。我实现了不同的函数来让解密在前端工作,但所有这些都导致了臭名昭著的
OperationError: The operation failed for an operation-specific reason
错误。
两个工作函数比较简单,前端密钥对生成函数如下:
async function generateKeyPair() {
const keyPair = await window.crypto.subtle.generateKey(
{
name: 'RSA-OAEP',
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: { name: 'SHA-256' }
},
true,
['encrypt', 'decrypt']
);
const publicKey = await window.crypto.subtle.exportKey('jwk', keyPair.publicKey);
const privateKey = await window.crypto.subtle.exportKey('jwk', keyPair.privateKey);
return {
publicKey: window.btoa(JSON.stringify(publicKey)),
privateKey: window.btoa(JSON.stringify(privateKey))
};
}
后端功能使用
crypto
模块中的 WebCrypto API:
import { webcrypto } from "crypto";
async function encryptWithPublicKey(publicKey, plainText) {
const publicKeyJwk = JSON.parse(Buffer.from(publicKey, 'base64').toString('utf8'));
const key = await webcrypto.subtle.importKey(
'jwk',
publicKeyJwk,
{
name: 'RSA-OAEP',
hash: { name: 'SHA-256' }
},
true,
['encrypt']
);
const encrypted = await webcrypto.subtle.encrypt(
{
name: 'RSA-OAEP'
},
key,
Buffer.from(plainText)
);
const encryptedArray = new Uint8Array(encrypted);
const encryptedBuffer = Buffer.from(encryptedArray);
const encryptedString = encryptedBuffer.toString('base64');
return encryptedString;
}
我对第 3 步的最新尝试:
async function decryptDataWithPrivateKey(encryptedData, privateKey) {
// takes a base64 string and base64 JWK string and decrypts the data
const data = window.atob(encryptedData);
const key = JSON.parse(window.atob(privateKey));
const keyCrypto = await window.crypto.subtle.importKey(
'jwk',
key,
{
name: 'RSA-OAEP',
hash: { name: 'SHA-256' }
},
true,
['decrypt']
);
const decryptedData = await window.crypto.subtle.decrypt(
{
name: 'RSA-OAEP'
},
keyCrypto,
// data as a BufferSource
new Uint8Array(data.split('').map((char) => char.charCodeAt(0)))
);
return new TextDecoder().decode(decryptedData);
}