const rs = require('jsrsasign'); // 用户提供的 SM2 PKCS7 签名数据(没有头尾) const sm2P7Base64 = 'MIIDKgYKKoEcz1UGAQQCAqCCAxowggMWAgEBMQ4wDAYIKoEcz1UBgxEFADAMBgoqgRzPVQYBBAIBoIICNzCCAjMwggHWoAMCAQICBgD1tfRoKTAMBggqgRzPVQGDdQUAMEAxCzAJBgNVBAYTAkNOMQ8wDQYDVQQKDAZQQkNDUkMxIDAeBgNVBAMMF1BCQ0NSQyBTTTIgT3BlcmF0aW9uIENBMB4XDTI2MDQwMjA4MDEzOVoXDTM2MDMzMDA4MDEzOVowTTELMAkGA1UEBhMCQ04xDzANBgNVBAoMBlBCQ0NSQzEtMCsGA1UEAwwkOTRmMWY5MzgtZjBiZC00NzYyLTkyOGUtZjY4YTdjY2UxNDFkMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEu3dU5Vn20VjVL9xGCCRPB/EpATY6HW24+zIZv46Cfv0R2PGM+ZJs/dYarw7qJCnpIbe5T0PKmyyJITNVrVnnMaOBrDCBqTAfBgNVHSMEGDAWgBRUqfVQHMpD+o+YdrPK1JlRJL757zAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECkPjA8MQ4wDAYDVQQDDAVjcmw3MTEMMAoGA1UECwwDY3JsMQ8wDQYDVQQKDAZQQkNDUkMxCzAJBgNVBAYTAkNOMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQU5bG6U0lYzWtkPJE74M/3HdafKKcwDAYIKoEcz1UBg3UFAANJADBGAiEAuLTE36/Eobcui23bFiPvOU4MOT0O0r9SyyHZ1JuvLwMCIQCejuSk03jyUAkbh1SaPx5n7WlDjI6tx9v9RJ7iw5rlojGBtzCBtAIBATBKMEAxCzAJBgNVBAYTAkNOMQ8wDQYDVQQKDAZQQkNDUkMxIDAeBgNVBAMMF1BCQ0NSQyBTTTIgT3BlcmF0aW9uIENBAgYA9bX0aCkwDAYIKoEcz1UBgxEFADANBgkqgRzPVQGCLQEFAARGMEQCIALTgWMD7io1JHfzInBwzDQpe9bonchuLFSED//JLDtnAiBmEUtr+ssAQIzFG4wY0CAj9QZxhENyCU2UYL1fhaysUA=='; const parser = new rs.KJUR.asn1.cms.CMSParser(); const p7 = parser.getCMSSignedData(rs.b64tohex(sm2P7Base64)); console.log('=== 调试 SM2 公钥提取 ==='); if (p7.certs && p7.certs.array && p7.certs.array.length > 0) { const certPem = p7.certs.array[0]; console.log('证书 PEM 前200字符:', certPem.substring(0, 200)); const x509 = new rs.X509(); x509.readCertPEM(certPem); console.log('\n证书信息:'); console.log('主题:', x509.getSubjectString()); console.log('颁发者:', x509.getIssuerString()); console.log('序列号:', x509.getSerialNumberHex()); // 尝试获取公钥 console.log('\n尝试获取公钥:'); try { const pubKey = x509.getPublicKey(); console.log('getPublicKey() 结果:', pubKey); if (pubKey) { console.log('公钥类型:', typeof pubKey); console.log('公钥 keys:', Object.keys(pubKey)); } } catch (e) { console.error('getPublicKey() 错误:', e.message); } // 尝试直接从 ASN.1 解析 console.log('\n尝试从 ASN.1 解析公钥:'); try { const hex = rs.pemtohex(certPem); // 证书结构: SEQUENCE -> tbsCertificate -> subjectPublicKeyInfo const hTBS = rs.ASN1HEX.getTLVbyList(hex, 0, [0]); const hSPKI = rs.ASN1HEX.getTLVbyList(hTBS, 0, [6]); // subjectPublicKeyInfo 通常在第6个位置 if (hSPKI) { console.log('subjectPublicKeyInfo hex:', hSPKI.substring(0, 100) + '...'); // 提取公钥值 const hAlgorithm = rs.ASN1HEX.getTLVbyList(hSPKI, 0, [0]); const hPublicKey = rs.ASN1HEX.getTLVbyList(hSPKI, 0, [1]); if (hAlgorithm) { console.log('算法 OID:', rs.ASN1HEX.getOIDbyList(hAlgorithm, 0, [0])); } if (hPublicKey) { console.log('公钥值 hex:', hPublicKey.substring(4) + '...'); // 跳过 tag 和 length // 尝试创建 PEM const pubKeyPem = rs.KJUR.asn1.ASN1Util.getPEMStringFromHex(hSPKI, 'PUBLIC KEY'); console.log('公钥 PEM:', pubKeyPem.substring(0, 200) + '...'); } } } catch (e) { console.error('ASN.1 解析错误:', e.message); } }