Webcrypto API - How to provide array buffers ( signature and public key ) as strings?

464 Views Asked by At

I'm using the Webcrypto API to sign data and now have the public key and signature both of type ArrayBuffer. Both information should be stored into separate files, so

  • the public key should be stored as a string into a "public_key" file
  • the signature should be stored as a string into a "signature" file

I'm new to this and don't know the "easiest" file formats so other languages/packages ( e.g. Java backends ) can deal with the files.

For the public key the SPKI format as a PEM string looks fine? But I don't know an approach for the signature. I started with the following

( Playground link )

const generateKeyPair = async function() {
    return crypto.subtle.generateKey(
        {
            name: "ECDSA",
            namedCurve: "P-384",
        },
        true,
        ["sign", "verify"]
    );
};

const sign = async function(privateKey: CryptoKey, buffer: BufferSource) {
    return crypto.subtle.sign({
      name: privateKey.algorithm.name,
      hash: 'SHA-512'
    }, privateKey, buffer);
};

const exportKeyAsSPKI = async function(cryptoKey: CryptoKey) {
    return crypto.subtle.exportKey("spki", cryptoKey)
};

const spkiToPEM = function(buffer: ArrayBuffer) {
    const asString = String.fromCharCode.apply(null, new Uint8Array(buffer));
    const asBase64 = btoa(asString);
    
    return `-----BEGIN PUBLIC KEY-----\n${asBase64}\n-----END PUBLIC KEY-----`;
};

(async () => {
    // Generate keys 
    
    const { privateKey, publicKey } = await generateKeyPair();

    // Sign data

    const data = { foo: 'bar' };
    const stringifiedData = JSON.stringify(data);
    const buffer = new TextEncoder().encode(stringifiedData);
    
    const signature = await sign(privateKey, buffer);

    // Convert public key to string to store into file

    const publicKeyAsSPKIFormat = await exportKeyAsSPKI(publicKey);
    const pemEncodedKey = spkiToPEM(publicKeyAsSPKIFormat);

    // Convert signature to string to store into file

    // ... TODO ...

    // DONE

    console.log("Public key:");
    console.log(pemEncodedKey);

    console.log("Signature:");
    console.log("todo...");
})();

What is the approach for the signature? Are there any better approaches for the public key?

0

There are 0 best solutions below