288 lines
12 KiB
JavaScript
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()
|
|
}) |