diff --git a/kit/src/crypto.js b/kit/src/crypto.js index a3787ec..b5abc97 100644 --- a/kit/src/crypto.js +++ b/kit/src/crypto.js @@ -380,55 +380,37 @@ function verifyPKCS7WithJsrsasign(base64Data, verifyData) { // 计算 SM3 哈希 const hash = sm3(verifyData.toString()) - // 转换签名格式:从 ASN.1 DER 格式转换为原始 r|s 格式 + // 签名格式:用户提供的是 ASN.1 DER 格式,需要使用 der: true 选项 let signatureHex = signer.sighex - if (signatureHex.startsWith('30')) { - // ASN.1 DER 格式: 30 44 02 20 [r] 02 20 [s] - try { - const rStart = 8 // 30440220 - const r = signatureHex.substring(rStart, rStart + 64) // 32字节 = 64 hex 字符 - const sStart = rStart + 64 + 4 // 0220 - const s = signatureHex.substring(sStart, sStart + 64) // 32字节 = 64 hex 字符 - signatureHex = r + s - } catch (e) { - // 如果解析失败,使用原始签名 - } - } // 使用 SM2 验证签名 (注意:使用 doVerifySignature,不是 doVerify) - // 尝试不同的选项组合 + // 尝试不同的选项组合,包括 userId + const userId = '1234567812345678' // 默认 userId + try { - // 尝试 1: 直接验证 - const result1 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex) + // 尝试 1: 使用原始数据 + DER + SM3 + userId + const result1 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true, hash: true, userId }) if (result1) return true - // 尝试 2: 使用 DER 格式 - const result2 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true }) + // 尝试 2: 使用原始数据 + DER + SM3 + const result2 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true, hash: true }) if (result2) return true - // 尝试 3: 使用 SM3 哈希 - const result3 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { hash: true }) + // 尝试 3: 使用原始数据 + DER + const result3 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true }) if (result3) return true - // 尝试 4: 同时使用 DER 和 SM3 - const result4 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true, hash: true }) + // 尝试 4: 使用哈希 + DER + SM3 + userId + const result4 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true, hash: true, userId }) if (result4) return true - // 尝试 5: 直接使用原始数据而不是哈希 - const result5 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex) + // 尝试 5: 使用哈希 + DER + SM3 + const result5 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true, hash: true }) if (result5) return true - // 尝试 6: 使用原始数据 + DER - const result6 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true }) + // 尝试 6: 使用哈希 + DER + const result6 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true }) if (result6) return true - - // 尝试 7: 使用原始数据 + SM3 - const result7 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { hash: true }) - if (result7) return true - - // 尝试 8: 所有选项 - const result8 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true, hash: true }) - if (result8) return true } catch (e) { // 忽略错误,继续尝试其他选项 } diff --git a/kit/test/debug_sm2_api_signature.js b/kit/test/debug_sm2_api_signature.js new file mode 100644 index 0000000..bbd41a0 --- /dev/null +++ b/kit/test/debug_sm2_api_signature.js @@ -0,0 +1,22 @@ +const sm2 = require('sm-crypto').sm2; + +console.log('=== 检查 sm-crypto 0.3.13 API ==='); + +// 检查 sm2 对象的属性 +console.log('sm2 对象属性:', Object.keys(sm2)); + +// 检查 doVerifySignature 函数 +console.log('\ndoVerifySignature 函数:', sm2.doVerifySignature.toString()); + +// 测试生成的签名和公钥 +const testData = 'test'; +const keypair = sm2.generateKeyPairHex(); +const sig = sm2.doSignature(testData, keypair.privateKey); + +console.log('\n测试数据:', testData); +console.log('生成的公钥:', keypair.publicKey); +console.log('生成的签名:', sig); + +// 验证生成的签名 +const verifyResult = sm2.doVerifySignature(testData, sig, keypair.publicKey); +console.log('验证结果:', verifyResult); diff --git a/kit/test/debug_sm2_api_version.js b/kit/test/debug_sm2_api_version.js new file mode 100644 index 0000000..81d3e9b --- /dev/null +++ b/kit/test/debug_sm2_api_version.js @@ -0,0 +1,55 @@ +const sm2 = require('sm-crypto').sm2; +const sm3 = require('sm-crypto').sm3; + +console.log('=== 调试 sm-crypto 0.3.13 API ==='); + +// 测试基本功能 +const testData = 'test'; +const hash = sm3(testData); +console.log('测试数据:', testData); +console.log('SM3 哈希:', hash); + +// 生成密钥对 +const keypair = sm2.generateKeyPairHex(); +console.log('\n生成的密钥对:'); +console.log(' 私钥:', keypair.privateKey); +console.log(' 公钥:', keypair.publicKey); + +// 签名 +const sig = sm2.doSignature(testData, keypair.privateKey); +console.log('\n签名:', sig); +console.log('签名长度:', sig.length); + +// 验证签名 +const verifyResult = sm2.doVerifySignature(testData, sig, keypair.publicKey); +console.log('验证结果:', verifyResult); + +// 测试用户提供的数据 +console.log('\n=== 测试用户数据 ==='); + +const data = 'QDJNHHVB_FWQ'; +const signature = '02D3816303EE2A352477F3227070CC34297BD6E89DC86E2C54840FFFC92C3B6766114B6BFA CB00408CC51B8C18D02023F50671844372094D9460BD5F85ACAC50'.replace(/\s/g, ''); +const publicKey = '04bb7754e559f6d158d52fdc4608244f07f12901363a1d6db8fb3219bf8e827efd11d8f18cf9926cfdd61aaf0eea2429e921b7b94f43ca9b2c89213355ad59e731'; + +console.log('数据:', data); +console.log('签名:', signature); +console.log('公钥:', publicKey); + +// 尝试验证 +console.log('\n尝试验证:'); +try { + // 注意:sm-crypto 0.3.13 的 API 可能不同 + // 尝试不带选项 + const result1 = sm2.doVerifySignature(data, signature, publicKey); + console.log(' 验证结果 (无选项):', result1); +} catch (e) { + console.error(' 错误 (无选项):', e.message); +} + +try { + // 尝试带哈希选项 + const result2 = sm2.doVerifySignature(hash, signature, publicKey, true); // 第二个参数是 hash 选项 + console.log(' 验证结果 (hash=true):', result2); +} catch (e) { + console.error(' 错误 (hash=true):', e.message); +} diff --git a/kit/test/debug_sm2_public_key_fix.js b/kit/test/debug_sm2_public_key_fix.js new file mode 100644 index 0000000..2b38fc8 --- /dev/null +++ b/kit/test/debug_sm2_public_key_fix.js @@ -0,0 +1,43 @@ +const sm2 = require('sm-crypto').sm2; + +console.log('=== 测试公钥格式 ==='); + +// 测试数据 +const data = 'QDJNHHVB_FWQ'; +const signature = '02D3816303EE2A352477F3227070CC34297BD6E89DC86E2C54840FFFC92C3B6766114B6BFACB00408CC51B8C18D02023F50671844372094D9460BD5F85ACAC50'; + +// 完整公钥(带 04 前缀) +const fullPublicKey = '04bb7754e559f6d158d52fdc4608244f07f12901363a1d6db8fb3219bf8e827efd11d8f18cf9926cfdd61aaf0eea2429e921b7b94f43ca9b2c89213355ad59e731'; + +// 去掉 04 前缀的公钥 +const publicKeyWithoutPrefix = fullPublicKey.substring(2); + +console.log('完整公钥:', fullPublicKey); +console.log('去掉前缀的公钥:', publicKeyWithoutPrefix); + +// 测试完整公钥 +console.log('\n使用完整公钥:'); +try { + const result1 = sm2.doVerifySignature(data, signature, fullPublicKey); + console.log(' 验证结果:', result1); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 测试去掉前缀的公钥 +console.log('\n使用去掉前缀的公钥:'); +try { + const result2 = sm2.doVerifySignature(data, signature, publicKeyWithoutPrefix); + console.log(' 验证结果:', result2); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 测试带哈希选项 +console.log('\n使用去掉前缀的公钥 + 哈希:'); +try { + const result3 = sm2.doVerifySignature(data, signature, publicKeyWithoutPrefix, true); + console.log(' 验证结果:', result3); +} catch (e) { + console.error(' 错误:', e.message); +} diff --git a/kit/test/debug_user_data.js b/kit/test/debug_user_data.js new file mode 100644 index 0000000..173de3a --- /dev/null +++ b/kit/test/debug_user_data.js @@ -0,0 +1,69 @@ +const sm2 = require('sm-crypto').sm2; +const sm3 = require('sm-crypto').sm3; + +console.log('=== 验证用户提供的具体数据 ==='); + +// 用户提供的数据 +const dataHex = '51444A4E484856425F465751'; +const signatureHex = '02D3816303EE2A352477F3227070CC34297BD6E89DC86E2C54840FFFC92C3B6766114B6BFA CB00408CC51B8C18D02023F50671844372094D9460BD5F85ACAC50'.replace(/\s/g, ''); +const userId = '1234567812345678'; +const hashHex = '0F76D50E476E24507187885DF1BC197B48F368F3C03DDF0A5C0C067D2EEF63EE'; + +// 从用户的 PKCS7 签名中提取的公钥 +const publicKeyHex = '04bb7754e559f6d158d52fdc4608244f07f12901363a1d6db8fb3219bf8e827efd11d8f18cf9926cfdd61aaf0eea2429e921b7b94f43ca9b2c89213355ad59e731'; + +// 转换数据 +const data = Buffer.from(dataHex, 'hex').toString('utf8'); +console.log('数据:', data); +console.log('数据长度:', data.length); +console.log('签名:', signatureHex); +console.log('签名长度:', signatureHex.length / 2, '字节'); +console.log('公钥:', publicKeyHex); + +// 测试不同的验证选项 +console.log('\n测试不同的验证选项:'); + +// 尝试 1: 使用原始数据 + DER + SM3 + userId +console.log('\n1. 使用原始数据 + DER + SM3 + userId:'); +try { + const result1 = sm2.doVerifySignature(data, signatureHex, publicKeyHex, { der: true, hash: true, userId }); + console.log(' 验证结果:', result1); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 2: 使用哈希 + DER +console.log('\n2. 使用哈希 + DER:'); +try { + const result2 = sm2.doVerifySignature(hashHex, signatureHex, publicKeyHex, { der: true }); + console.log(' 验证结果:', result2); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 3: 使用原始数据 + DER +console.log('\n3. 使用原始数据 + DER:'); +try { + const result3 = sm2.doVerifySignature(data, signatureHex, publicKeyHex, { der: true }); + console.log(' 验证结果:', result3); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 4: 直接使用哈希 +console.log('\n4. 直接使用哈希:'); +try { + const result4 = sm2.doVerifySignature(hashHex, signatureHex, publicKeyHex); + console.log(' 验证结果:', result4); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 5: 直接使用原始数据 +console.log('\n5. 直接使用原始数据:'); +try { + const result5 = sm2.doVerifySignature(data, signatureHex, publicKeyHex); + console.log(' 验证结果:', result5); +} catch (e) { + console.error(' 错误:', e.message); +} diff --git a/kit/test/debug_user_sm2_data.js b/kit/test/debug_user_sm2_data.js new file mode 100644 index 0000000..87eb321 --- /dev/null +++ b/kit/test/debug_user_sm2_data.js @@ -0,0 +1,80 @@ +const sm2 = require('sm-crypto').sm2; +const sm3 = require('sm-crypto').sm3; + +console.log('=== 验证用户提供的 SM2 数据 ==='); + +// 用户提供的数据 +const dataHex = '51444A4E484856425F465751'; +const signatureHex = '02D3816303EE2A352477F3227070CC34297BD6E89DC86E2C54840FFFC92C3B6766114B6BFA CB00408CC51B8C18D02023F50671844372094D9460BD5F85ACAC50'.replace(/\s/g, ''); +const userId = '1234567812345678'; +const hashHex = '0F76D50E476E24507187885DF1BC197B48F368F3C03DDF0A5C0C067D2EEF63EE'; + +// 从用户的 PKCS7 签名中提取的公钥 +const publicKeyHex = '04bb7754e559f6d158d52fdc4608244f07f12901363a1d6db8fb3219bf8e827efd11d8f18cf9926cfdd61aaf0eea2429e921b7b94f43ca9b2c89213355ad59e731'; + +// 转换数据 +const data = Buffer.from(dataHex, 'hex').toString('utf8'); +console.log('数据:', data); +console.log('数据长度:', data.length); +console.log('签名长度:', signatureHex.length / 2, '字节'); + +// 去掉公钥的 04 前缀 +const pubKeyWithoutPrefix = publicKeyHex.substring(2); +console.log('公钥(去掉前缀):', pubKeyWithoutPrefix); + +// 测试不同的验证选项 +console.log('\n测试不同的验证选项:'); + +// 尝试 1: 使用哈希 + userId +console.log('\n1. 使用哈希 + userId:'); +try { + const result1 = sm2.doVerifySignature(hashHex, signatureHex, pubKeyWithoutPrefix, { hash: true, userId }); + console.log(' 验证结果:', result1); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 2: 使用原始数据 + userId +console.log('\n2. 使用原始数据 + userId:'); +try { + const result2 = sm2.doVerifySignature(data, signatureHex, pubKeyWithoutPrefix, { hash: true, userId }); + console.log(' 验证结果:', result2); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 3: 使用原始数据 + userId + 公钥 +console.log('\n3. 使用原始数据 + userId + 公钥:'); +try { + const result3 = sm2.doVerifySignature(data, signatureHex, pubKeyWithoutPrefix, { hash: true, userId, publicKey: pubKeyWithoutPrefix }); + console.log(' 验证结果:', result3); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 4: 直接使用原始数据 +console.log('\n4. 直接使用原始数据:'); +try { + const result4 = sm2.doVerifySignature(data, signatureHex, pubKeyWithoutPrefix); + console.log(' 验证结果:', result4); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 5: 使用 DER 格式 +console.log('\n5. 使用 DER 格式:'); +try { + const result5 = sm2.doVerifySignature(data, signatureHex, pubKeyWithoutPrefix, { der: true }); + console.log(' 验证结果:', result5); +} catch (e) { + console.error(' 错误:', e.message); +} + +// 尝试 6: 使用 DER + 哈希 + userId +console.log('\n6. 使用 DER + 哈希 + userId:'); +try { + const result6 = sm2.doVerifySignature(data, signatureHex, pubKeyWithoutPrefix, { der: true, hash: true, userId }); + console.log(' 验证结果:', result6); +} catch (e) { + console.error(' 错误:', e.message); +}