微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Ed25519 KeyPair 签署和验证 JWSjson 网络签名

如何解决使用 Ed25519 KeyPair 签署和验证 JWSjson 网络签名

我想使用通过 Ed25519 在客户端设备上生成的私钥对 JWS(json 网络签名)进行签名。然后将此签名发送到我的后端并使用公钥进行验证。 为了熟悉该过程,我想尝试在节点 js 中签署和验证 JWS。
我的私钥和公钥都已经生成并且在 base58 中可用。这是我目前使用 Ed25519 私钥签署 JWT 的尝试:

const { SignJWT } = require("jose/jwt/sign");
const bs50 = require("bs58");

async function main() {
  const publicbase58 = "A77GCUCZ7FAuXVMKtwwXyFhMa158XsaoGKHYNnJ1q3pv";
  const privateKeybase58 = "BE1VM7rTRJReLsTLLG4JMNX5ozcp7qpmMuRht9zB1UjU";

  const publicKeyBuffer = bs50.decode(publicbase58);
  const privateKeyBuffer = bs50.decode(privateKeybase58);

  const publicKey = new Uint8Array(publicKeyBuffer);
  const privateKey = new Uint8Array(privateKeyBuffer);

  const jwt = await new SignJWT({
    subject: "uuid",})
    .setProtectedHeader({ alg: "EdDSA" })
    .setExpirationTime("2h")
    .sign(privateKey);

  console.log(jwt);
}

错误:类型错误:密钥必须是 KeyObject 或 CryptoKey 类型之一。接收到一个 Uint8Array 实例

当尝试使用 sign() 函数时,我收到上述错误,因为我的私钥是 Uint8Array 类型,唯一接受的类型是 KeyObjectCryptoKey 但我不不知道如何将 Uint8Arrays 转换为 KeyObjectsCryptoKeys

我从这个 answer 中得到了一些代码片段

解决方法

您需要采用 Node.js 可识别的格式的密钥。 KeyObject create*Key API 识别并支持该密钥 - 对于 Ed25519 密钥,即假设 Node.js >= 16.0.0:

  • SPKI 中的 PEM/DER 公钥
  • PKCS8 中的 PEM/DER 用于私钥
  • 公钥和私钥的 JWK

这是一个使用 DER 的片段。

import { SignJWT } from "jose/jwt/sign"
import { jwtVerify } from "jose/jwt/verify"
import bs58 from "bs58"
import { createPrivateKey,createPublicKey } from "crypto"

(async function main() {
  const publicBase58 = "A77GCUCZ7FAuXVMKtwwXyFhMa158XsaoGKHYNnJ1q3pv";
  const privateKeyBase58 = "BE1VM7rTRJReLsTLLG4JMNX5ozcp7qpmMuRht9zB1UjU";

  let publicKey = bs58.decode(publicBase58);
  let privateKey = bs58.decode(privateKeyBase58);

  publicKey = createPublicKey({
    key: Buffer.concat([Buffer.from("302a300506032b6570032100","hex"),publicKey]),format: "der",type: "spki",});

  privateKey = createPrivateKey({
    key: Buffer.concat([
      Buffer.from("302e020100300506032b657004220420",privateKey,]),type: "pkcs8",})

  const jwt = await new SignJWT({
    subject: "uuid",})
    .setProtectedHeader({ alg: "EdDSA" })
    .setExpirationTime("2h")
    .sign(privateKey);

  console.log(await jwtVerify(jwt,publicKey))
})()

这是使用 JWK 的一个。

import { SignJWT } from "jose/jwt/sign"
import { jwtVerify } from "jose/jwt/verify"
import bs58 from "bs58"
import { createPrivateKey,createPublicKey } from "crypto"

(async function main() {
  const publicBase58 = "A77GCUCZ7FAuXVMKtwwXyFhMa158XsaoGKHYNnJ1q3pv";
  const privateKeyBase58 = "BE1VM7rTRJReLsTLLG4JMNX5ozcp7qpmMuRht9zB1UjU";

  let publicKey = bs58.decode(publicBase58);
  let privateKey = bs58.decode(privateKeyBase58);

  publicKey = createPublicKey({
    key: {
      kty: "OKP",crv: "Ed25519",x: publicKey.toString("base64url")
    },format: "jwk"
  });

  privateKey = createPrivateKey({
    key: {
      kty: "OKP",x: publicKey.toString("base64url"),d: privateKey.toString("base64url"),},format: "jwk"
  })

  const jwt = await new SignJWT({
    subject: "uuid",publicKey))
})()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?