Reputation: 187
I generated using python a RSA key pair and I want to import it in javascript. I successfully import the public key but I'm struggling with the private key importation.
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"]
);
);
}
When I try to import the private key like this :
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);
I got the following error :
Syntax error
Cannot create a key using the specified key usages.
Do you know how to correct this ?
EDIT :
I need to export the key as 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")
and to import the key as 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"]
);
}
Upvotes: 1
Views: 5315
Reputation: 39289
spki
is used to import public keys. Change it to pkcs8
FYI, the header in your key, -----BEGIN PRIVATE KEY-----
means that your key is in PKCS #8 format. That is the form of key webcrypto can import.
If you had -----BEGIN RSA PRIVATE KEY-----
, that would mean your key was serialized in PKCS#1 format. And before calling importKey(), you would need to convert it to PKCS#8. See How can I import an RSA private key in PEM format for use with WebCrypto?
Upvotes: 8