如何在 JavaScript 中使用 base64 编码的 JSON Web 密钥解密数据?

问题描述 投票:0回答:0

我想创建一个执行以下操作的应用程序:

  1. 在前端生成JWK RSA-OAEP密钥对,用base64编码
  2. 使用编码的公共 JWK 作为参数在 Node.js(使用 WebCrypto API)中加密字符串。以 base64 格式返回结果。
  3. 使用第一步生成的编码私有JWK,在前端对加密编码后的字符串进行解密

我能够完成前两个步骤。我实现了不同的函数来让解密在前端工作,但所有这些都导致了臭名昭著的

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);
    }
javascript node.js cryptography cryptojs webcrypto-api
© www.soinside.com 2019 - 2024. All rights reserved.