seckit/src/__tests__/algorithm/sm2_test.js
2026-04-18 10:54:59 +08:00

288 lines
12 KiB
JavaScript

const test = require('tape')
const rs = require('jsrsasign')
const sm2 = require('../src/sm2')
const util = require('../src/util')
const publicKeyPemFromAliKmsForSign = `-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAERrsLH25zLm2LIo6tivZM9afLprSX
6TCKAmQJArAO7VOtZyW4PQwfaTsUIF7IXEFG4iI8bNuTQwMykUzLu2ypEA==
-----END PUBLIC KEY-----
`
const sm2PKIXPublicKeyHex = '3059301306072a8648ce3d020106082a811ccf5501822d03420004ef7db908af06082ef4a30e0ec28623371c106a53296a7b0e1a9b5717bd9cb81beb20d094aba685fd0f6a7ecc007ccf797ba634476326723b303d9dec873f440b'
const signatureHex = '30450220757984e0a063394ee0792b52172dd4273c05e2a66d734ff804a37b9ac639c098022100d9739a8d7a37fc88a1b4210998da489ad5b0dee1c8cb9097e532318aded5d204'
const csrFromAli = `-----BEGIN CERTIFICATE REQUEST-----
MIIBYjCCAQkCAQAwRzELMAkGA1UEBhMCQ04xEzARBgNVBAMMCkNhcmdvU21hcnQx
DzANBgNVBAcMBlpodWhhaTESMBAGA1UECAwJR3Vhbmdkb25nMFkwEwYHKoZIzj0C
AQYIKoEcz1UBgi0DQgAERrsLH25zLm2LIo6tivZM9afLprSX6TCKAmQJArAO7VOt
ZyW4PQwfaTsUIF7IXEFG4iI8bNuTQwMykUzLu2ypEKBgMC4GCSqGSIb3DQEJDjEh
MB8wHQYDVR0OBBYEFA3FO8vT+8qZBfGZa2TRhLRbme+9MC4GCSqGSIb3DQEJDjEh
MB8wHQYDVR0RBBYwFIESZW1tYW4uc3VuQGlxYXguY29tMAoGCCqBHM9VAYN1A0cA
MEQCIBQx6yv3rzfWCkKqDZQOfNKESQc6NtpQbeVvcxfBrciwAiAj78kkrF5R3g4l
bxIHjKZHc2sztHCXe7cseWGiLq0syg==
-----END CERTIFICATE REQUEST-----
`
// CA was from https://www.gmcert.org/
const CA_CERT = `-----BEGIN CERTIFICATE-----
MIICIzCCAcigAwIBAgIJAKun/ZLoSXfeMAoGCCqBHM9VAYN1MGcxCzAJBgNVBAYT
AkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdIYWlEaWFuMRMwEQYDVQQK
DApHTUNlcnQub3JnMR8wHQYDVQQDDBZHTUNlcnQgR00gUm9vdCBDQSAtIDAxMB4X
DTE5MTAyNDEyMzEzM1oXDTM5MDcxMTEyMzEzM1owZzELMAkGA1UEBhMCQ04xEDAO
BgNVBAgMB0JlaWppbmcxEDAOBgNVBAcMB0hhaURpYW4xEzARBgNVBAoMCkdNQ2Vy
dC5vcmcxHzAdBgNVBAMMFkdNQ2VydCBHTSBSb290IENBIC0gMDEwWTATBgcqhkjO
PQIBBggqgRzPVQGCLQNCAASXWWtv+ifV7dJHqPNXwcmioh/48Wg3IuI+o11nLEOD
zljxL2yMxoQM6xfNJHuqadXXNZv3D2rml5Pk0W/tmfHEo10wWzAdBgNVHQ4EFgQU
f1peOwCEWSoPmL6hDm85lUMQTQcwHwYDVR0jBBgwFoAUf1peOwCEWSoPmL6hDm85
lUMQTQcwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYIKoEcz1UBg3UDSQAw
RgIhAJ7AZAC0i+4OyfxDuvPIg0I7ZtqL2kII2f1syaIW4C6iAiEAlHuUu0TMrOAr
sU47scL1B9BhyEh5tbEjsKLHia3K0YU=
-----END CERTIFICATE-----
`
// cert was generated from https://www.gmcert.org/
const cert = `-----BEGIN CERTIFICATE-----
MIICDTCCAbOgAwIBAgIJAOWoGwJCnVw5MAoGCCqBHM9VAYN1MGcxCzAJBgNVBAYT
AkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdIYWlEaWFuMRMwEQYDVQQK
DApHTUNlcnQub3JnMR8wHQYDVQQDDBZHTUNlcnQgR00gUm9vdCBDQSAtIDAxMB4X
DTIxMDIyNDA3NTgxMloXDTIyMDIyNDA3NTgxMlowIjELMAkGA1UEBhMCQ04xEzAR
BgNVBAMMCkNhcmdvU21hcnQwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAATi93H1
6+sN4/e6ksqPb/yAaR5/ewgO0PVAtAqMXV3IIZsug/VgFrduCzE71PKHHKKrY3MA
d1pP8ozvDIGpoYJ8o4GMMIGJMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMCwG
CWCGSAGG+EIBDQQfFh1HTUNlcnQub3JnIFNpZ25lZCBDZXJ0aWZpY2F0ZTAdBgNV
HQ4EFgQUPY0wMfEXn8wNhQTy7bL/dNJcA1UwHwYDVR0jBBgwFoAUf1peOwCEWSoP
mL6hDm85lUMQTQcwCgYIKoEcz1UBg3UDSAAwRQIgQsJ/kjgsc5cDavOvLvAOn2c9
u1EHM5QIWn58/xlMu1gCIQDk7Kp4A/c+W2lr93yFHiTPxwtKIz/nwtH4GRAcxeiM
iA==
-----END CERTIFICATE-----
`
const sm2PrivateKeyEncryptedPKCS8 = `
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIH2MGEGCSqGSIb3DQEFDTBUMDQGCSqGSIb3DQEFDDAnBBDa6ckWJNP3QBD7MIF8
4nVqAgEQAgEQMA0GCSqBHM9VAYMRAgUAMBwGCCqBHM9VAWgCBBDMUgr+5Y/XN2g9
mPGiISzGBIGQytwK98/ET4WrS0H7AsUri6FTqztrzAvgzFl3+s9AsaYtUlzE3EzE
x6RWxo8kpKO2yj0a/Jh9WZCD4XAcoZ9aMopiWlOdpXJr/iQlMGdirCYIoF37lHMc
jZHNffmk4ii7NxCfjrzpiFq4clYsNMXeSEnq1tuOEur4kYcjHYSIFc9bPG656a60
+SIJsJuPFi0f
-----END ENCRYPTED PRIVATE KEY-----`
const sm2PrivateKeyPlainPKCS8 = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbFoKCy7tPL7D5PEl
K/4OKMUEoca/GZnuuwr57w+ObIWhRANCAASDVuZCpA69GNKbo1MvvZ87vujwJ8P2
85pbovhwNp+ZiJgfXv5V0cXN9sDvKwcIR6FPf99CcqjfCcRC8wWK+Uuh
-----END PRIVATE KEY-----`
const pkcs8SM2P256PrivateKeyHex = '308187020100301306072a8648ce3d020106082a811ccf5501822d046d306b0201010420b26da57ba53004ddcd387ad46a361b51b308481f2327d47fb10c5fb3a8c86b92a144034200040d5365bfdbdc564c5b0eda0a85ddbd753821a709de90efe0666ba2544766acf1100ac0484d166842011da5cd6139e53dedb99ce37cea9edf4941628066e861bf'
const sec1SM2PrivateKeyHex = '30770201010420857dd87970aab4328dad891c781e3b270742aa9cf5d3d3764efe77f6c3d6e33aa00a06082a811ccf5501822da14403420004ced963a5705a0490ff13dde893cbda6de61f41fcaf917a5b4007d30cdec46426bc39b9c18d15b2a68a64dc333f262e600b675856285b42296f24741ee6f562a0'
test('SM2 P-256 encrypt/decrypt local', function (t) {
const ec = new rs.ECDSA({ curve: sm2.getCurveName() })
const plainText = 'send reinforcements, we\'re going to advance'
const expected = '73656e64207265696e666f7263656d656e74732c20776527726520676f696e6720746f20616476616e6365'
const keypair = ec.generateKeyPairHex()
const ciphertext = sm2.encrypt(keypair.ecpubhex, plainText)
const asn1text = sm2.plainCiphertext2ASN1(ciphertext)
console.log('ciphertext=' + ciphertext)
console.log('asn.1 ciphertext=' + asn1text)
const ciphertext1 = sm2.asn1Ciphertext2Plain(asn1text)
t.equal(ciphertext1, ciphertext)
const result = sm2.decryptHex(keypair.ecprvhex, ciphertext)
t.equal(result, expected)
const result2 = sm2.decryptHex(keypair.ecprvhex, asn1text)
t.equal(result2, expected)
t.end()
})
test('SM2 P-256 encrypt, output hex asn.1 ciphertext', function (t) {
const ec = new rs.ECDSA({ curve: sm2.getCurveName() })
const plainText = 'send reinforcements, we\'re going to advance'
const expected = '73656e64207265696e666f7263656d656e74732c20776527726520676f696e6720746f20616476616e6365'
const keypair = ec.generateKeyPairHex()
const ciphertext = sm2.encrypt(keypair.ecpubhex, plainText, sm2.asn1EncrypterOptions())
const tag = ciphertext.substring(0, 2)
t.equal(tag, '30')
const result = sm2.decryptHex(keypair.ecprvhex, ciphertext)
t.equal(result, expected)
t.end()
})
test('SM2 P-256 sign/verify local', function (t) {
const ec = new rs.ECDSA({ curve: sm2.getCurveName() })
const keypair = ec.generateKeyPairHex()
const sig1 = sm2.createSM2Signature()
sig1.init({ curve: sm2.getCurveName(), d: keypair.ecprvhex })
sig1.updateString('emmansun')
const hSig = sig1.sign()
console.log('hSig=' + hSig)
const sig2 = sm2.createSM2Signature()
sig2.init({ curve: sm2.getCurveName(), xy: keypair.ecpubhex })
sig2.updateString('emmansun')
t.true(sig2.verify(hSig))
t.end()
})
test('SM2 P-256 sm2 specific sign/verify', function (t) {
const ec = new rs.ECDSA({ curve: sm2.getCurveName() })
const keypair = ec.generateKeyPairHex()
const sig1 = sm2.createSM2Signature()
sig1.init({ curve: sm2.getCurveName(), d: keypair.ecprvhex })
const hSig = sig1.sm2Sign('emmansun')
const hSig1 = sig1.sm2Sign('emmansun 1')
console.log('hSig=' + hSig)
console.log('hSig1=' + hSig1)
const sig2 = sm2.createSM2Signature()
sig2.init({ curve: sm2.getCurveName(), xy: keypair.ecpubhex })
t.true(sig2.sm2Verify(hSig, 'emmansun'))
t.true(sig2.sm2Verify(hSig1, 'emmansun 1'))
t.end()
})
test('NIST P-256 sign/verify local', function (t) {
const ec = new rs.ECDSA({ curve: sm2.getCurveName() })
const keypair = ec.generateKeyPairHex()
const sig1 = new sm2.Signature({ alg: 'SHA256withECDSA' })
sig1.init({ curve: sm2.getCurveName(), d: keypair.ecprvhex })
sig1.updateString('emmansun')
const hSig = sig1.sign()
console.log('hSig=' + hSig)
const sig2 = new sm2.Signature({ alg: 'SHA256withECDSA' })
sig2.init({ curve: sm2.getCurveName(), xy: keypair.ecpubhex })
sig2.updateString('emmansun')
t.true(sig2.verify(hSig))
t.end()
})
test('SM2 parse public key pem, verify signature, both from ali KMS', function (t) {
const sig = sm2.createSM2Signature()
sig.init(publicKeyPemFromAliKmsForSign)
t.equal(sig.pubKey.curveName, sm2.getCurveName())
t.true(sig.verifyWithMessageHash('66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0', signatureHex))
t.end()
})
test('SM2 calculate ZA', function (t) {
const sig = sm2.createSM2Signature()
sig.init(publicKeyPemFromAliKmsForSign)
const za = util.toHex(sig.pubKey.calculateZA())
t.equal(za, '17e7fc071f1418200aeead3c5118a2f18381431d92b808a3bd1ba2d8270c2914')
t.end()
})
test('SM2 parse CSR from ALI KMS', function (t) {
const result = rs.asn1.csr.CSRUtil.getParam(csrFromAli)
t.equal(result.sigalg, sm2.getSignAlg())
t.end()
})
test('SM2 gen CSR', function (t) {
const kp = rs.KEYUTIL.generateKeypair('EC', sm2.getCurveName())
const prvKey = kp.prvKeyObj
const pubKey = kp.pubKeyObj
const csr = rs.asn1.csr.CSRUtil.newCSRPEM({
subject: { str: '/C=US/O=TEST' },
sbjpubkey: pubKey,
sigalg: sm2.getSignAlg(),
sbjprvkey: prvKey
})
console.log(csr)
const result = rs.asn1.csr.CSRUtil.getParam(csr)
console.log(JSON.stringify(result))
t.end()
})
test('SM2 read cert', function (t) {
const x = sm2.createX509()
x.readCertPEM(cert)
t.equal(x.getSignatureAlgorithmField(), sm2.getSignAlg())
t.true(x.verifySignature(rs.KEYUTIL.getKey(CA_CERT)))
t.end()
})
test('Parse PKCS8 encrypted SM2 private key', function (t) {
const key = rs.KEYUTIL.getKeyFromEncryptedPKCS8PEM(sm2PrivateKeyEncryptedPKCS8, 'Password1')
t.equal(key.curveName, 'sm2p256v1')
t.equal(key.prvKeyHex, '6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85')
t.equal(key.pubKeyHex, '048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1')
t.end()
})
test('Parse PKCS8 unencrypted SM2 private key', function (t) {
const key = rs.KEYUTIL.getKeyFromPlainPrivatePKCS8PEM(sm2PrivateKeyPlainPKCS8)
t.equal(key.curveName, 'sm2p256v1')
t.equal(key.prvKeyHex, '6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85')
t.equal(key.pubKeyHex, '048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1')
t.end()
})
test('Parse PKCS8 unencrypted SM2 private key with Signature', function (t) {
const sig1 = sm2.createSM2Signature()
sig1.init(sm2PrivateKeyPlainPKCS8)
const hSig = sig1.sm2Sign('emmansun')
console.log('hSig=' + hSig)
const sig2 = sm2.createSM2Signature()
sig2.init({ curve: sm2.getCurveName(), xy: sig1.prvKey.pubKeyHex })
t.true(sig2.sm2Verify(hSig, 'emmansun'))
t.end()
})
test('Parse PKCS8 encrypted SM2 private key with Signature', function (t) {
const sig1 = sm2.createSM2Signature()
sig1.init(sm2PrivateKeyEncryptedPKCS8, 'Password1')
const hSig = sig1.sm2Sign('emmansun')
console.log('hSig=' + hSig)
const sig2 = sm2.createSM2Signature()
sig2.init({ curve: sm2.getCurveName(), xy: sig1.prvKey.pubKeyHex })
t.true(sig2.sm2Verify(hSig, 'emmansun'))
t.end()
})
test('Parse PKCS8 unencrypted SM2 private key (hex) with Signature', function (t) {
const sig1 = sm2.createSM2Signature()
sig1.init(pkcs8SM2P256PrivateKeyHex, undefined, 'pkcs8prv')
const hSig = sig1.sm2Sign('emmansun')
console.log('hSig=' + hSig)
const sig2 = sm2.createSM2Signature()
sig2.init({ curve: sm2.getCurveName(), xy: sig1.prvKey.pubKeyHex })
t.true(sig2.sm2Verify(hSig, 'emmansun'))
t.end()
})
test('Parse SEC1 SM2 private key (hex) with Signature', function (t) {
const sig1 = sm2.createSM2Signature()
sig1.init(sec1SM2PrivateKeyHex, undefined, 'pkcs5prv')
const hSig = sig1.sm2Sign('emmansun')
console.log('hSig=' + hSig)
const sig2 = sm2.createSM2Signature()
sig2.init({ curve: sm2.getCurveName(), xy: sig1.prvKey.pubKeyHex })
t.true(sig2.sm2Verify(hSig, 'emmansun'))
t.end()
})
test('Parse SM2 PKIX public key (hex) with Signature', function (t) {
const sig1 = sm2.createSM2Signature()
sig1.init(sm2PKIXPublicKeyHex, undefined, 'pkcs8pub')
t.equals(sig1.pubKey.pubKeyHex, '04ef7db908af06082ef4a30e0ec28623371c106a53296a7b0e1a9b5717bd9cb81beb20d094aba685fd0f6a7ecc007ccf797ba634476326723b303d9dec873f440b')
t.end()
})