crypto.sign()函数以用给定的私钥签署消息

发布于 2025-01-22 14:35:15 字数 1575 浏览 3 评论 0原文

我需要在nodejs中使用crypto.sign()函数签署消息以获取有效的JWT。 我有一个像这样的私钥(基本64):

Dm2xriMD6riJagld4WCA6zWqtuWh40UzT/ZKO0pZgtHATOt0pGw90jG8BQHCE3EOjiCkFR2/gaW6JWi+3nZp8A==

我试图获得一个签名:

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}`;
};

我收到了此错误:

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'

如何使我的私钥适应有效格式?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

离线来电— 2025-01-29 14:35:15

对于ED25519的方法需要PKCS#8格式中的一个私钥。您的密钥是一个原始键,由RAW PRIVATE 32字节密钥和RAW PUBLIC 32字节(BASE64编码)的串联组成。可以派生和导入DER编码的PKCS#8密钥,如下所示:

  • base64解码您的密钥。使用RAW 64字节键的前32个字节(即RAW私钥)。
  • concat私有ED25519密钥(HEX)的以下前缀:302E020100300506032B657004220420
  • 导入该编码的PKCS#8密钥。

因此,必须更改getJwt()中的密钥导入,如下所示:

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

此外

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"})
}

,在encode()函数中,

  • exots

    删除行const kent keydecoded = buffer.from(键,“ base64”)

  • 创建签名

    请注意,对于ED25519,null必须作为sign()调用中的第一个参数传递。该算法来自键。

通过这些更改,Nodejs代码返回以下JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJ0ZXN0IiwiYXVkIjoidGVzdC5jb20iLCJpYXQiOjE2NTAxMDExNzgsImV4cCI6MTY1MDEwMTI3OCwic3ViIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MTIzIn0.f7WG_02UKljrMeVVOTNNBAGxtLXJUT_8QAnujNhomV18Pn5cU-0lHRgVlmRttOlqI7Iol_fHut3C4AOXxDGnAQ

预期JWT

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文