• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

242
Vistas
Crypto.sign() function to sign a message with given private key

I need to sign a message with crypto.sign() function in NodeJS to get a valid JWT. I have a private key (base 64) like this:

Dm2xriMD6riJagld4WCA6zWqtuWh40UzT/ZKO0pZgtHATOt0pGw90jG8BQHCE3EOjiCkFR2/gaW6JWi+3nZp8A==

And I tried to get a signature:

const getJWT = () => {
  const privateKey =
    "Dm2xriMD6riJagld4WCA6zWqtuWh40UzT/ZKO0pZgtHATOt0pGw90jG8BQHCE3EOjiCkFR2/gaW6JWi+3nZp8A==";
  const payload = {
    iss: "test",
    aud: "test.com",
    iat: 1650101178,
    exp: 1650101278,
    sub: "12345678-1234-1234-1234-123456789123"
  };
  const token = encode(payload, privateKey);
  return token
};

const encode = (payload, key) => {
  const header = {
    typ: "JWT",
    alg: "EdDSA"
  };
  const headerBase64URL = base64url(JSON.stringify(header));
  const payloadBase64URL = base64url(JSON.stringify(payload));
  const msg = Buffer.from(`${headerBase64URL}.${payloadBase64URL}`);
  const keyDecoded = Buffer.from(key, "base64");
  const signature = crypto.sign("Ed25519", msg, keyDecoded); //Here is the problem
  const signatureBase64url = base64url(Buffer.from(signature));
  return `${msg}.${signatureBase64url}`;
};

I received this error:

internal/crypto/sig.js:142
  return _signOneShot(keyData, keyFormat, keyType, keyPassphrase, data,
         ^

Error: error:0909006C:PEM routines:get_name:no start line

  library: 'PEM routines',
  function: 'get_name',
  reason: 'no start line',
  code: 'ERR_OSSL_PEM_NO_START_LINE'

How can I adapt my private key to a valid format?

about 3 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

The crypto.sign() method requires for Ed25519 a private key in PKCS#8 format. Your key is a raw key consisting of the concatenation of the raw private 32 bytes key and the raw public 32 bytes, base64 encoded. A DER encoded PKCS#8 key can be derived and imported as follows:

  • Base64 decode your key. Use the first 32 bytes of your raw 64 bytes key (i.e. the raw private key).
  • Concat the following prefix for a private Ed25519 key (hex): 302e020100300506032b657004220420
  • Import that DER encoded PKCS#8 key.

Accordingly, the key import in getJWT() must be changed as follows:

const privateKey = toPkcs8der('Dm2xriMD6riJagld4WCA6zWqtuWh40UzT/ZKO0pZgtHATOt0pGw90jG8BQHCE3EOjiCkFR2/gaW6JWi+3nZp8A==');

with

const toPkcs8der = (rawB64) => {
    var rawPrivate = Buffer.from(rawB64, 'base64').subarray(0, 32);
    var prefixPrivateEd25519 = Buffer.from('302e020100300506032b657004220420','hex');
    var der = Buffer.concat([prefixPrivateEd25519, rawPrivate]);
    return crypto.createPrivateKey({key: der, format: "der", type: "pkcs8"})
}

Furthermore, in the encode() function:

  • Remove the line const keyDecoded = Buffer.from(key, "base64")

  • Create the signature with

    const signature = crypto.sign(null, msg, key)
    

    Note that for Ed25519, a null must be passed as first parameter in the sign() call. The algorithm comes from the key.

With these changes, the NodeJS code returns the following JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJ0ZXN0IiwiYXVkIjoidGVzdC5jb20iLCJpYXQiOjE2NTAxMDExNzgsImV4cCI6MTY1MDEwMTI3OCwic3ViIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MTIzIn0.f7WG_02UKljrMeVVOTNNBAGxtLXJUT_8QAnujNhomV18Pn5cU-0lHRgVlmRttOlqI7Iol_fHut3C4AOXxDGnAQ

that matches the expected JWT.

about 3 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda