Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Converts a secp256k1 public key as returned by https://docs.tangany.com/#f95ba7a2-5526-4eef-b0da-7d7a13be34d2 to OpenSSL PEM format
/**
* Converts a secp256k1 public key as returned by `GET https://api.tangany.com/v1/wallet/:wallet` to OpenSSL PEM format
* @param {string} publicKey - hexadecimal key to convert
* @return PEM-formatted representation of given public key
* @example
* const pem = convertPublicKeyToPEM("04f500418025ba3babca935e9f7617c438210ab72ae3ece0b25e5dff579c31ddd1549ab1ee4f0dcb53e51aacceb15147af6f4a1610040aa8e042a0f3e208496257");
*/
function convertPublicKeyToPEM (publicKey) {
let key = Buffer.from(publicKey, "hex");
if (key.length !== 65) {
throw new Error("Invalid public key length");
}
// Uncompressed key with 0x04 prefix, following x and y
key = key.slice(1);
// DER prefix; this is SEQUENCE { SEQUENCE { OID 1.2.840.10045.2.1 (ecPublicKey), OID 1.3.132.0.10 (secp256k1) }, BIT STRING prefix.
const header = Buffer.from([0x30, 0x56, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x0A, 0x03, 0x42, 0x00, 0x04]);
const pemKey = Buffer.concat([header, key]);
// Insert line breaks after 64 characters (https://tools.ietf.org/html/rfc1421#section-4.3.2.4)
const pemStr = pemKey.toString("base64").replace(/(.{64})/g, "$1\n");
let result = "-----BEGIN PUBLIC KEY-----\n";
result += pemStr + "\n";
result += "-----END PUBLIC KEY-----\n";
return result;
}
const pk = "04f500418025ba3babca935e9f7617c438210ab72ae3ece0b25e5dff579c31ddd1549ab1ee4f0dcb53e51aacceb15147af6f4a1610040aa8e042a0f3e208496257";
console.log(convertPublicKeyToPEM(pk));
/*
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE9QBBgCW6O6vKk16fdhfEOCEKtyrj7OCy
Xl3/V5wx3dFUmrHuTw3LU+UarM6xUUevb0oWEAQKqOBCoPPiCEliVw==
-----END PUBLIC KEY-----
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment