sm-crypto-v2 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +4 -2
- package/dist/index.d.ts +5 -1
- package/dist/index.js +66 -9
- package/dist/index.mjs +66 -9
- package/package.json +1 -1
- package/src/sm2/asn1.ts +50 -1
- package/src/sm2/index.ts +40 -12
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
4
4
|
|
5
|
+
## [1.8.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.7.0...v1.8.0) (2023-12-15)
|
6
|
+
|
7
|
+
|
8
|
+
### Features
|
9
|
+
|
10
|
+
* **sm2:** support asn1 der encoded encryption/decryption ([f08b9fd](https://github.com/Cubelrti/sm-crypto-v2/commit/f08b9fd5b64a2a257d41694c1858d7a6b07326ae))
|
11
|
+
|
5
12
|
## [1.7.0](https://github.com/Cubelrti/sm-crypto-v2/compare/v1.6.0...v1.7.0) (2023-07-17)
|
6
13
|
|
7
14
|
|
package/README.md
CHANGED
@@ -57,9 +57,11 @@ verifyResult = sm2.verifyPublicKey(compressedPublicKey) // 验证公钥
|
|
57
57
|
```js
|
58
58
|
import { sm2 } from 'sm-crypto-v2'
|
59
59
|
const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
|
60
|
+
// 支持使用 asn1 对加密结果进行编码,在 options 参数中传入 { asn1: true } 即可,默认不开启
|
61
|
+
let encryptData = sm2.doEncrypt(msgString, publicKey, cipherMode, { asn1: false }) // 加密结果
|
60
62
|
|
61
|
-
|
62
|
-
let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode) // 解密结果
|
63
|
+
// 支持使用 asn1 对密文进行解码再解密,在 options 参数中传入 { asn1: true } 即可,默认不开启
|
64
|
+
let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode, { asn1: false }) // 解密结果
|
63
65
|
|
64
66
|
encryptData = sm2.doEncrypt(msgArray, publicKey, cipherMode) // 加密结果,输入数组
|
65
67
|
decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode, {output: 'array'}) // 解密结果,输出数组
|
package/dist/index.d.ts
CHANGED
@@ -49,15 +49,19 @@ declare const EmptyArray: Uint8Array;
|
|
49
49
|
/**
|
50
50
|
* 加密
|
51
51
|
*/
|
52
|
-
declare function doEncrypt(msg: string | Uint8Array, publicKey: string | ProjPointType<bigint>, cipherMode?: number
|
52
|
+
declare function doEncrypt(msg: string | Uint8Array, publicKey: string | ProjPointType<bigint>, cipherMode?: number, options?: {
|
53
|
+
asn1?: boolean;
|
54
|
+
}): string;
|
53
55
|
/**
|
54
56
|
* 解密
|
55
57
|
*/
|
56
58
|
declare function doDecrypt(encryptData: string, privateKey: string, cipherMode?: number, options?: {
|
57
59
|
output: 'array';
|
60
|
+
asn1?: boolean;
|
58
61
|
}): Uint8Array;
|
59
62
|
declare function doDecrypt(encryptData: string, privateKey: string, cipherMode?: number, options?: {
|
60
63
|
output: 'string';
|
64
|
+
asn1?: boolean;
|
61
65
|
}): string;
|
62
66
|
interface SignaturePoint {
|
63
67
|
k: bigint;
|
package/dist/index.js
CHANGED
@@ -133,6 +133,19 @@ var DERInteger = class extends ASN1Object {
|
|
133
133
|
return this.v;
|
134
134
|
}
|
135
135
|
};
|
136
|
+
var DEROctetString = class extends ASN1Object {
|
137
|
+
constructor(s) {
|
138
|
+
super();
|
139
|
+
this.s = s;
|
140
|
+
this.t = "04";
|
141
|
+
if (s)
|
142
|
+
this.v = s.toLowerCase();
|
143
|
+
}
|
144
|
+
hV = "";
|
145
|
+
getValue() {
|
146
|
+
return this.v;
|
147
|
+
}
|
148
|
+
};
|
136
149
|
var DERSequence = class extends ASN1Object {
|
137
150
|
constructor(asn1Array) {
|
138
151
|
super();
|
@@ -167,11 +180,19 @@ function encodeDer(r, s) {
|
|
167
180
|
const derSeq = new DERSequence([derR, derS]);
|
168
181
|
return derSeq.getEncodedHex();
|
169
182
|
}
|
183
|
+
function encodeEnc(x2, y, hash, cipher) {
|
184
|
+
const derX = new DERInteger(x2);
|
185
|
+
const derY = new DERInteger(y);
|
186
|
+
const derHash = new DEROctetString(hash);
|
187
|
+
const derCipher = new DEROctetString(cipher);
|
188
|
+
const derSeq = new DERSequence([derX, derY, derHash, derCipher]);
|
189
|
+
return derSeq.getEncodedHex();
|
190
|
+
}
|
170
191
|
function decodeDer(input) {
|
171
192
|
const start = getStartOfV(input, 0);
|
172
193
|
const vIndexR = getStartOfV(input, start);
|
173
194
|
const lR = getL(input, start);
|
174
|
-
const vR = input.
|
195
|
+
const vR = input.substring(vIndexR, vIndexR + lR * 2);
|
175
196
|
const nextStart = vIndexR + vR.length;
|
176
197
|
const vIndexS = getStartOfV(input, nextStart);
|
177
198
|
const lS = getL(input, nextStart);
|
@@ -180,6 +201,23 @@ function decodeDer(input) {
|
|
180
201
|
const s = utils.hexToNumber(vS);
|
181
202
|
return { r, s };
|
182
203
|
}
|
204
|
+
function decodeEnc(input) {
|
205
|
+
function extractSequence(input2, start2) {
|
206
|
+
const vIndex = getStartOfV(input2, start2);
|
207
|
+
const length = getL(input2, start2);
|
208
|
+
const value = input2.substring(vIndex, vIndex + length * 2);
|
209
|
+
const nextStart = vIndex + value.length;
|
210
|
+
return { value, nextStart };
|
211
|
+
}
|
212
|
+
const start = getStartOfV(input, 0);
|
213
|
+
const { value: vR, nextStart: startS } = extractSequence(input, start);
|
214
|
+
const { value: vS, nextStart: startHash } = extractSequence(input, startS);
|
215
|
+
const { value: hash, nextStart: startCipher } = extractSequence(input, startHash);
|
216
|
+
const { value: cipher } = extractSequence(input, startCipher);
|
217
|
+
const x2 = utils.hexToNumber(vR);
|
218
|
+
const y = utils.hexToNumber(vS);
|
219
|
+
return { x: x2, y, hash, cipher };
|
220
|
+
}
|
183
221
|
|
184
222
|
// src/sm2/utils.ts
|
185
223
|
var utils2 = __toESM(require("@noble/curves/abstract/utils"));
|
@@ -714,7 +752,7 @@ function calculateSharedKey(keypairA, ephemeralKeypairA, publicKeyB, ephemeralPu
|
|
714
752
|
// src/sm2/index.ts
|
715
753
|
var C1C2C3 = 0;
|
716
754
|
var EmptyArray = new Uint8Array();
|
717
|
-
function doEncrypt(msg, publicKey, cipherMode = 1) {
|
755
|
+
function doEncrypt(msg, publicKey, cipherMode = 1, options) {
|
718
756
|
const msgArr = typeof msg === "string" ? hexToArray(utf8ToHex(msg)) : Uint8Array.from(msg);
|
719
757
|
const publicKeyPoint = typeof publicKey === "string" ? sm2Curve.ProjectivePoint.fromHex(publicKey) : publicKey;
|
720
758
|
const keypair = generateKeyPairHex();
|
@@ -728,6 +766,11 @@ function doEncrypt(msg, publicKey, cipherMode = 1) {
|
|
728
766
|
const c3 = bytesToHex(sm3(utils4.concatBytes(x2, msgArr, y2)));
|
729
767
|
xorCipherStream(x2, y2, msgArr);
|
730
768
|
const c2 = bytesToHex(msgArr);
|
769
|
+
if (options?.asn1) {
|
770
|
+
const point = sm2Curve.ProjectivePoint.fromHex(keypair.publicKey);
|
771
|
+
const encode = cipherMode === C1C2C3 ? encodeEnc(point.x, point.y, c2, c3) : encodeEnc(point.x, point.y, c3, c2);
|
772
|
+
return encode;
|
773
|
+
}
|
731
774
|
return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2;
|
732
775
|
}
|
733
776
|
function xorCipherStream(x2, y2, msg) {
|
@@ -752,17 +795,31 @@ function xorCipherStream(x2, y2, msg) {
|
|
752
795
|
}
|
753
796
|
}
|
754
797
|
function doDecrypt(encryptData, privateKey, cipherMode = 1, {
|
755
|
-
output = "string"
|
798
|
+
output = "string",
|
799
|
+
asn1 = false
|
756
800
|
} = {}) {
|
757
801
|
const privateKeyInteger = utils4.hexToNumber(privateKey);
|
758
|
-
let
|
759
|
-
let c2
|
760
|
-
|
761
|
-
|
762
|
-
|
802
|
+
let c1;
|
803
|
+
let c2;
|
804
|
+
let c3;
|
805
|
+
if (asn1) {
|
806
|
+
const { x: x3, y, cipher, hash } = decodeEnc(encryptData);
|
807
|
+
c1 = sm2Curve.ProjectivePoint.fromAffine({ x: x3, y });
|
808
|
+
c3 = hash;
|
809
|
+
c2 = cipher;
|
810
|
+
if (cipherMode === C1C2C3) {
|
811
|
+
[c2, c3] = [c3, c2];
|
812
|
+
}
|
813
|
+
} else {
|
814
|
+
c1 = sm2Curve.ProjectivePoint.fromHex("04" + encryptData.substring(0, 128));
|
815
|
+
c3 = encryptData.substring(128, 128 + 64);
|
816
|
+
c2 = encryptData.substring(128 + 64);
|
817
|
+
if (cipherMode === C1C2C3) {
|
818
|
+
c3 = encryptData.substring(encryptData.length - 64);
|
819
|
+
c2 = encryptData.substring(128, encryptData.length - 64);
|
820
|
+
}
|
763
821
|
}
|
764
822
|
const msg = hexToArray(c2);
|
765
|
-
const c1 = sm2Curve.ProjectivePoint.fromHex("04" + encryptData.substring(0, 128));
|
766
823
|
const p = c1.multiply(privateKeyInteger);
|
767
824
|
const x2 = hexToArray(leftPad(utils4.numberToHexUnpadded(p.x), 64));
|
768
825
|
const y2 = hexToArray(leftPad(utils4.numberToHexUnpadded(p.y), 64));
|
package/dist/index.mjs
CHANGED
@@ -105,6 +105,19 @@ var DERInteger = class extends ASN1Object {
|
|
105
105
|
return this.v;
|
106
106
|
}
|
107
107
|
};
|
108
|
+
var DEROctetString = class extends ASN1Object {
|
109
|
+
constructor(s) {
|
110
|
+
super();
|
111
|
+
this.s = s;
|
112
|
+
this.t = "04";
|
113
|
+
if (s)
|
114
|
+
this.v = s.toLowerCase();
|
115
|
+
}
|
116
|
+
hV = "";
|
117
|
+
getValue() {
|
118
|
+
return this.v;
|
119
|
+
}
|
120
|
+
};
|
108
121
|
var DERSequence = class extends ASN1Object {
|
109
122
|
constructor(asn1Array) {
|
110
123
|
super();
|
@@ -139,11 +152,19 @@ function encodeDer(r, s) {
|
|
139
152
|
const derSeq = new DERSequence([derR, derS]);
|
140
153
|
return derSeq.getEncodedHex();
|
141
154
|
}
|
155
|
+
function encodeEnc(x2, y, hash, cipher) {
|
156
|
+
const derX = new DERInteger(x2);
|
157
|
+
const derY = new DERInteger(y);
|
158
|
+
const derHash = new DEROctetString(hash);
|
159
|
+
const derCipher = new DEROctetString(cipher);
|
160
|
+
const derSeq = new DERSequence([derX, derY, derHash, derCipher]);
|
161
|
+
return derSeq.getEncodedHex();
|
162
|
+
}
|
142
163
|
function decodeDer(input) {
|
143
164
|
const start = getStartOfV(input, 0);
|
144
165
|
const vIndexR = getStartOfV(input, start);
|
145
166
|
const lR = getL(input, start);
|
146
|
-
const vR = input.
|
167
|
+
const vR = input.substring(vIndexR, vIndexR + lR * 2);
|
147
168
|
const nextStart = vIndexR + vR.length;
|
148
169
|
const vIndexS = getStartOfV(input, nextStart);
|
149
170
|
const lS = getL(input, nextStart);
|
@@ -152,6 +173,23 @@ function decodeDer(input) {
|
|
152
173
|
const s = utils.hexToNumber(vS);
|
153
174
|
return { r, s };
|
154
175
|
}
|
176
|
+
function decodeEnc(input) {
|
177
|
+
function extractSequence(input2, start2) {
|
178
|
+
const vIndex = getStartOfV(input2, start2);
|
179
|
+
const length = getL(input2, start2);
|
180
|
+
const value = input2.substring(vIndex, vIndex + length * 2);
|
181
|
+
const nextStart = vIndex + value.length;
|
182
|
+
return { value, nextStart };
|
183
|
+
}
|
184
|
+
const start = getStartOfV(input, 0);
|
185
|
+
const { value: vR, nextStart: startS } = extractSequence(input, start);
|
186
|
+
const { value: vS, nextStart: startHash } = extractSequence(input, startS);
|
187
|
+
const { value: hash, nextStart: startCipher } = extractSequence(input, startHash);
|
188
|
+
const { value: cipher } = extractSequence(input, startCipher);
|
189
|
+
const x2 = utils.hexToNumber(vR);
|
190
|
+
const y = utils.hexToNumber(vS);
|
191
|
+
return { x: x2, y, hash, cipher };
|
192
|
+
}
|
155
193
|
|
156
194
|
// src/sm2/utils.ts
|
157
195
|
import * as utils2 from "@noble/curves/abstract/utils";
|
@@ -686,7 +724,7 @@ function calculateSharedKey(keypairA, ephemeralKeypairA, publicKeyB, ephemeralPu
|
|
686
724
|
// src/sm2/index.ts
|
687
725
|
var C1C2C3 = 0;
|
688
726
|
var EmptyArray = new Uint8Array();
|
689
|
-
function doEncrypt(msg, publicKey, cipherMode = 1) {
|
727
|
+
function doEncrypt(msg, publicKey, cipherMode = 1, options) {
|
690
728
|
const msgArr = typeof msg === "string" ? hexToArray(utf8ToHex(msg)) : Uint8Array.from(msg);
|
691
729
|
const publicKeyPoint = typeof publicKey === "string" ? sm2Curve.ProjectivePoint.fromHex(publicKey) : publicKey;
|
692
730
|
const keypair = generateKeyPairHex();
|
@@ -700,6 +738,11 @@ function doEncrypt(msg, publicKey, cipherMode = 1) {
|
|
700
738
|
const c3 = bytesToHex(sm3(utils4.concatBytes(x2, msgArr, y2)));
|
701
739
|
xorCipherStream(x2, y2, msgArr);
|
702
740
|
const c2 = bytesToHex(msgArr);
|
741
|
+
if (options?.asn1) {
|
742
|
+
const point = sm2Curve.ProjectivePoint.fromHex(keypair.publicKey);
|
743
|
+
const encode = cipherMode === C1C2C3 ? encodeEnc(point.x, point.y, c2, c3) : encodeEnc(point.x, point.y, c3, c2);
|
744
|
+
return encode;
|
745
|
+
}
|
703
746
|
return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2;
|
704
747
|
}
|
705
748
|
function xorCipherStream(x2, y2, msg) {
|
@@ -724,17 +767,31 @@ function xorCipherStream(x2, y2, msg) {
|
|
724
767
|
}
|
725
768
|
}
|
726
769
|
function doDecrypt(encryptData, privateKey, cipherMode = 1, {
|
727
|
-
output = "string"
|
770
|
+
output = "string",
|
771
|
+
asn1 = false
|
728
772
|
} = {}) {
|
729
773
|
const privateKeyInteger = utils4.hexToNumber(privateKey);
|
730
|
-
let
|
731
|
-
let c2
|
732
|
-
|
733
|
-
|
734
|
-
|
774
|
+
let c1;
|
775
|
+
let c2;
|
776
|
+
let c3;
|
777
|
+
if (asn1) {
|
778
|
+
const { x: x3, y, cipher, hash } = decodeEnc(encryptData);
|
779
|
+
c1 = sm2Curve.ProjectivePoint.fromAffine({ x: x3, y });
|
780
|
+
c3 = hash;
|
781
|
+
c2 = cipher;
|
782
|
+
if (cipherMode === C1C2C3) {
|
783
|
+
[c2, c3] = [c3, c2];
|
784
|
+
}
|
785
|
+
} else {
|
786
|
+
c1 = sm2Curve.ProjectivePoint.fromHex("04" + encryptData.substring(0, 128));
|
787
|
+
c3 = encryptData.substring(128, 128 + 64);
|
788
|
+
c2 = encryptData.substring(128 + 64);
|
789
|
+
if (cipherMode === C1C2C3) {
|
790
|
+
c3 = encryptData.substring(encryptData.length - 64);
|
791
|
+
c2 = encryptData.substring(128, encryptData.length - 64);
|
792
|
+
}
|
735
793
|
}
|
736
794
|
const msg = hexToArray(c2);
|
737
|
-
const c1 = sm2Curve.ProjectivePoint.fromHex("04" + encryptData.substring(0, 128));
|
738
795
|
const p = c1.multiply(privateKeyInteger);
|
739
796
|
const x2 = hexToArray(leftPad(utils4.numberToHexUnpadded(p.x), 64));
|
740
797
|
const y2 = hexToArray(leftPad(utils4.numberToHexUnpadded(p.y), 64));
|
package/package.json
CHANGED
package/src/sm2/asn1.ts
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
import * as utils from '@noble/curves/abstract/utils';
|
4
4
|
import { ONE } from './bn';
|
5
|
+
import { utf8ToHex } from './utils';
|
5
6
|
|
6
7
|
export function bigintToValue(bigint: bigint) {
|
7
8
|
let h = bigint.toString(16)
|
@@ -81,6 +82,20 @@ class DERInteger extends ASN1Object {
|
|
81
82
|
}
|
82
83
|
}
|
83
84
|
|
85
|
+
class DEROctetString extends ASN1Object {
|
86
|
+
public hV: string = ''
|
87
|
+
constructor(public s: string) {
|
88
|
+
super()
|
89
|
+
|
90
|
+
this.t = '04' // octstr 标签说明
|
91
|
+
if (s) this.v = s.toLowerCase()
|
92
|
+
}
|
93
|
+
|
94
|
+
getValue() {
|
95
|
+
return this.v
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
84
99
|
class DERSequence extends ASN1Object {
|
85
100
|
public t = '30'
|
86
101
|
constructor(public asn1Array: ASN1Object[]) {
|
@@ -134,6 +149,14 @@ export function encodeDer(r: bigint, s: bigint) {
|
|
134
149
|
return derSeq.getEncodedHex()
|
135
150
|
}
|
136
151
|
|
152
|
+
export function encodeEnc(x: bigint, y: bigint, hash: string, cipher: string) {
|
153
|
+
const derX = new DERInteger(x)
|
154
|
+
const derY = new DERInteger(y)
|
155
|
+
const derHash = new DEROctetString(hash)
|
156
|
+
const derCipher = new DEROctetString(cipher)
|
157
|
+
const derSeq = new DERSequence([derX, derY, derHash, derCipher])
|
158
|
+
return derSeq.getEncodedHex()
|
159
|
+
}
|
137
160
|
/**
|
138
161
|
* 解析 ASN.1 der,针对 sm2 验签
|
139
162
|
*/
|
@@ -145,7 +168,7 @@ export function decodeDer(input: string) {
|
|
145
168
|
|
146
169
|
const vIndexR = getStartOfV(input, start)
|
147
170
|
const lR = getL(input, start)
|
148
|
-
const vR = input.
|
171
|
+
const vR = input.substring(vIndexR, vIndexR +lR * 2)
|
149
172
|
|
150
173
|
const nextStart = vIndexR + vR.length
|
151
174
|
const vIndexS = getStartOfV(input, nextStart)
|
@@ -159,3 +182,29 @@ export function decodeDer(input: string) {
|
|
159
182
|
|
160
183
|
return { r, s }
|
161
184
|
}
|
185
|
+
|
186
|
+
/**
|
187
|
+
* 解析 ASN.1 der,针对 sm2 加密
|
188
|
+
*/
|
189
|
+
export function decodeEnc(input: string) {
|
190
|
+
// Extracts a sequence from the input based on the current start index.
|
191
|
+
function extractSequence(input: string, start: number): { value: string; nextStart: number } {
|
192
|
+
const vIndex = getStartOfV(input, start);
|
193
|
+
const length = getL(input, start);
|
194
|
+
const value = input.substring(vIndex, vIndex + length * 2);
|
195
|
+
const nextStart = vIndex + value.length;
|
196
|
+
return { value, nextStart };
|
197
|
+
}
|
198
|
+
|
199
|
+
const start = getStartOfV(input, 0);
|
200
|
+
|
201
|
+
const { value: vR, nextStart: startS } = extractSequence(input, start);
|
202
|
+
const { value: vS, nextStart: startHash } = extractSequence(input, startS);
|
203
|
+
const { value: hash, nextStart: startCipher } = extractSequence(input, startHash);
|
204
|
+
const { value: cipher } = extractSequence(input, startCipher);
|
205
|
+
|
206
|
+
const x = utils.hexToNumber(vR);
|
207
|
+
const y = utils.hexToNumber(vS);
|
208
|
+
|
209
|
+
return { x, y, hash, cipher };
|
210
|
+
}
|
package/src/sm2/index.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* eslint-disable no-use-before-define */
|
2
|
-
import { encodeDer, decodeDer } from './asn1'
|
2
|
+
import { encodeDer, decodeDer, encodeEnc, decodeEnc } from './asn1'
|
3
3
|
import { arrayToHex, arrayToUtf8, generateKeyPairHex, hexToArray, leftPad, utf8ToHex } from './utils'
|
4
4
|
import { sm3 } from './sm3'
|
5
5
|
import * as utils from '@noble/curves/abstract/utils';
|
@@ -18,7 +18,9 @@ export const EmptyArray = new Uint8Array()
|
|
18
18
|
/**
|
19
19
|
* 加密
|
20
20
|
*/
|
21
|
-
export function doEncrypt(msg: string | Uint8Array, publicKey: string | ProjPointType<bigint>, cipherMode = 1
|
21
|
+
export function doEncrypt(msg: string | Uint8Array, publicKey: string | ProjPointType<bigint>, cipherMode = 1, options?: {
|
22
|
+
asn1?: boolean // 使用 ASN.1 对 C1 编码
|
23
|
+
}) {
|
22
24
|
|
23
25
|
const msgArr = typeof msg === 'string' ? hexToArray(utf8ToHex(msg)) : Uint8Array.from(msg)
|
24
26
|
const publicKeyPoint = typeof publicKey === 'string' ? sm2Curve.ProjectivePoint.fromHex(publicKey) :
|
@@ -29,6 +31,7 @@ export function doEncrypt(msg: string | Uint8Array, publicKey: string | ProjPoin
|
|
29
31
|
|
30
32
|
// c1 = k * G
|
31
33
|
let c1 = keypair.publicKey
|
34
|
+
|
32
35
|
if (c1.length > 128) c1 = c1.substring(c1.length - 128)
|
33
36
|
const p = publicKeyPoint.multiply(k)
|
34
37
|
|
@@ -41,7 +44,13 @@ export function doEncrypt(msg: string | Uint8Array, publicKey: string | ProjPoin
|
|
41
44
|
|
42
45
|
xorCipherStream(x2, y2, msgArr)
|
43
46
|
const c2 = bytesToHex(msgArr)
|
44
|
-
|
47
|
+
if (options?.asn1) {
|
48
|
+
const point = sm2Curve.ProjectivePoint.fromHex(keypair.publicKey)
|
49
|
+
const encode = cipherMode === C1C2C3 ?
|
50
|
+
encodeEnc(point.x, point.y, c2, c3) :
|
51
|
+
encodeEnc(point.x, point.y, c3, c2)
|
52
|
+
return encode
|
53
|
+
}
|
45
54
|
return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2
|
46
55
|
}
|
47
56
|
|
@@ -78,26 +87,45 @@ function xorCipherStream(x2: Uint8Array, y2: Uint8Array, msg: Uint8Array) {
|
|
78
87
|
*/
|
79
88
|
export function doDecrypt(encryptData: string, privateKey: string, cipherMode?: number, options?: {
|
80
89
|
output: 'array'
|
90
|
+
asn1?: boolean
|
81
91
|
}): Uint8Array
|
82
92
|
export function doDecrypt(encryptData: string, privateKey: string, cipherMode?: number, options?: {
|
83
|
-
output: 'string'
|
93
|
+
output: 'string',
|
94
|
+
asn1?: boolean
|
84
95
|
}): string
|
85
96
|
export function doDecrypt(encryptData: string, privateKey: string, cipherMode = 1, {
|
86
97
|
output = 'string',
|
98
|
+
asn1 = false,
|
87
99
|
} = {}) {
|
88
100
|
const privateKeyInteger = utils.hexToNumber(privateKey)
|
89
101
|
|
90
|
-
let
|
91
|
-
let c2
|
102
|
+
let c1: ProjPointType<bigint>
|
103
|
+
let c2: string
|
104
|
+
let c3: string
|
105
|
+
|
92
106
|
|
93
|
-
if (
|
94
|
-
|
95
|
-
|
107
|
+
if (asn1) {
|
108
|
+
const {x, y, cipher, hash} = decodeEnc(encryptData)
|
109
|
+
c1 = sm2Curve.ProjectivePoint.fromAffine({ x, y })
|
110
|
+
c3 = hash
|
111
|
+
c2 = cipher
|
112
|
+
if (cipherMode === C1C2C3) {
|
113
|
+
[c2, c3] = [c3, c2]
|
114
|
+
}
|
115
|
+
} else {
|
116
|
+
// c1c3c2
|
117
|
+
c1 = sm2Curve.ProjectivePoint.fromHex('04' + encryptData.substring(0, 128))!
|
118
|
+
c3 = encryptData.substring(128, 128 + 64)
|
119
|
+
c2 = encryptData.substring(128 + 64)
|
120
|
+
|
121
|
+
if (cipherMode === C1C2C3) {
|
122
|
+
c3 = encryptData.substring(encryptData.length - 64)
|
123
|
+
c2 = encryptData.substring(128, encryptData.length - 64)
|
124
|
+
}
|
96
125
|
}
|
126
|
+
|
97
127
|
|
98
128
|
const msg = hexToArray(c2)
|
99
|
-
const c1 = sm2Curve.ProjectivePoint.fromHex('04' + encryptData.substring(0, 128))!
|
100
|
-
|
101
129
|
const p = c1.multiply(privateKeyInteger)
|
102
130
|
const x2 = hexToArray(leftPad(utils.numberToHexUnpadded(p.x), 64))
|
103
131
|
const y2 = hexToArray(leftPad(utils.numberToHexUnpadded(p.y), 64))
|
@@ -105,7 +133,7 @@ export function doDecrypt(encryptData: string, privateKey: string, cipherMode =
|
|
105
133
|
xorCipherStream(x2, y2, msg)
|
106
134
|
// c3 = hash(x2 || msg || y2)
|
107
135
|
const checkC3 = arrayToHex(Array.from(sm3(utils.concatBytes(x2, msg, y2))))
|
108
|
-
|
136
|
+
|
109
137
|
if (checkC3 === c3.toLowerCase()) {
|
110
138
|
return output === 'array' ? msg : arrayToUtf8(msg)
|
111
139
|
} else {
|