JavaScript,Crypto.subtle:如何导入RSA私钥



i使用python a rsa键对生成,我想在javascript中导入它。我成功地导入了公共密钥,但我正在挣扎着私钥进口。

python:

from Cryptodome.PublicKey import RSA
key = RSA.generate(1024)
private_key = key.export_key().decode("ascii")
public_key = key.publickey().export_key().decode("ascii")

javaScript:

function str2ab(str) {
  const buf = new ArrayBuffer(str.length);
  const bufView = new Uint8Array(buf);
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}
async function importRsaPublicKey(pem) {
  // fetch the part of the PEM string between header and footer
  const pemHeader = "-----BEGIN PUBLIC KEY-----";
  const pemFooter = "-----END PUBLIC KEY-----";
  const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length);
  // base64 decode the string to get the binary data
  const binaryDerString = window.atob(pemContents);
  // convert from a binary string to an ArrayBuffer
  const binaryDer = str2ab(binaryDerString);
  return await window.crypto.subtle.importKey(
    "spki",
    binaryDer,
    {
      name: "RSA-OAEP",
      hash: "SHA-256"
    },
    true,
    ["encrypt"]
  );
}
async function importRsaPrivateKey(pem) {
  // Same logic as previous
  const pemHeader = "-----BEGIN RSA PRIVATE KEY-----";
  const pemFooter = "-----END RSA PRIVATE KEY-----";
  const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length);
    
  const binaryDerString = window.atob(pemContents);
  const binaryDer = str2ab(binaryDerString);
  return await window.crypto.subtle.importKey(
      "spki",
        binaryDer,
        {
          name: "RSA-OAEP",
          hash: "SHA-256"
         },
        true,
        ["decrypt"]
        );
    );
}

当我尝试导入这样的私钥时:

var pem = "-----BEGIN RSA PRIVATE KEY-----MIICWwIBAAKBgQC1rayx8fyYUbyV5h/HtkIq3TBw5CZY8qKL4Kx5+gCLJj4ZklZ+6J6HU+OLGclLVoE7fwLPIJTRIG47kRG7eUG4rfmkXQJx4gOyBjOpfnE5GRDlXzUcymk5XOh87N1o0PGsfYm844PYZaU2MWiyvob717LlEELO4l7nxc11/oucTQIDAQABAoGARGd5W+CMZj90PY5RTe0qOaBhgkfsxlXI7NixqBWAyeOiwxcNuSfVtIdZ58BUQaj27JNUV+9hCOJojsX+wrMTkpaD1bmDEFibxuHOCuZQ/DszTmPNwx5INcR7wKhibbJA4rtzoHt2B8G/6mc0O+bJz6p0C4IJULTmiTvhuQULesMCQQDTZ/2zzO5sv4Z2Y2GD3RAoF+MhoYyR3Rt/36LsAmAWVQz12UIhqd0VzljEKNDUIFNHRU5GTcGSPvrBSNZbfTYPAkEA3ABfQ54KKoVQEcHNG6OI4QrA8PaQfCfVq1hMnbLoxJYRB9Fjfbs38uljJ6j6CqtQMfrrE7ZplpOXcW6FeXWD4wJAE0VJdRhbK4KR6TzJ6NE/5ce3ppspSyqSlSd3nHfi9mYuVkLFqnfndVNn+AmYb526uaZxqirwWDpxdSkEkTZqtQJAGU3ppytcW/utc/1ojA9JRSkpfA3AHKewSd8EIPddEo94MgABg4qvKr9xajRjXirKNJV5yHCowGsFdkSSEaBUpQJARQPMkQ7OWrlXLwICP9zUkPVJWkq2LSDZA1Rx3ySgbDD+VjrOo+1wtKmHuGf9QFxbqc50QT58OqrCDRWzq8BExw==-----END RSA PRIVATE KEY-----";
var private_key = await importRsaPrivateKey(pem);

我有以下错误:

语法错误

无法使用指定的密钥用法创建密钥。

您知道如何纠正此问题吗?

编辑:

我需要将密钥导出为PKCS8:

python:

from Cryptodome.PublicKey import RSA
key = RSA.generate(1024)
private_key = key.export_key(pkcs=8).decode("ascii")
public_key = key.publickey(pkcs=8).export_key().decode("ascii")

并将键导入为pkcs8 not spki

javacript:

async function importRsaPrivateKey(pem) {
  const pemHeader = "-----BEGIN PRIVATE KEY-----";
  const pemFooter = "-----END PRIVATE KEY-----";
  const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length);
  const binaryDerString = window.atob(pemContents);
  const binaryDer = str2ab(binaryDerString);
  return await window.crypto.subtle.importKey(
    "pkcs8",
    binaryDer,
    {
      name: "RSA-OAEP",
      hash: "SHA-256"
    },
    true,
    ["decrypt"]
    );
}

spki用于导入公共密钥。将其更改为pkcs8

fyi,键中的标题, -----BEGIN PRIVATE KEY-----表示您的密钥在PKCS#8格式中。这就是关键WebCrypto的形式。

如果您患有-----BEGIN RSA PRIVATE KEY-----,那将意味着您的密钥以PKCS#1格式序列化。在调用ImportKey((之前,您需要将其转换为PKCS#8。查看如何以PEM格式导入RSA专用密钥,以供WebCrypto使用?

最新更新