我尝试使用Web Crypto生成RSA密钥,并使用它用jsrsasignFirefox does not support RSA-PSS)对字符串进行签名。因此,我导出了Web加密密钥并将其转换为PKCS8-PEM,但是当我调用KEYUTIL.getKeyFromPlainPrivatePKCS8PEM将密钥导入jsrsasign时,将引发错误:格式错误的纯PKCS8私有密钥(代码:001)

我怎么了JSBin

window.crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
    hash: {name: "SHA-256"},
  },
  true,
  ["encrypt", "decrypt"]
)
.then(keyPair => window.crypto.subtle.exportKey("pkcs8", keyPair.privateKey))
.then(arrayBufferToBase64String)
.then(toPem)
.then(pem => {
  var rsa = KEYUTIL.getKeyFromPlainPrivatePKCS8PEM(pem); // throws: malformed plain PKCS8 private key(code:001)
  var sig = rsa.signStringPSS('text', 'sha256', 32);
  console.log('signature', sig);
})
.catch(::console.error)

function arrayBufferToString(arrayBuffer) {
  var byteArray = new Uint8Array(arrayBuffer)
  var byteString = '';
  for (var i=0; i<byteArray.byteLength; i++) {
    byteString += String.fromCharCode(byteArray[i]);
  }
  return byteString;
}

function arrayBufferToBase64String(arrayBuffer) {
  return btoa(arrayBufferToString(arrayBuffer));
}

function toPem(key) {
  return `
-----BEGIN RSA PRIVATE KEY-----
${key}
-----END RSA PRIVATE KEY-----
`;
}


编辑:

我刚刚意识到jsrsasign可以处理jwk:

window.crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
    hash: {name: "SHA-256"},
  },
  true,
  ["encrypt", "decrypt"]
)
.then(keyPair => window.crypto.subtle.exportKey("jwk", keyPair.privateKey))
.then(jwk => {
  var rsa = KEYUTIL.getKey(jwk);
  var sig = rsa.signStringPSS('text', 'sha256', 32);
  console.log('signature', sig);
})
.catch(::console.error)


我更喜欢这种解决方案,但是我仍然想知道为什么我的pkcs8解决方案不起作用。

最佳答案

由于“ RSA”部分,您的PEM编码密钥实际上是PKCS#1,而不是PKCS#8。这只是DER中的RSA密钥对象,而密钥标识符没有包装在序列中。

jsrsasign正在寻找PKCS#8标头“ BEGIN PRIVATE KEY”而不是“ BEGIN RSA PRIVATE KEY”。更改标题可以使其正常工作。

关于javascript - 如何将Web加密 key 导出到jsrsasign,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33739022/

10-11 23:57