Как использовать веб-шифрование для импорта зашифрованного закрытого ключа RSA

Кто-то сгенерировал пару ключей RSA со следующим кодом, используя nodejs

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 Crypto 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;
  }

Когда я следил за документом web crypto api для разворачивания ключа "pkcs8": https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/unwrapKey Он указывает, что мы должны соответствовать исходной соли и IV при шифровании ключа. Я подозреваю, что это проблема. Я не знаю, что такое оригинальная соль и капельница. Может кто-то помочь мне с этим? Спасибо.

0 ответов

Другие вопросы по тегам