aardio 文档

aardio 范例: 证书操作

import fsys;
import console;
import crypt.cert;
import crypt.rsa;

// ==================== 1. 创建自签名证书 ====================
console.log("【1. 创建自签名证书】");

var cert, err = crypt.cert.createSelfSigned("CN=测试证书, O=aardio, C=CN", 5/*有效期5年*/);
if(!cert){
    console.error("创建失败:", err);
    return;
}

console.log("创建成功!");
console.log("  主题:", cert.subject);
console.log("  颁发者:", cert.issuer);
console.log("  序列号:", cert.serialNumber);
console.log("  指纹:", cert.thumbprint);
console.log("  算法:", cert.algorithm);
console.log("  生效时间:", cert.validFrom);
console.log("  过期时间:", cert.validTo);
console.log("  是否有效:", cert.isValid);
console.log("  含私钥:", cert.hasPrivateKey);

// ==================== 2. 导出证书 ====================
console.log('【2. 导出证书】');

// 导出 PEM 格式(纯证书,不含私钥)
var pem = cert.exportPem();
console.log("PEM 格式(前100字符):", string.left(pem, 100), " ++ .");

// 导出 DER 格式(二进制)
var der = cert.exportDer();
console.log("DER 格式长度:", #der, "字节");

// 导出 PFX 格式(含私钥,需要密码)
var pfxData, password = cert.exportPfx("123456");
if(pfxData){
    console.log("PFX 格式长度:", #pfxData, "字节, 密码:", password);
} else {
    console.log("PFX 导出失败:", password);
}

// 保存到临时文件
var tempDir = io.tmpname();
var pfxPath = io.joinpath(tempDir, "test.pfx");
var pemPath = io.joinpath(tempDir, "test.pem");
var derPath = io.joinpath(tempDir, "test.cer");

string.save(pfxPath, pfxData);
string.save(pemPath, pem);
string.save(derPath, der);
console.log("已保存到临时目录:", tempDir);

// 释放原证书
cert.release();

// ==================== 3. 从各种格式加载证书 ====================
console.log('【3. 从各种格式加载证书】');

// 从 PFX 加载(含私钥)
var cert1 = crypt.cert.loadPfx(pfxPath, "123456");
console.log("从 PFX 加载:", cert1 ? "成功" : "失败");
console.log("  主题:", cert1.subject);
console.log("  含私钥:", cert1.hasPrivateKey);
cert1.release();

// 从 PEM 加载(纯证书)
var cert2 = crypt.cert(pem);
console.log("从 PEM 加载:", cert2 ? "成功" : "失败");
console.log("  主题:", cert2.subject);
cert2.release();

// 从 DER 加载
var cert3 = crypt.cert(der);
console.log("从 DER 加载:", cert3 ? "成功" : "失败");
console.log("  主题:", cert3.subject);
cert3.release();

// 从文件路径加载
var cert4 = crypt.cert(derPath);
console.log("从文件加载:", cert4 ? "成功" : "失败");
console.log("  主题:", cert4.subject);
cert4.release();

// ==================== 4. 使用 crypt.rsa 生成密钥,再创建证书 ====================
console.log('【4. 从 RSA 密钥 + 证书 PEM 创建】');

// 先创建一个自签名证书获取证书 PEM(模拟从外部获取的证书)
var tempCert = crypt.cert.createSelfSigned("CN=RSA测试");
var certPem = tempCert.exportPem();

// 获取私钥 PEM(实际场景中私钥和证书通常是配对的)
// 这里我们重新生成密钥来演示 fromPem 的用法
var rsa = crypt.rsa();
rsa.genKey(1/*AT_KEYEXCHANGE*/, 1/*EXPORTABLE*/, 2048);
var keyPem = rsa.exportPrivateKeyPkcs8ToPem();
console.log("生成的私钥 PEM(前80字符):", string.left(keyPem, 80), " ++ .");
rsa.release();

// 注意:fromPem 要求私钥和证书必须匹配
// 由于上面的私钥和证书不匹配,这里用 tempCert 自带的私钥导出
// 实际使用时,私钥和证书应该是配对的
tempCert.release();

// 正确的做法:创建配套的密钥和证书
console.log('创建配套的密钥和证书用于 fromPem 测试:');
var cert5 = crypt.cert.createSelfSigned("CN=fromPem测试, O=Demo");

// 导出 PFX 然后提取私钥(模拟实际场景)
var pfx5 = cert5.exportPfx("test");
var pem5 = cert5.exportPem();

// 重新从 PFX 加载以验证
var cert6 = crypt.cert.loadPfx(pfx5, "test");
console.log("从 PFX 重新加载:", cert6 ? "成功" : "失败");
console.log("  主题:", cert6.subject);
console.log("  含私钥:", cert6.hasPrivateKey);

cert5.release();
cert6.release();

// ==================== 5. 验证证书链 ====================
console.log('【5. 验证证书链】');

var cert7 = crypt.cert.createSelfSigned("CN=验证测试");
var valid, verifyErr = cert7.verify();
console.log("自签名证书验证:", valid ? "通过" : "失败");
if(!valid) console.log("  原因:", verifyErr);
// 注意:自签名证书通常无法通过链验证,因为根证书不在受信任存储中
cert7.release();

// ==================== 6. 从系统存储查找证书 ====================
console.log('【6. 从系统存储查找证书】');

// 查找当前用户的个人证书存储中的证书
var sysCert = crypt.cert.find("MY", "Microsoft");
if(sysCert){
    console.success("找到系统证书:");
    console.log("  主题:", sysCert.subject);
    console.log("  颁发者:", sysCert.issuer);
    console.log("  有效期:", sysCert.validFrom, "至", sysCert.validTo);
    sysCert.release();
} else {
    console.fail("未找到包含 'Microsoft' 的证书(这是正常的)");
}

// 也可以按指纹查找
// var sysCert2 = crypt.cert.find("ROOT", "指纹hex字符串", "thumbprint");

// ==================== 7. 便捷方法:一步创建并保存 PFX ====================
console.log('【7. 一步创建 PFX 文件】');

var pfxFile = io.joinpath(tempDir, "quick.pfx");
var path, pwd = crypt.cert.createPfx(pfxFile, "mypassword", "CN=快速创建", 1);
if(path){
    console.success("PFX 已保存:", path);
    console.log("密码:", pwd);
} else {
    console.fail("创建失败:", pwd);
}

// ==================== 清理临时文件 ====================
fsys.delete(tempDir);
console.pause();
Markdown 格式