在 Dart 中使用 Ed25519 算法生成 JWS(json 网络签名)
Generate JWS (json web signature) with Ed25519 algo in Dart
我想用 Ed25519
生成的私钥签署 json 网络签名。然后将这个签名发送到我的后端,并使用Node.js中的public密钥进行验证。目前我坚持使用 Dart 创建 json 网络签名。
privateKey
是 base58 编码的,所以我首先将它解码为整数列表,如下所示:
String generateJwt(String subject, String secret) {
var decodedRaw = Base58Decode(secret);
print(decodedRaw);
/* [208, 105, 206, 135, 43, 101, 101, 250, 227,
140, 174, 15, 170, 99, 69, 156, 193, 74, 234,
158, 136, 83, 124, 133, 190, 248, 205, 196,
217, 126, 164, 196] */
final payload = {"id": subject};
}
现在我想使用有效载荷作为 JWS 的有效载荷,并通过我的 Ed25519
解码的私钥保护 header。
这是在 Node.js:
中使用 jose 创建的 jwt 的格式
{
payload: { subject: 'uuid', exp: 1627901626 },
protectedHeader: { alg: 'EdDSA' }
}
我的目标是使用 Dart 在本地设备上创建一个相同格式的 JWS。
编辑:
我现在找到了包 dart_jsonwebtoken,它可以使用 Ed25519 曲线算法签署 json 网络令牌。
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:fast_base58/fast_base58.dart';
generateJwt(String subject, String secret) {
final decodedRaw = Base58Decode(secret);
// Create a json web token
final jwt = JWT(
{
'subject': subject,
},
issuer: subject,
);
final key = EdDSAPrivateKey(decodedRaw);
final token = jwt.sign(key, algorithm: JWTAlgorithm.EdDSA);
print('Signed token: $token\n');
}
但我现在得到错误:ed25519: bad privateKey length 32
。这显然表明我的 privateKey 大小错误。 Repo 声明 PrivateKeySize
是 64 字节,但是有没有办法只使用大小为 32 的私钥,因为通过 Ed25519
生成的我的密钥的大小始终为 32
/// PublicKeySize is the size, in bytes, of public keys as used in this package.
const PublicKeySize = 32;
/// PrivateKeySize is the size, in bytes, of private keys as used in this package.
const PrivateKeySize = 64;
所需的 64 字节密钥是通过连接私有密钥和 public 密钥生成的:
发布的私钥是十六进制编码的:
d069ce872b6565fae38cae0faa63459cc14aea9e88537c85bef8cdc4d97ea4c4
对应的public键没有贴出来,但可以计算为(十六进制编码):
5067025e39f7628f60c91c178287b28446b34a752579e709dcb1ad1ac8dc6401
因此所需的 64 字节密钥是(十六进制编码):
d069ce872b6565fae38cae0faa63459cc14aea9e88537c85bef8cdc4d97ea4c45067025e39f7628f60c91c178287b28446b34a752579e709dcb1ad1ac8dc6401
或Base58编码:
5AgHMMkzfDxdAHHHmpqjQYLqaKnrXTddWGpMQW8Dsj4391Fm7G79ZutmKwZousSvUWbYsf1W8Q12RAMFjXjDcDs6
生成的可能的 JWT:
generateJwt('the subject', '5AgHMMkzfDxdAHHHmpqjQYLqaKnrXTddWGpMQW8Dsj4391Fm7G79ZutmKwZousSvUWbYsf1W8Q12RAMFjXjDcDs6');
是:
eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoidGhlIHN1YmplY3QiLCJpYXQiOjE2MjgwMTkyNDIsImlzcyI6InRoZSBzdWJqZWN0In0.17gFglAs7g8ztBTDsfIx7B6l1GFkbI96xezX6g53lEvoy9HfNqT1wc8MApa8uA1muLDU4MWiwgmpwO51beZDBw
一个简单的测试就是验证消息:
eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoidGhlIHN1YmplY3QiLCJpYXQiOjE2MjgwMTkyNDIsImlzcyI6InRoZSBzdWJqZWN0In0
签名:
17gFglAs7g8ztBTDsfIx7B6l1GFkbI96xezX6g53lEvoy9HfNqT1wc8MApa8uA1muLDU4MWiwgmpwO51beZDBw
使用 Ed25515 和第二个独立程序。我能够使用 C#/BouncyCastle 成功验证这一点。
我想用 Ed25519
生成的私钥签署 json 网络签名。然后将这个签名发送到我的后端,并使用Node.js中的public密钥进行验证。目前我坚持使用 Dart 创建 json 网络签名。
privateKey
是 base58 编码的,所以我首先将它解码为整数列表,如下所示:
String generateJwt(String subject, String secret) {
var decodedRaw = Base58Decode(secret);
print(decodedRaw);
/* [208, 105, 206, 135, 43, 101, 101, 250, 227,
140, 174, 15, 170, 99, 69, 156, 193, 74, 234,
158, 136, 83, 124, 133, 190, 248, 205, 196,
217, 126, 164, 196] */
final payload = {"id": subject};
}
现在我想使用有效载荷作为 JWS 的有效载荷,并通过我的 Ed25519
解码的私钥保护 header。
这是在 Node.js:
{
payload: { subject: 'uuid', exp: 1627901626 },
protectedHeader: { alg: 'EdDSA' }
}
我的目标是使用 Dart 在本地设备上创建一个相同格式的 JWS。
编辑:
我现在找到了包 dart_jsonwebtoken,它可以使用 Ed25519 曲线算法签署 json 网络令牌。
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:fast_base58/fast_base58.dart';
generateJwt(String subject, String secret) {
final decodedRaw = Base58Decode(secret);
// Create a json web token
final jwt = JWT(
{
'subject': subject,
},
issuer: subject,
);
final key = EdDSAPrivateKey(decodedRaw);
final token = jwt.sign(key, algorithm: JWTAlgorithm.EdDSA);
print('Signed token: $token\n');
}
但我现在得到错误:ed25519: bad privateKey length 32
。这显然表明我的 privateKey 大小错误。 Repo 声明 PrivateKeySize
是 64 字节,但是有没有办法只使用大小为 32 的私钥,因为通过 Ed25519
生成的我的密钥的大小始终为 32
/// PublicKeySize is the size, in bytes, of public keys as used in this package.
const PublicKeySize = 32;
/// PrivateKeySize is the size, in bytes, of private keys as used in this package.
const PrivateKeySize = 64;
所需的 64 字节密钥是通过连接私有密钥和 public 密钥生成的:
发布的私钥是十六进制编码的:
d069ce872b6565fae38cae0faa63459cc14aea9e88537c85bef8cdc4d97ea4c4
对应的public键没有贴出来,但可以计算为(十六进制编码):
5067025e39f7628f60c91c178287b28446b34a752579e709dcb1ad1ac8dc6401
因此所需的 64 字节密钥是(十六进制编码):
d069ce872b6565fae38cae0faa63459cc14aea9e88537c85bef8cdc4d97ea4c45067025e39f7628f60c91c178287b28446b34a752579e709dcb1ad1ac8dc6401
或Base58编码:
5AgHMMkzfDxdAHHHmpqjQYLqaKnrXTddWGpMQW8Dsj4391Fm7G79ZutmKwZousSvUWbYsf1W8Q12RAMFjXjDcDs6
生成的可能的 JWT:
generateJwt('the subject', '5AgHMMkzfDxdAHHHmpqjQYLqaKnrXTddWGpMQW8Dsj4391Fm7G79ZutmKwZousSvUWbYsf1W8Q12RAMFjXjDcDs6');
是:
eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoidGhlIHN1YmplY3QiLCJpYXQiOjE2MjgwMTkyNDIsImlzcyI6InRoZSBzdWJqZWN0In0.17gFglAs7g8ztBTDsfIx7B6l1GFkbI96xezX6g53lEvoy9HfNqT1wc8MApa8uA1muLDU4MWiwgmpwO51beZDBw
一个简单的测试就是验证消息:
eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoidGhlIHN1YmplY3QiLCJpYXQiOjE2MjgwMTkyNDIsImlzcyI6InRoZSBzdWJqZWN0In0
签名:
17gFglAs7g8ztBTDsfIx7B6l1GFkbI96xezX6g53lEvoy9HfNqT1wc8MApa8uA1muLDU4MWiwgmpwO51beZDBw
使用 Ed25515 和第二个独立程序。我能够使用 C#/BouncyCastle 成功验证这一点。