Comments (2)
Ok I could make it work thanks to @engelke articles 1 and 2.
Using the live parsing tool of asn1js I could figure out how to reach field containing the binary key.
Once I had obtained the bytes of the public key field, I had to split them to obtain the two values for x and y. The first byte of ECDSA binary key contains the compression info (x04
for uncompressed), followed by x
and y
.
The number of bytes obtained was 97, which makes sense: 97 == 1 + 48 + 48
, and 48 bytes is 384 bits (ECDSA P-384).
const content = publicKey.bits.bytes.slice(1);
const length = content.length;
if (length * 8 != 384 * 2) {
throw new Error(`Invalid key size (${length * 8} bits)`)
}
publicKey.x = content.slice(0, length/2);
publicKey.y = content.slice(length/2);
But the jwk
expects the x
and y
to be «base64url» encoded:
function binaryToBase64URL(int8Array) {
return window.btoa(String.fromCharCode.apply(null, int8Array))
.replace(/\+/g, '-').replace(/\//g, '_') // URL friendly
.replace(/\=+$/, ''); // No padding.
}
As a summary, I could get the PEM to be loaded with:
function loadKey(pemChain) {
const stripped = pemChain.split("\n").slice(1, -2).join("");
const der = base64ToBinary(stripped);
var certificate = parseX509ECDSACertificate(der); // x509ecdsa.js
const jwk = {
kty: "EC",
crv: "P-384",
x: binaryToBase64URL(certificate.publicKey.x),
y: binaryToBase64URL(certificate.publicKey.y),
ext: true,
}
const usages = ["verify"]; //"verify" for public key import, "sign" for private key imports
return window.crypto.subtle.importKey("jwk", jwk, {
name: "ECDSA",
namedCurve: "P-384"
},
false, //whether the key is extractable (i.e. can be used in exportKey),
usages
);
}
The parseX509ECDSACertificate()
function can be found in this pull-request elsewhere.
The key is now loaded properly. I now have some failing verification, but that's another story ;)
(I'm closing this, feel free to re-open of ping me if you think this is worth adding to the documentation somewhere)
Thanks @jvehent also for your support!
from webcrypto-examples.
@ttaubert and @mozmark confirmed that loading ECDSA from spki
is not supported.
We should use the jwk
instead.
That means we should parse the chain with an ASN.1 library, extract the x
and y
coordinates from the result and provide them as a an object:
const stripped = pemChain.split("\n").slice(1, -2).join("");
const binaryKey = base64ToBinary(stripped);
const asn1 = org.pkijs.fromBER(binaryKey.buffer);
console.log(asn1.result);
const coordX = ?
const coordY = ?
const jwk = {
kty: "EC",
crv: "P-384",
x: coordX,
y: coordY
}
const usages = ["verify"]; //"verify" for public key import, "sign" for private key imports
return window.crypto.subtle.importKey("jwk", jwk, {
name: "ECDSA",
namedCurve: "P-384"
},
false, //whether the key is extractable (i.e. can be used in exportKey),
usages
);
I didn't figure out how to parse and extract the x and y values yet. Plus I'm afraid to be lost between the different expected types/encoding (base64, buffer, UintArray, hex...) :]
edit: example in Go : https://play.golang.org/p/v9GKNxAuKj
from webcrypto-examples.
Related Issues (20)
- How to import base64 encoded key? HOT 1
- RSA-OAEP wrapKey/unwrapKey HOT 1
- Describe each encryption a litle bit HOT 1
- Deterministic generation of key pair from seed HOT 2
- How to recover public key with ECDSA?
- Source of Recommended/Discouraged algorithms HOT 3
- verbose mode
- Just thank you
- importKey RSA-OAEP with SHA-1 not working on safari 11
- HKDF-CTR replaced by HKDF
- how to use the ECDH or DH keys in transing?
- window.crypto.subtle.importKey not working for me when i hosted my web app on Server (IIS or NodeJs)
- ECDH deriveKey example should use HKDF
- Why are RSA APIs marked as "not recommended"?
- How to encrypt using RSA-OAEP for multiple recipient? HOT 1
- Unable to encrypt the bulk data in webcrypto
- Low rounds of PBKDF2
- False negative for PBKDF2+deriveKey
- Use key pair to encrypt / decrypt and sign / verify?
- Issue in decryption crypto.subtle encrypted text using RSACryptoServiceProvider
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from webcrypto-examples.