kit.program/kit/test/debug_sm2_verify_detail.js
2026-04-04 17:54:13 +08:00

114 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const rs = require('jsrsasign');
const sm2 = require('sm-crypto').sm2;
const sm3 = require('sm-crypto').sm3;
// 用户提供的 SM2 PKCS7 签名数据
const sm2P7Base64 = 'MIIDKgYKKoEcz1UGAQQCAqCCAxowggMWAgEBMQ4wDAYIKoEcz1UBgxEFADAMBgoqgRzPVQYBBAIBoIICNzCCAjMwggHWoAMCAQICBgD1tfRoKTAMBggqgRzPVQGDdQUAMEAxCzAJBgNVBAYTAkNOMQ8wDQYDVQQKDAZQQkNDUkMxIDAeBgNVBAMMF1BCQ0NSQyBTTTIgT3BlcmF0aW9uIENBMB4XDTI2MDQwMjA4MDEzOVoXDTM2MDMzMDA4MDEzOVowTTELMAkGA1UEBhMCQ04xDzANBgNVBAoMBlBCQ0NSQzEtMCsGA1UEAwwkOTRmMWY5MzgtZjBiZC00NzYyLTkyOGUtZjY4YTdjY2UxNDFkMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEu3dU5Vn20VjVL9xGCCRPB/EpATY6HW24+zIZv46Cfv0R2PGM+ZJs/dYarw7qJCnpIbe5T0PKmyyJITNVrVnnMaOBrDCBqTAfBgNVHSMEGDAWgBRUqfVQHMpD+o+YdrPK1JlRJL757zAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECkPjA8MQ4wDAYDVQQDDAVjcmw3MTEMMAoGA1UECwwDY3JsMQ8wDQYDVQQKDAZQQkNDUkMxCzAJBgNVBAYTAkNOMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQU5bG6U0lYzWtkPJE74M/3HdafKKcwDAYIKoEcz1UBg3UFAANJADBGAiEAuLTE36/Eobcui23bFiPvOU4MOT0O0r9SyyHZ1JuvLwMCIQCejuSk03jyUAkbh1SaPx5n7WlDjI6tx9v9RJ7iw5rlojGBtzCBtAIBATBKMEAxCzAJBgNVBAYTAkNOMQ8wDQYDVQQKDAZQQkNDUkMxIDAeBgNVBAMMF1BCQ0NSQyBTTTIgT3BlcmF0aW9uIENBAgYA9bX0aCkwDAYIKoEcz1UBgxEFADANBgkqgRzPVQGCLQEFAARGMEQCIALTgWMD7io1JHfzInBwzDQpe9bonchuLFSED//JLDtnAiBmEUtr+ssAQIzFG4wY0CAj9QZxhENyCU2UYL1fhaysUA==';
// 测试用的原始数据
const mockOriginalData = 'QDJNHHVB_FWQ';
console.log('=== 详细调试 SM2 PKCS7 验证 ===');
console.log('原始数据:', mockOriginalData);
console.log('原始数据长度:', mockOriginalData.length);
console.log('原始数据 UTF-8 编码:', Buffer.from(mockOriginalData, 'utf8').toString('hex'));
const parser = new rs.KJUR.asn1.cms.CMSParser();
const p7 = parser.getCMSSignedData(rs.b64tohex(sm2P7Base64));
console.log('\nPKCS7 信息:');
console.log('版本:', p7.version);
console.log('哈希算法:', p7.hashalgs);
console.log('签名者数量:', p7.sinfos ? p7.sinfos.length : 0);
if (p7.sinfos && p7.sinfos.length > 0) {
const signer = p7.sinfos[0];
console.log('\n签名者信息:');
console.log(' 签名算法:', signer.sigalg);
console.log(' 签名值 (hex):', signer.sighex);
console.log(' 签名值长度:', signer.sighex ? signer.sighex.length / 2 : 0, '字节');
// 解析签名值ASN.1 DER 格式)
console.log('\n解析签名值:');
try {
const sigAsn1 = rs.ASN1HEX.getTLVbyList(signer.sighex, 0, []);
console.log(' 签名 ASN.1 结构:', sigAsn1);
// 提取 r 和 s 值
const r = rs.ASN1HEX.getTLVbyList(sigAsn1, 0, [0]);
const s = rs.ASN1HEX.getTLVbyList(sigAsn1, 0, [1]);
console.log(' r 值:', r.substring(4)); // 跳过 tag 和 length
console.log(' s 值:', s.substring(4));
} catch (e) {
console.error(' 解析签名值错误:', e.message);
}
}
// 提取公钥
if (p7.certs && p7.certs.array && p7.certs.array.length > 0) {
const certPem = p7.certs.array[0];
const certHex = rs.pemtohex(certPem);
const tbsCert = rs.ASN1HEX.getTLVbyList(certHex, 0, [0]);
const spki = rs.ASN1HEX.getTLVbyList(tbsCert, 0, [6]);
const publicKeyBitString = rs.ASN1HEX.getTLVbyList(spki, 0, [1]);
const publicKeyHex = publicKeyBitString.substring(6);
console.log('\n公钥信息:');
console.log(' 公钥 (hex):', publicKeyHex);
console.log(' 公钥长度:', publicKeyHex.length / 2, '字节');
console.log(' 公钥格式:', publicKeyHex.startsWith('04') ? '未压缩格式' : '压缩格式');
// 尝试验证签名
if (p7.sinfos && p7.sinfos.length > 0) {
const signer = p7.sinfos[0];
// 计算 SM3 哈希
console.log('\n计算 SM3 哈希:');
const hash = sm3(mockOriginalData);
console.log(' 原始数据哈希:', hash);
// 测试不同的公钥格式
console.log('\n测试不同的公钥格式:');
// 1. 使用完整公钥(带 04 前缀)
try {
const result1 = sm2.doVerifySignature(hash, signer.sighex, publicKeyHex);
console.log(' 验证结果(完整公钥):', result1);
} catch (e) {
console.error(' 验证错误(完整公钥):', e.message);
}
// 2. 使用不带 04 前缀的公钥
try {
const pubKeyWithoutPrefix = publicKeyHex.substring(2);
const result2 = sm2.doVerifySignature(hash, signer.sighex, pubKeyWithoutPrefix);
console.log(' 验证结果(不带前缀):', result2);
} catch (e) {
console.error(' 验证错误(不带前缀):', e.message);
}
// 3. 尝试使用签名值的不同格式
console.log('\n测试不同的签名值格式:');
try {
// 直接使用 sighex
const result3 = sm2.doVerifySignature(hash, signer.sighex, publicKeyHex);
console.log(' 验证结果(直接使用 sighex:', result3);
} catch (e) {
console.error(' 验证错误(直接使用 sighex:', e.message);
}
// 4. 测试不同的编码
console.log('\n测试不同的编码:');
try {
// 使用 Buffer 转换
const hashBuffer = Buffer.from(mockOriginalData, 'utf8');
const hash2 = sm3(hashBuffer);
console.log(' Buffer 哈希:', hash2);
const result4 = sm2.doVerifySignature(hash2, signer.sighex, publicKeyHex);
console.log(' 验证结果Buffer 编码):', result4);
} catch (e) {
console.error(' 验证错误Buffer 编码):', e.message);
}
}
}