aardio 文档

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*****/

Markdown 格式