Skip to content

Commit 8023bb2

Browse files
authored
Remove Buffer usage
1 parent 3c79883 commit 8023bb2

11 files changed

+132
-62
lines changed

.npmignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
.travis.yml
1+
test
2+
.github

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
{
22
"name": "gmsm-sm2js",
3-
"version": "0.6.7",
3+
"version": "0.7.0",
44
"description": "Pure Javascript implementation of the SM2/SM3/SM4 functions based on jsrsasign",
55
"keywords": [
66
"sm2",
77
"sm3",
88
"sm4",
9-
"gmsm"
9+
"gmsm",
10+
"jsrsasign"
1011
],
1112
"main": "index.js",
1213
"scripts": {
13-
"test": "standard && node src/cryptojs_sm3_test.js && node src/cryptojs_sm4_test.js && node src/sm2_test.js"
14+
"test": "standard && node test/util_test.js && node test/cryptojs_sm3_test.js && node test/cryptojs_sm4_test.js && node test/sm2_test.js"
1415
},
1516
"dependencies": {
1617
"jsrsasign": "^11.1.0"

src/jsrsasign_patch.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const rs = require('jsrsasign')
22
const KJUR = rs.KJUR
33
const C = rs.CryptoJS
44
const CEnc = C.enc
5+
const util = require('./util')
56

67
function parsePBES2 (hP8Prv) {
78
const pASN = rs.ASN1HEX.parse(hP8Prv)
@@ -148,7 +149,7 @@ function patchSM4 () {
148149
default:
149150
throw new Error('unsupported algorithm: ' + algName)
150151
}
151-
const cipher = crypto.createCipheriv(cipherMode, Buffer.from(hKey, 'hex'), Buffer.from(param.iv, 'hex'))
152+
const cipher = crypto.createCipheriv(cipherMode, util.hexToUint8Array(hKey), util.hexToUint8Array(param.iv))
152153
return cipher.update(hPlain, 'hex', 'hex') + cipher.final('hex')
153154
}
154155
const wKey = C.enc.Hex.parse(hKey)
@@ -222,7 +223,7 @@ function patchSM4 () {
222223
default:
223224
throw new Error('unsupported algorithm: ' + algName)
224225
}
225-
const cipher = crypto.createDecipheriv(cipherMode, Buffer.from(hKey, 'hex'), Buffer.from(param.iv, 'hex'))
226+
const cipher = crypto.createDecipheriv(cipherMode, util.hexToUint8Array(hKey), util.hexToUint8Array(param.iv))
226227
return cipher.update(hEnc, 'hex', 'hex') + cipher.final('hex')
227228
}
228229
const wKey = C.enc.Hex.parse(hKey)

src/sm2.js

+37-37
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ function adaptSM2 (ecdsa) {
9090
ecdsa[sm2] = true
9191
/**
9292
* Encrypt data with SM2 alg
93-
* @param {String|Uint8Array|Buffer} data The data to be encrypted
93+
* @param {string|Uint8Array} data The data to be encrypted
9494
* @param {EncrypterOptions} opts options for ciphertext format, default is C1C3C2
9595
* @returns hex string of ciphertext
9696
*/
@@ -101,12 +101,12 @@ function adaptSM2 (ecdsa) {
101101

102102
/**
103103
* Encrypt hex data with SM2 alg
104-
* @param {String} data The hex data to be encrypted
104+
* @param {string} data The hex data to be encrypted
105105
* @param {EncrypterOptions} opts options for ciphertext format, default is C1C3C2
106106
* @returns hex string of ciphertext
107107
*/
108108
ecdsa.encryptHex = function (dataHex, opts = DEFAULT_SM2_ENCRYPT_OPTIONS) {
109-
return this.encrypt(new Uint8Array(Buffer.from(dataHex, 'hex')), opts)
109+
return this.encrypt(util.hexToUint8Array(dataHex), opts)
110110
}
111111

112112
/**
@@ -133,7 +133,7 @@ function adaptSM2 (ecdsa) {
133133
const k = this.getBigRandom(n)
134134
const c1 = G.multiply(k)
135135
const s = Q.multiply(k)
136-
const c2 = kdf(new Uint8Array(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE).concat(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE))), dataLen)
136+
const c2 = kdf(Uint8Array.from(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE).concat(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE))), dataLen)
137137
if (!c2) {
138138
if (count++ > MAX_RETRY) {
139139
throw new Error('sm2: A5, failed to calculate valid t')
@@ -143,25 +143,25 @@ function adaptSM2 (ecdsa) {
143143
for (let i = 0; i < dataLen; i++) {
144144
c2[i] ^= data[i]
145145
}
146-
md.update(new Uint8Array(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE)))
146+
md.update(Uint8Array.from(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE)))
147147
md.update(data)
148-
md.update(new Uint8Array(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE)))
148+
md.update(Uint8Array.from(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE)))
149149
const c3 = md.digestRaw()
150150
if (opts.getEncodingFormat() === CIPHERTEXT_ENCODING_PLAIN) {
151-
return Buffer.from(c1.getEncoded(false)).toString('hex') + Buffer.from(c3).toString('hex') + Buffer.from(c2).toString('hex')
151+
return util.toHex(c1.getEncoded(false)) + util.toHex(c3) + util.toHex(c2)
152152
}
153153
const derX = new rs.asn1.DERInteger({ bigint: c1.getX().toBigInteger() })
154154
const derY = new rs.asn1.DERInteger({ bigint: c1.getY().toBigInteger() })
155-
const derC3 = new rs.asn1.DEROctetString({ hex: Buffer.from(c3).toString('hex') })
156-
const derC2 = new rs.asn1.DEROctetString({ hex: Buffer.from(c2).toString('hex') })
155+
const derC3 = new rs.asn1.DEROctetString({ hex: util.toHex(c3) })
156+
const derC2 = new rs.asn1.DEROctetString({ hex: util.toHex(c2) })
157157
const derSeq = new rs.asn1.DERSequence({ array: [derX, derY, derC3, derC2] })
158158
return derSeq.tohex()
159159
} while (true)
160160
}
161161

162162
/**
163163
* SM2 decryption
164-
* @param {String|Uint8Array|Buffer} data The data to be decrypted
164+
* @param {String|Uint8Array} data The data to be decrypted
165165
* @return {String} decrypted hex content
166166
*/
167167
ecdsa.decrypt = function (data) {
@@ -171,18 +171,18 @@ function adaptSM2 (ecdsa) {
171171

172172
/**
173173
* SM2 decryption
174-
* @param {String} dataHex The hex data to be decrypted
175-
* @return {String} decrypted hex content
174+
* @param {string} dataHex The hex data to be decrypted
175+
* @return {string} decrypted hex content
176176
*/
177177
ecdsa.decryptHex = function (dataHex) {
178-
return this.decrypt(new Uint8Array(Buffer.from(dataHex, 'hex')))
178+
return this.decrypt(util.hexToUint8Array(dataHex))
179179
}
180180

181181
/**
182182
* SM2 decryption (internal function)
183183
* @param {Uint8Array} data The hex data to be decrypted
184184
* @param {BigInteger} d The SM2 private key
185-
* @return {String} decrypted hex content
185+
* @return {string} decrypted hex content
186186
*/
187187
ecdsa.decryptRaw = function (data, d) {
188188
data = util.normalizeInput(data)
@@ -198,7 +198,7 @@ function adaptSM2 (ecdsa) {
198198
const s = c1.multiply(d)
199199
const c2 = data.subarray(97)
200200
const c3 = data.subarray(65, 97)
201-
const plaintext = kdf(new Uint8Array(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE).concat(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE))), dataLen - 97)
201+
const plaintext = kdf(Uint8Array.from(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE).concat(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE))), dataLen - 97)
202202
if (!plaintext) {
203203
throw new Error('sm2: invalid cipher content')
204204
}
@@ -207,9 +207,9 @@ function adaptSM2 (ecdsa) {
207207
}
208208
// check c3
209209
const md = new MessageDigest()
210-
md.update(new Uint8Array(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE)))
210+
md.update(Uint8Array.from(util.integerToBytes(s.getX().toBigInteger(), SM2_BYTE_SIZE)))
211211
md.update(plaintext)
212-
md.update(new Uint8Array(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE)))
212+
md.update(Uint8Array.from(util.integerToBytes(s.getY().toBigInteger(), SM2_BYTE_SIZE)))
213213
const hash = md.digestRaw()
214214
let difference = 0
215215
for (let i = 0; i < hash.length; i++) {
@@ -219,7 +219,7 @@ function adaptSM2 (ecdsa) {
219219
throw new Error('sm2: decryption error')
220220
}
221221

222-
return Buffer.from(plaintext).toString('hex')
222+
return util.toHex(plaintext)
223223
}
224224

225225
/**
@@ -301,7 +301,7 @@ function adaptSM2 (ecdsa) {
301301

302302
/**
303303
* calculateZA ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
304-
* @param {String|Uint8Array|Buffer} uid The user id, use default if not specified
304+
* @param {string|Uint8Array} uid The user id, use default if not specified
305305
* @returns Uint8Array of the result
306306
*/
307307
ecdsa.calculateZA = function (uid) {
@@ -315,29 +315,29 @@ function adaptSM2 (ecdsa) {
315315
}
316316
const entla = uidLen << 3 // bit length
317317
const md = new MessageDigest()
318-
md.update(new Uint8Array([0xff & (entla >>> 8), 0xff & entla]))
318+
md.update(Uint8Array.from([0xff & (entla >>> 8), 0xff & entla]))
319319
md.update(uid)
320-
md.update(new Uint8Array(Buffer.from(SM2_CURVE_PARAMS_FOR_ZA, 'hex'))) // a||b||gx||gy
320+
md.update(util.hexToUint8Array(SM2_CURVE_PARAMS_FOR_ZA)) // a||b||gx||gy
321321
let Q
322322
if (this.pubKeyHex) {
323323
Q = rs.ECPointFp.decodeFromHex(this.ecparams.curve, this.pubKeyHex)
324324
} else {
325325
const d = new rs.BigInteger(this.prvKeyHex, 16)
326326
const G = this.ecparams.G
327327
Q = G.multiply(d)
328-
this.pubKeyHex = Buffer.from(Q.getEncoded()).toString('hex')
328+
this.pubKeyHex = util.toHex(Q.getEncoded())
329329
}
330-
md.update(new Uint8Array(util.integerToBytes(Q.getX().toBigInteger(), SM2_BYTE_SIZE))) // x
331-
md.update(new Uint8Array(util.integerToBytes(Q.getY().toBigInteger(), SM2_BYTE_SIZE))) // y
330+
md.update(Uint8Array.from(util.integerToBytes(Q.getX().toBigInteger(), SM2_BYTE_SIZE))) // x
331+
md.update(Uint8Array.from(util.integerToBytes(Q.getY().toBigInteger(), SM2_BYTE_SIZE))) // y
332332
return md.digestRaw()
333333
}
334334
}
335335
}
336336

337337
/**
338338
* SM2 KDF function
339-
* @param {String|Uint8Array|Buffer} data The salt for kdf
340-
* @param {Number} len The request key bytes length
339+
* @param {string|Uint8Array} data The salt for kdf
340+
* @param {number} len The request key bytes length
341341
* @returns Uint8Array of the generated key
342342
*/
343343
function kdf (data, len) {
@@ -394,7 +394,7 @@ class MessageDigest {
394394
*/
395395
updateHex (hex) {
396396
if (useNodeSM3) {
397-
this.md.update(new Uint8Array(Buffer.from(hex, 'hex')))
397+
this.md.update(util.hexToUint8Array(hex))
398398
} else {
399399
this.md.update(rs.CryptoJS.enc.Hex.parse(hex))
400400
}
@@ -618,7 +618,7 @@ class Signature {
618618
* SM2 encryption function
619619
*
620620
* @param {string|object} pubkey hex public key string or ECDSA object
621-
* @param {string|Buffer|Uint8Array} data plaintext data
621+
* @param {string|Uint8Array} data plaintext data
622622
* @param {EncrypterOptions} opts options, just support encodingFormat now, default is plain encoding format
623623
* @returns hex plain format ciphertext
624624
*/
@@ -643,7 +643,7 @@ function encrypt (pubkey, data, opts = DEFAULT_SM2_ENCRYPT_OPTIONS) {
643643
* @returns hex ans.1 format ciphertext
644644
*/
645645
function plainCiphertext2ASN1 (data) {
646-
data = new Uint8Array(Buffer.from(data, 'hex'))
646+
data = util.hexToUint8Array(data)
647647
const dataLen = data.length
648648

649649
if (data[0] !== UNCOMPRESSED) {
@@ -657,8 +657,8 @@ function plainCiphertext2ASN1 (data) {
657657
const c3 = data.subarray(65, 97)
658658
const derX = new rs.asn1.DERInteger({ bigint: point1.getX().toBigInteger() })
659659
const derY = new rs.asn1.DERInteger({ bigint: point1.getY().toBigInteger() })
660-
const derC3 = new rs.asn1.DEROctetString({ hex: Buffer.from(c3).toString('hex') })
661-
const derC2 = new rs.asn1.DEROctetString({ hex: Buffer.from(c2).toString('hex') })
660+
const derC3 = new rs.asn1.DEROctetString({ hex: util.toHex(c3) })
661+
const derC2 = new rs.asn1.DEROctetString({ hex: util.toHex(c2) })
662662
const derSeq = new rs.asn1.DERSequence({ array: [derX, derY, derC3, derC2] })
663663

664664
return derSeq.getEncodedHex()
@@ -704,7 +704,7 @@ function asn1Ciphertext2Plain (hexASN1Data) {
704704
const c3 = aValue[2]
705705
const c2 = aValue[3]
706706

707-
return Buffer.from(point.getEncoded(false)).toString('hex') + c3 + c2
707+
return util.toHex(point.getEncoded(false)) + c3 + c2
708708
}
709709

710710
/**
@@ -716,14 +716,14 @@ function asn1Ciphertext2Plain (hexASN1Data) {
716716
* @returns hex plain format ciphertext
717717
*/
718718
function encryptHex (pubkey, data, opts = DEFAULT_SM2_ENCRYPT_OPTIONS) {
719-
return encrypt(pubkey, new Uint8Array(Buffer.from(data, 'hex')), opts)
719+
return encrypt(pubkey, util.hexToUint8Array(data), opts)
720720
}
721721

722722
/**
723723
* SM2 decrypt function
724724
*
725725
* @param {string|object} prvKey private key used to decrypt, private key hex string or ECDSA object.
726-
* @param {string|Buffer|Uint8Array} data plain format (C1||C3|C2) ciphertext data
726+
* @param {string|Uint8Array} data plain format (C1||C3|C2) ciphertext data
727727
* @returns hex plaintext
728728
*/
729729
function decrypt (prvKey, data) {
@@ -758,7 +758,7 @@ function decryptHex (prvKey, data) {
758758
if (tag === '30') {
759759
data = asn1Ciphertext2Plain(data)
760760
}
761-
return decrypt(prvKey, new Uint8Array(Buffer.from(data, 'hex')))
761+
return decrypt(prvKey, util.hexToUint8Array(data))
762762
}
763763

764764
function getCurveName () {
@@ -780,7 +780,7 @@ rs.asn1.csr.CSRUtil.newCSRPEM = function (param) {
780780
const hCSRI = (new rs.asn1.csr.CertificationRequestInfo(this.params)).getEncodedHex()
781781
const sig = new Signature({ alg: this.params.sigalg })
782782
sig.init(this.params.sbjprvkey)
783-
const sighex = sig.sm2Sign(new Uint8Array(Buffer.from(hCSRI, 'hex')))
783+
const sighex = sig.sm2Sign(util.hexToUint8Array(hCSRI))
784784
this.params.sighex = sighex
785785
}
786786
}
@@ -801,7 +801,7 @@ function createX509 () {
801801

802802
const sig = new Signature({ alg: algName })
803803
sig.init(pubKey)
804-
return sig.sm2Verify(hSigVal, new Uint8Array(Buffer.from(hTbsCert, 'hex')))
804+
return sig.sm2Verify(hSigVal, util.hexToUint8Array(hTbsCert))
805805
}
806806
return x
807807
}

0 commit comments

Comments
 (0)