如何使用网络加密来导入加密的RSA私钥

时间:2019-12-16 01:12:49

标签: javascript openssl rsa webcrypto-api

有人使用nodejs用以下代码生成了RSA密钥对

export function generateAsymmetric2048KeyPairAsync: (passphrase) {
    const options = {
        modulusLength: 2048,
        publicExponent: 0x10001,
        publicKeyEncoding: {
            type: 'spki',
            format: 'pem'
        },
        privateKeyEncoding: {
            type: 'pkcs8',
            format: 'pem',
            cipher: 'aes-256-cbc',
            passphrase: passphrase
        }
    };

    const generateKeyPairAsync = promisify(generateKeyPair);
    return generateKeyPairAsync('rsa', options);
}

或者您可以使用以下openssl命令生成相同的密钥对

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private_key.pem -out public_key.pem
openssl pkey -in private_key.pem -out private_key_en.pem -aes256

我的任务是使用Web加密API将它们导入浏览器环境。我可以导入公钥,但是编码的私钥有麻烦。以下代码段是我尝试使用的代码。 iv和salt是算法的参数对象所需的BufferArray,但我不知道为它们分配什么。

  const iv                // assign a 16b array here
  const salt              // assign a 16b array here
  const encodedPPKBuffer  // read the private key here
  const passphrase        // read the passphrase here
  
  const pbkAlgo = {
    name: "PBKDF2",
    salt: salt, 
    iterations: 100000,
    hash: "SHA-256"
  }
  
  const aesAlgo = { 
    name: "AES-CBC", 
    iv: iv, 
    length: 256
  };
  
  const rsaAlgo = {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256",
  };
  
  function getKeyMaterial() {
    const enc = new TextEncoder();
    return window.crypto.subtle.importKey(
      "raw",
      enc.encode(passphrase),
      {name: "PBKDF2"},
      false,
      ["deriveBits", "deriveKey"]
    );
  }
  
  async function getUnwrappingKey() {
    const keyMaterial = await getKeyMaterial();
    return window.crypto.subtle.deriveKey(
      pbkAlgo,
      keyMaterial,
      aesAlgo,
      true,
      [ "wrapKey", "unwrapKey" ]
    );
  }
  
  async function unwrapPrivateKey(wrappedKey) {
    const unwrappingKey = await getUnwrappingKey();

    const ppk = await window.crypto.subtle.unwrapKey(
      "pkcs8",               // import format
      encodedPPKBuffer,      // ArrayBuffer representing key to unwrap
      unwrappingKey,         // CryptoKey representing key encryption key
      aesAlgo,               // algorithm params for key encryption key
      rsaAlgo,         
      true,                  // extractability of key to unwrap
      ["decrypt"]     // key usages for key to unwrap
    );
    return ppk;
  }

当我遵循网络加密api文档解开“ pkcs8”密钥时:https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/unwrapKey 它指定在加密密钥时我们必须将原始盐和IV匹配。我怀疑这是问题所在。我不知道原来的盐和IV是什么。有人可以帮我弄这个吗?谢谢。

0 个答案:

没有答案