BouncyCastle 实现 Ed25519 算法示例( aardio 版 ):
import console;
import BouncyCastle;
import crypt;
//----------- 生成 Ed25519 密钥对 ------------------
// 初始化 Ed25519 密钥对生成器
var keyPairGen = BouncyCastle.Crypto.Generators.Ed25519KeyPairGenerator();
keyPairGen.Init( BouncyCastle.Crypto.KeyGenerationParameters(BouncyCastle.Security.SecureRandom(), 256) );
// 生成密钥对
var keyPair = keyPairGen.GenerateKeyPair();
var privateKey = keyPair.Private;
var publicKey = keyPair.Public;
//----------- 导入导出 PEM 格式 Key ------------------
// 从 PEM 格式导入公钥或私钥
var importPemKey = function(pem){
var h = string.match(pem,"!\N<@-----BEGIN@>\s+(.+?)<@-----@>");
var bytes = raw.buffer( crypt.decodeBin(pem) );
if(h=="PUBLIC KEY"){
return BouncyCastle.Security.PublicKeyFactory.CreateKey(bytes);
}
elseif(h=="PRIVATE KEY"){
return BouncyCastle.Security.PrivateKeyFactory.CreateKey(bytes);
}
};
// 导出的公钥 PEM
var exportPublicKeyX509 = function(publicKey){
var publicKeyInfo = BouncyCastle.X509.SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
return crypt.pem(publicKeyInfo.GetEncoded(), "PUBLIC KEY");
}
// 导出的私钥 PEM
var exportPrivateKeyPkcs8ToPem = function(privateKey){
var privateKeyInfo = BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
return crypt.pem(privateKeyInfo.GetEncoded(), "PRIVATE KEY");
};
// 导出的私钥 PEM
var privateKeyPem = exportPrivateKeyPkcs8ToPem(privateKey);
console.log(privateKeyPem);
//导出的公钥 PEM
var publicKeyPem = exportPublicKeyX509(publicKey);
console.log(publicKeyPem);
// 从 PEM 导入私钥
var newPrivKey = importPemKey(privateKeyPem);
// 从 PEM 导入公钥
var newPubKey = importPemKey(publicKeyPem);
//----------- 导入导出不带 ASN.1 结构的原始 32 字节 Key (Raw 数据) ------------------
// 公钥 Raw 导出(返回 buffer 类型字节串)
var rawPubKeyBytes = publicKey.GetEncoded(); // Ed25519 原始公钥就是 32 字节
// 私钥 Raw 导出(返回 buffer 类型字节串)
var rawPrivKeyBytes = privateKey.GetEncoded(); // Ed25519 原始私钥也是 32 字节
// 公钥 Raw 导入
var newPubKeyFromRaw = BouncyCastle.Crypto.Parameters.Ed25519PublicKeyParameters(rawPubKeyBytes, 0);
// 私钥 Raw 导入
var newPrivKeyFromRaw = BouncyCastle.Crypto.Parameters.Ed25519PrivateKeyParameters(rawPrivKeyBytes, 0);
console.log("原始公钥长度:", #rawPubKeyBytes);
console.log("原始私钥长度:", #rawPrivKeyBytes);
//----------- 签名验证演示 ------------------
var msg = "测试数据";
var msgBytes = raw.buffer(msg);
// 签名
var signer = BouncyCastle.Crypto.Signers.Ed25519Signer();
signer.Init(true, newPrivKey);
signer.BlockUpdate(msgBytes, 0, #msgBytes);
var signature = signer.GenerateSignature();
// 验证
var verifier = BouncyCastle.Crypto.Signers.Ed25519Signer();
verifier.Init(false, newPubKey);
verifier.BlockUpdate(msgBytes, 0, #msgBytes);
var isMatched = verifier.VerifySignature(signature);
console.status(isMatched,"签名验证结果 (使用导入的密钥)");
console.pause();
JWT 使用 EdDSA(Ed25519) 算法示例:
import console;
import BouncyCastle;
import crypt.jwt.algorithm.EdDSA;
//----------- 生成 Ed25519 密钥对 ------------------
var keyPairGen = BouncyCastle.Crypto.Generators.Ed25519KeyPairGenerator();
keyPairGen.Init(BouncyCastle.Crypto.KeyGenerationParameters(
BouncyCastle.Security.SecureRandom(), 256));
var keyPair = keyPairGen.GenerateKeyPair();
var privateKey = keyPair.Private;
var publicKey = keyPair.Public;
//----------- JWT 编码/解码测试 ------------------
// 要存储的数据
var data = {
sub = "user123";
name = "张三";
role = "admin";
exp = tonumber(time().addSeconds(3600)); // 1小时后过期
};
// 使用私钥 + Ed25519 签名生成 JWT
var token = crypt.jwt.encode(data, privateKey, "EdDSA");
console.log("=== 生成的 JWT Token ===");
console.log(token);
console.log();
// 使用公钥 + Ed25519 验证并解码 JWT
var decoded = crypt.jwt.decode(token, publicKey, "EdDSA");
if(decoded) {
console.success("=== 验证成功,解码结果 ===");
console.log("Header:");
console.dump(decoded.header);
console.log("Payload:");
console.dump(decoded.payload);
} else {
console.fail("JWT 验证失败!");
}
console.log();
//----------- 测试篡改后的 Token ------------------
console.log("=== 测试篡改 Token ===");
var tamperedToken = string.replace(token, "张三", "李四");
var tamperedResult = crypt.jwt.decode(tamperedToken, publicKey, ed25519Verify);
console.status(tamperedResult,"篡改后验证签名(应当显示失败)")
console.pause();
crypt.jwt.algorithm.EdDSA 库的源代码如下;
//wt.algorithm.ed25519 算法
import crypt.jwt;
import BouncyCastle;
namespace crypt.jwt.algorithm.EdDSA{
sign = function(key, payload) {
var signer = ..BouncyCastle.Crypto.Signers.Ed25519Signer();
signer.Init(true, key);
var msgBytes = ..raw.buffer(payload);
signer.BlockUpdate(msgBytes, 0, #msgBytes);
return signer.GenerateSignature();
};
verify = function(key, signature, payload) {
var verifier = ..BouncyCastle.Crypto.Signers.Ed25519Signer();
verifier.Init(false, key);
var msgBytes = ..raw.buffer(payload);
verifier.BlockUpdate(msgBytes, 0, #msgBytes);
return verifier.VerifySignature(..raw.buffer(signature));
};
}
/*****intellisense()
crypt.jwt.algorithm.EdDSA = 导入此库为 crypt.jwt 添加 ed25519 算法。
end intellisense*****/