GithubHelp home page GithubHelp logo

Comments (2)

leplatrem avatar leplatrem commented on August 20, 2024 1

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.

leplatrem avatar leplatrem commented on August 20, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.