n20-common-lib 2.7.7 → 2.7.8
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/package.json +1 -1
- package/src/plugins/Sign/NetSM3/index.js +236 -229
- package/src/plugins/Sign/SkfSign/index.js +249 -229
- package/src/plugins/Sign/index.js +13 -0
- package/src/plugins/Sign/sign.js +33 -11
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {IWSAgent} from './InfosecNetSignCNGAgent.min.js'
|
|
2
|
+
import {Message, MessageBox, Notification} from 'element-ui'
|
|
3
3
|
/*
|
|
4
4
|
获取证书列表接口:2.7.1 IWSASkfGetCertList (DllFilePath, SucceedFunction)
|
|
5
5
|
Attached签名接口:2.7.2 IWSASkfSignData (PlainText, CertIndex, UsbKeyPin, DigestArithmetic, SucceedFunction)
|
|
6
6
|
Attached 方式验签接口:2.7.4 IWSASkfVerifySignData (signedMsg ,SucceedFunction)
|
|
7
7
|
*/
|
|
8
8
|
let {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
IWSASetTimeOut, // 设置超时时间
|
|
10
|
+
IWSAGetVersion, // 获取版本号
|
|
11
|
+
IWSASkfGetCertList, // 获取证书列表
|
|
12
|
+
IWSASkfDetachedSign, //SKF Attached 方式签名
|
|
13
|
+
IWSASkfDetachedVerify, // SKF Attached 方式解签
|
|
14
|
+
IWSASendAvailable,
|
|
15
|
+
IWSAGetAvailable
|
|
16
16
|
} = new IWSAgent()
|
|
17
17
|
|
|
18
18
|
IWSASetTimeOut(6000)
|
|
@@ -22,258 +22,265 @@ IWSASetTimeOut(6000)
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
IWSAGetVersion((version) => {
|
|
25
|
-
|
|
25
|
+
console.warn(version)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
const codeDate = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
29
|
+
'-20000': '没有可用内存',
|
|
30
|
+
'-20001': '输入参数为空',
|
|
31
|
+
'-20002': 'Base64 解码失败',
|
|
32
|
+
'-20003': 'Base64 编码失败',
|
|
33
|
+
'-20004': '用户取消',
|
|
34
|
+
'-20005': '找不到证书',
|
|
35
|
+
'-20006': '缺少数据',
|
|
36
|
+
'-20007': '数据类型错误',
|
|
37
|
+
'-20008': '消息类型错误',
|
|
38
|
+
'-20009': '消息错误',
|
|
39
|
+
'-20010': '证书的签名错误',
|
|
40
|
+
'-20011': '证书过期',
|
|
41
|
+
'-20012': '证书已废止',
|
|
42
|
+
'-20013': '证书不可信任',
|
|
43
|
+
'-20014': '上级证书未发现',
|
|
44
|
+
'-20015': '没有找到匹配私钥',
|
|
45
|
+
'-20016': '证书解析错误',
|
|
46
|
+
'-20017': '证书签名非法',
|
|
47
|
+
'-20018': '打开证书存储区错误',
|
|
48
|
+
'-20019': '获得 CSP 失败',
|
|
49
|
+
'-20020': '签名失败',
|
|
50
|
+
'-20021': '验签失败',
|
|
51
|
+
'-20022': '加密失败',
|
|
52
|
+
'-20023': '解密失败',
|
|
53
|
+
'-20024': '未设置默认 DN 分隔符',
|
|
54
|
+
'-20025': '设置默认 DN 分隔符失败',
|
|
55
|
+
'-20026': '查证书扩展失败',
|
|
56
|
+
'-20027': '取证书属性失败',
|
|
57
|
+
'-20028': '取用户密钥失败',
|
|
58
|
+
'-20029': '创建 HASH 失败',
|
|
59
|
+
'-20030': 'HASH 数据失败',
|
|
60
|
+
'-20031': '裸签名失败',
|
|
61
|
+
'-20032': '验裸签名失败',
|
|
62
|
+
'-20033': '不支持的算法标识符',
|
|
63
|
+
'-20034': 'UNICODE 字符转多字节失败',
|
|
64
|
+
'-20035': '创建证书句柄失败',
|
|
65
|
+
'-20036': '多字节转 UNICODE 字符失败',
|
|
66
|
+
'-20037': 'DER 解码失败',
|
|
67
|
+
'-20038': '无效的 P7 签名',
|
|
68
|
+
'-20039': 'P7 中的数据 OID 错',
|
|
69
|
+
'-20040': 'P7 中的 RSA 算法 OID 错',
|
|
70
|
+
'-20051': '二代用户取消按钮',
|
|
71
|
+
'-20052': '二代等待超时',
|
|
72
|
+
'-20053': '不能得到证书的属性',
|
|
73
|
+
'-20054': 'DER 编码失败',
|
|
74
|
+
'-20055': '内存拷贝失败',
|
|
75
|
+
'-20056': 'DN 超长',
|
|
76
|
+
'-20057': 'DN 校验失败',
|
|
77
|
+
'-20058': '获取操作系统版本失败',
|
|
78
|
+
'-20059': '查找证书数量为空',
|
|
79
|
+
'-20060': '文件被占用',
|
|
80
|
+
'-20061': '证书链不完整',
|
|
81
|
+
'-20080': '创建证书列表失败',
|
|
82
|
+
'-20081': '字符转换到宽字符失败',
|
|
83
|
+
'-20082': '获取证书 CONTEXTDATA 失败',
|
|
84
|
+
'-20083': '获取证书类型失败',
|
|
85
|
+
'-20084': '输入参数错误',
|
|
86
|
+
'-20085': '获取证书列表结点数据错误',
|
|
87
|
+
'-20086': 'ECC 签名验证失败',
|
|
88
|
+
'-20087': 'ECC 证书签名验证失败',
|
|
89
|
+
'-20088': '获取 P7 包类型失败',
|
|
90
|
+
'-20089': '打开文件 失败',
|
|
91
|
+
'-20090': '获取文件状态失败',
|
|
92
|
+
'-20091': '获取文件大小失败',
|
|
93
|
+
'-20092': '文件路径太长',
|
|
94
|
+
'-20093': '保存文件失败',
|
|
95
|
+
'-20201': '校验 PIN 失败',
|
|
96
|
+
'-20202': '签名证书类型错误',
|
|
97
|
+
'-20203': 'ExportCertificate 失败',
|
|
98
|
+
'-20204': 'DigestInit 失败',
|
|
99
|
+
'-20205': 'DigestUpdate 失败',
|
|
100
|
+
'-20206': 'DigestFinal 失败',
|
|
101
|
+
'-20207': 'ECCSignData 失败',
|
|
102
|
+
'-20208': '验签名失败!',
|
|
103
|
+
'-20209': '非 ECC 证书',
|
|
104
|
+
'-20210': 'SM4 加密失败',
|
|
105
|
+
'-20211': 'Hash 算法错误',
|
|
106
|
+
'-20212': '读取文件失败',
|
|
107
|
+
'-20215': '加载 dll 失败',
|
|
108
|
+
'-20216': '获取函数地址失败',
|
|
109
|
+
'-20217': '函数执行失败',
|
|
110
|
+
'-20300': 'License 解析错误',
|
|
111
|
+
'-20301': 'IP 或域名未授权',
|
|
112
|
+
'-20302': '功能未授权',
|
|
113
|
+
'-20303': '未在有效期',
|
|
114
|
+
'-30001': '类型错误',
|
|
115
|
+
'-30002': 'CATCH 错误',
|
|
116
|
+
'-30003': '加载 dll 失败',
|
|
117
|
+
'-30004': '获取函数地址',
|
|
118
|
+
'-30005': '函数调用失败',
|
|
119
|
+
'-30006': 'json 解析失败',
|
|
120
|
+
'-30007': '拼接 json catch',
|
|
121
|
+
'-30008': 'dll 路径错误',
|
|
122
|
+
'-30009': 'dll 权限验证失败',
|
|
123
|
+
'-30101': 'DLL 没有签名值',
|
|
124
|
+
'-30102': '签名无效/打开文件错误',
|
|
125
|
+
'-30103': 'DLL 签名检验失败',
|
|
126
|
+
'-30104': 'DLL 签名检验失败',
|
|
127
|
+
'-30105': 'DLL 签名检验失败',
|
|
128
|
+
'-30106': 'DLL 签名检验失败'
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
function getDN() {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
let dn
|
|
133
|
+
let userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
|
|
134
|
+
if (userInfo && userInfo.dn) {
|
|
135
|
+
dn = userInfo.dn
|
|
136
|
+
}
|
|
137
|
+
return dn
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
/* 检测本地签名端口是否可用 */
|
|
141
141
|
export function availableSign(fn, url) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
142
|
+
url || (url = '/portal/NetSignCNG v2.3.170.1.exe')
|
|
143
|
+
// 查找已经打开的签名端口
|
|
144
|
+
let available = IWSAGetAvailable()
|
|
145
|
+
if (available) {
|
|
146
|
+
fn && fn(available)
|
|
147
|
+
} else {
|
|
148
|
+
// 如果没有,再刺探一遍 (异步请求,需等待)
|
|
149
|
+
IWSASendAvailable()
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
available = IWSAGetAvailable()
|
|
152
|
+
fn && fn(available)
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
154
|
+
if (!available) {
|
|
155
|
+
Notification({
|
|
156
|
+
title: '提示',
|
|
157
|
+
dangerouslyUseHTMLString: true,
|
|
158
|
+
message: `<div>检测到您的电脑中没有安装签名助手,为了不影响使用请使用管理员权限<a class="color-primary" href="${url}" download>下载安装</a>NetSignCNG签名助手</div>`,
|
|
159
|
+
duration: 5000
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
}, 300)
|
|
163
|
+
}
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
function verifyDn(dnList, dn) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
if (dnList.length === 0) return 'dnListEmpty'
|
|
168
|
+
if (!dnList) return 'Empty'
|
|
169
|
+
if (!dn) return 'dnIsEmpty'
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
let checkRes = ''
|
|
172
|
+
let userDnAttrsArr = dn.split(',').map((c) => c.trim())
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
174
|
+
let isIn = false
|
|
175
|
+
dnList.find((C) => {
|
|
176
|
+
let dnAttrsArr = C.certDN.split(',').map((c) => c.trim())
|
|
177
|
+
if (dnAttrsArr.every((dnAttr) => userDnAttrsArr.includes(dnAttr))) {
|
|
178
|
+
return (isIn = true)
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
if (!isIn) {
|
|
182
|
+
checkRes = 'checkRes'
|
|
179
183
|
}
|
|
180
|
-
})
|
|
181
|
-
if (!isIn) {
|
|
182
|
-
checkRes = 'checkRes'
|
|
183
|
-
}
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
return checkRes
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
// 签名
|
|
189
189
|
export async function getSign(plain, dn) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
190
|
+
if (dn === undefined) {
|
|
191
|
+
dn = getDN()
|
|
192
|
+
}
|
|
193
|
+
if (!dn) {
|
|
194
|
+
Message.error('签名参数DN错误!')
|
|
195
|
+
return false
|
|
196
|
+
}
|
|
197
|
+
let plainText = ''
|
|
198
|
+
if (typeof plain === 'object') {
|
|
199
|
+
plainText = JSON.stringify(plain)
|
|
200
|
+
} else {
|
|
201
|
+
plainText = plain
|
|
202
|
+
}
|
|
203
|
+
let answer
|
|
204
|
+
const checkRes = await getCertInfo()
|
|
204
205
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
206
|
+
if (checkRes != 'checkRes') {
|
|
207
|
+
switch (checkRes) {
|
|
208
|
+
case 'dnListEmpty':
|
|
209
|
+
Message.warning('没有匹配到证书!')
|
|
210
|
+
break
|
|
211
|
+
case 'dnIsEmpty':
|
|
212
|
+
Message.warning('DN参数为空!')
|
|
213
|
+
break
|
|
214
|
+
case 'Empty':
|
|
215
|
+
Message.warning('当前Ukey不匹配!')
|
|
216
|
+
break
|
|
217
|
+
default:
|
|
218
|
+
Message.warning('没有匹配到证书!')
|
|
216
219
|
}
|
|
217
|
-
|
|
218
|
-
)
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
if (checkRes != 'checkRes') {
|
|
222
|
-
switch (checkRes) {
|
|
223
|
-
case 'dnListEmpty':
|
|
224
|
-
Message.warning('没有匹配到证书!')
|
|
225
|
-
break
|
|
226
|
-
case 'dnIsEmpty':
|
|
227
|
-
Message.warning('DN参数为空!')
|
|
228
|
-
break
|
|
229
|
-
case 'Empty':
|
|
230
|
-
Message.warning('当前Ukey不匹配!')
|
|
231
|
-
break
|
|
232
|
-
default:
|
|
233
|
-
Message.warning('没有匹配到证书!')
|
|
220
|
+
return ''
|
|
234
221
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
222
|
+
// 签名
|
|
223
|
+
await MessageBox.prompt('请输入PIN码', '提示', {
|
|
224
|
+
confirmButtonText: '确定',
|
|
225
|
+
cancelButtonText: '取消',
|
|
226
|
+
inputType: 'password'
|
|
227
|
+
}).then(({value}) => {
|
|
228
|
+
return performSign(plainText, value).then((signedData) => {
|
|
229
|
+
answer = signedData;
|
|
230
|
+
});
|
|
231
|
+
}).catch(() => {
|
|
232
|
+
resolve()
|
|
233
|
+
})
|
|
234
|
+
return answer;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export async function getCertInfo(dn) {
|
|
238
|
+
return new Promise((resolve, reject) => {
|
|
239
|
+
// 获取证书列表
|
|
240
|
+
IWSASkfGetCertList(
|
|
241
|
+
process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'ShuttleCsp11_3000GM.dll',
|
|
242
|
+
(CertListData, errorCode) => {
|
|
243
|
+
if (errorCode) {
|
|
244
|
+
Message.error(codeDate[errorCode])
|
|
245
|
+
reject()
|
|
246
|
+
} else {
|
|
247
|
+
const checkRes = verifyDn(CertListData, dn)
|
|
248
|
+
resolve(checkRes)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
)
|
|
243
252
|
})
|
|
244
|
-
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
async function performSign(plainText, value) {
|
|
257
|
+
return new Promise((resolve, reject) => {
|
|
245
258
|
IWSASkfDetachedSign(plainText, 0, value, 'SM3', (errorCode, signedData) => {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
259
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
260
|
+
resolve(signedData)
|
|
261
|
+
} else {
|
|
262
|
+
Message.error(codeDate[errorCode])
|
|
263
|
+
reject()
|
|
264
|
+
}
|
|
253
265
|
})
|
|
254
|
-
|
|
255
|
-
.catch(() => {
|
|
256
|
-
resolve()
|
|
257
|
-
})
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
return Promise.resolve(answer)
|
|
266
|
+
})
|
|
261
267
|
}
|
|
262
268
|
|
|
269
|
+
|
|
263
270
|
/* 签名解签 */
|
|
264
271
|
export async function verifySign(signedMsg) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
let plainText
|
|
273
|
+
await new Promise((resolve, reject) => {
|
|
274
|
+
IWSASkfDetachedVerify(signedMsg, (errorCode, PlainText, certDN) => {
|
|
275
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
276
|
+
plainText = PlainText
|
|
277
|
+
resolve()
|
|
278
|
+
} else {
|
|
279
|
+
Message.error(codeDate[errorCode])
|
|
280
|
+
reject()
|
|
281
|
+
}
|
|
282
|
+
})
|
|
275
283
|
})
|
|
276
|
-
})
|
|
277
284
|
|
|
278
|
-
|
|
285
|
+
return Promise.resolve(plainText)
|
|
279
286
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {IWSAgent} from './InfosecNetSignCNGAgent.min.js'
|
|
2
|
+
import {Message, MessageBox, Notification} from 'element-ui'
|
|
3
3
|
/*
|
|
4
4
|
获取证书列表接口:2.7.1 IWSASkfGetCertList (DllFilePath, SucceedFunction)
|
|
5
5
|
Attached签名接口:2.7.2 IWSASkfSignData (PlainText, CertIndex, UsbKeyPin, DigestArithmetic, SucceedFunction)
|
|
6
6
|
Attached 方式验签接口:2.7.4 IWSASkfVerifySignData (signedMsg ,SucceedFunction)
|
|
7
7
|
*/
|
|
8
8
|
let {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
IWSASetTimeOut, // 设置超时时间
|
|
10
|
+
IWSAGetVersion, // 获取版本号
|
|
11
|
+
IWSASkfGetCertList, // 获取证书列表
|
|
12
|
+
IWSASkfSignData, //SKF Attached 方式签名
|
|
13
|
+
IWSASkfVerifySignData, // SKF Attached 方式解签
|
|
14
|
+
IWSASendAvailable,
|
|
15
|
+
IWSAGetAvailable
|
|
16
16
|
} = new IWSAgent()
|
|
17
17
|
|
|
18
18
|
IWSASetTimeOut(6000)
|
|
@@ -22,258 +22,278 @@ IWSASetTimeOut(6000)
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
IWSAGetVersion((version) => {
|
|
25
|
-
|
|
25
|
+
console.warn(version)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
const codeDate = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
29
|
+
'-20000': '没有可用内存',
|
|
30
|
+
'-20001': '输入参数为空',
|
|
31
|
+
'-20002': 'Base64 解码失败',
|
|
32
|
+
'-20003': 'Base64 编码失败',
|
|
33
|
+
'-20004': '用户取消',
|
|
34
|
+
'-20005': '找不到证书',
|
|
35
|
+
'-20006': '缺少数据',
|
|
36
|
+
'-20007': '数据类型错误',
|
|
37
|
+
'-20008': '消息类型错误',
|
|
38
|
+
'-20009': '消息错误',
|
|
39
|
+
'-20010': '证书的签名错误',
|
|
40
|
+
'-20011': '证书过期',
|
|
41
|
+
'-20012': '证书已废止',
|
|
42
|
+
'-20013': '证书不可信任',
|
|
43
|
+
'-20014': '上级证书未发现',
|
|
44
|
+
'-20015': '没有找到匹配私钥',
|
|
45
|
+
'-20016': '证书解析错误',
|
|
46
|
+
'-20017': '证书签名非法',
|
|
47
|
+
'-20018': '打开证书存储区错误',
|
|
48
|
+
'-20019': '获得 CSP 失败',
|
|
49
|
+
'-20020': '签名失败',
|
|
50
|
+
'-20021': '验签失败',
|
|
51
|
+
'-20022': '加密失败',
|
|
52
|
+
'-20023': '解密失败',
|
|
53
|
+
'-20024': '未设置默认 DN 分隔符',
|
|
54
|
+
'-20025': '设置默认 DN 分隔符失败',
|
|
55
|
+
'-20026': '查证书扩展失败',
|
|
56
|
+
'-20027': '取证书属性失败',
|
|
57
|
+
'-20028': '取用户密钥失败',
|
|
58
|
+
'-20029': '创建 HASH 失败',
|
|
59
|
+
'-20030': 'HASH 数据失败',
|
|
60
|
+
'-20031': '裸签名失败',
|
|
61
|
+
'-20032': '验裸签名失败',
|
|
62
|
+
'-20033': '不支持的算法标识符',
|
|
63
|
+
'-20034': 'UNICODE 字符转多字节失败',
|
|
64
|
+
'-20035': '创建证书句柄失败',
|
|
65
|
+
'-20036': '多字节转 UNICODE 字符失败',
|
|
66
|
+
'-20037': 'DER 解码失败',
|
|
67
|
+
'-20038': '无效的 P7 签名',
|
|
68
|
+
'-20039': 'P7 中的数据 OID 错',
|
|
69
|
+
'-20040': 'P7 中的 RSA 算法 OID 错',
|
|
70
|
+
'-20051': '二代用户取消按钮',
|
|
71
|
+
'-20052': '二代等待超时',
|
|
72
|
+
'-20053': '不能得到证书的属性',
|
|
73
|
+
'-20054': 'DER 编码失败',
|
|
74
|
+
'-20055': '内存拷贝失败',
|
|
75
|
+
'-20056': 'DN 超长',
|
|
76
|
+
'-20057': 'DN 校验失败',
|
|
77
|
+
'-20058': '获取操作系统版本失败',
|
|
78
|
+
'-20059': '查找证书数量为空',
|
|
79
|
+
'-20060': '文件被占用',
|
|
80
|
+
'-20061': '证书链不完整',
|
|
81
|
+
'-20080': '创建证书列表失败',
|
|
82
|
+
'-20081': '字符转换到宽字符失败',
|
|
83
|
+
'-20082': '获取证书 CONTEXTDATA 失败',
|
|
84
|
+
'-20083': '获取证书类型失败',
|
|
85
|
+
'-20084': '输入参数错误',
|
|
86
|
+
'-20085': '获取证书列表结点数据错误',
|
|
87
|
+
'-20086': 'ECC 签名验证失败',
|
|
88
|
+
'-20087': 'ECC 证书签名验证失败',
|
|
89
|
+
'-20088': '获取 P7 包类型失败',
|
|
90
|
+
'-20089': '打开文件 失败',
|
|
91
|
+
'-20090': '获取文件状态失败',
|
|
92
|
+
'-20091': '获取文件大小失败',
|
|
93
|
+
'-20092': '文件路径太长',
|
|
94
|
+
'-20093': '保存文件失败',
|
|
95
|
+
'-20201': '校验 PIN 失败',
|
|
96
|
+
'-20202': '签名证书类型错误',
|
|
97
|
+
'-20203': 'ExportCertificate 失败',
|
|
98
|
+
'-20204': 'DigestInit 失败',
|
|
99
|
+
'-20205': 'DigestUpdate 失败',
|
|
100
|
+
'-20206': 'DigestFinal 失败',
|
|
101
|
+
'-20207': 'ECCSignData 失败',
|
|
102
|
+
'-20208': '验签名失败!',
|
|
103
|
+
'-20209': '非 ECC 证书',
|
|
104
|
+
'-20210': 'SM4 加密失败',
|
|
105
|
+
'-20211': 'Hash 算法错误',
|
|
106
|
+
'-20212': '读取文件失败',
|
|
107
|
+
'-20215': '加载 dll 失败',
|
|
108
|
+
'-20216': '获取函数地址失败',
|
|
109
|
+
'-20217': '函数执行失败',
|
|
110
|
+
'-20300': 'License 解析错误',
|
|
111
|
+
'-20301': 'IP 或域名未授权',
|
|
112
|
+
'-20302': '功能未授权',
|
|
113
|
+
'-20303': '未在有效期',
|
|
114
|
+
'-30001': '类型错误',
|
|
115
|
+
'-30002': 'CATCH 错误',
|
|
116
|
+
'-30003': '加载 dll 失败',
|
|
117
|
+
'-30004': '获取函数地址',
|
|
118
|
+
'-30005': '函数调用失败',
|
|
119
|
+
'-30006': 'json 解析失败',
|
|
120
|
+
'-30007': '拼接 json catch',
|
|
121
|
+
'-30008': 'dll 路径错误',
|
|
122
|
+
'-30009': 'dll 权限验证失败',
|
|
123
|
+
'-30101': 'DLL 没有签名值',
|
|
124
|
+
'-30102': '签名无效/打开文件错误',
|
|
125
|
+
'-30103': 'DLL 签名检验失败',
|
|
126
|
+
'-30104': 'DLL 签名检验失败',
|
|
127
|
+
'-30105': 'DLL 签名检验失败',
|
|
128
|
+
'-30106': 'DLL 签名检验失败'
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
function getDN() {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
let dn
|
|
133
|
+
let userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
|
|
134
|
+
if (userInfo && userInfo.dn) {
|
|
135
|
+
dn = userInfo.dn
|
|
136
|
+
}
|
|
137
|
+
return dn
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
/* 检测本地签名端口是否可用 */
|
|
141
141
|
export function availableSign(fn, url) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
142
|
+
url || (url = '/portal/NetSignCNG v2.3.170.1.exe')
|
|
143
|
+
// 查找已经打开的签名端口
|
|
144
|
+
let available = IWSAGetAvailable()
|
|
145
|
+
if (available) {
|
|
146
|
+
fn && fn(available)
|
|
147
|
+
} else {
|
|
148
|
+
// 如果没有,再刺探一遍 (异步请求,需等待)
|
|
149
|
+
IWSASendAvailable()
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
available = IWSAGetAvailable()
|
|
152
|
+
fn && fn(available)
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
154
|
+
if (!available) {
|
|
155
|
+
Notification({
|
|
156
|
+
title: '提示',
|
|
157
|
+
dangerouslyUseHTMLString: true,
|
|
158
|
+
message: `<div>检测到您的电脑中没有安装签名助手,为了不影响使用请使用管理员权限<a class="color-primary" href="${url}" download>下载安装</a>NetSignCNG签名助手</div>`,
|
|
159
|
+
duration: 5000
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
}, 300)
|
|
163
|
+
}
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
function verifyDn(dnList, dn) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
if (dnList.length === 0) return 'dnListEmpty'
|
|
168
|
+
if (!dnList) return 'Empty'
|
|
169
|
+
if (!dn) return 'dnIsEmpty'
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
let checkRes = ''
|
|
172
|
+
let userDnAttrsArr = dn.split(',').map((c) => c.trim())
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
174
|
+
let isIn = false
|
|
175
|
+
dnList.find((C) => {
|
|
176
|
+
let dnAttrsArr = C.certDN.split(',').map((c) => c.trim())
|
|
177
|
+
if (dnAttrsArr.every((dnAttr) => userDnAttrsArr.includes(dnAttr))) {
|
|
178
|
+
return (isIn = true)
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
if (!isIn) {
|
|
182
|
+
checkRes = 'checkRes'
|
|
179
183
|
}
|
|
180
|
-
})
|
|
181
|
-
if (!isIn) {
|
|
182
|
-
checkRes = 'checkRes'
|
|
183
|
-
}
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
return checkRes
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
// 签名
|
|
189
189
|
export async function getSign(plain, dn) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
190
|
+
if (dn === undefined) {
|
|
191
|
+
dn = getDN()
|
|
192
|
+
}
|
|
193
|
+
if (!dn) {
|
|
194
|
+
Message.error('签名参数DN错误!')
|
|
195
|
+
return false
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
let plainText = ''
|
|
199
|
+
if (typeof plain === 'object') {
|
|
200
|
+
plainText = JSON.stringify(plain)
|
|
201
|
+
} else {
|
|
202
|
+
plainText = plain
|
|
203
|
+
}
|
|
204
|
+
const checkRes = await getCertInfo(dn)
|
|
204
205
|
|
|
205
|
-
await new Promise((resolve, reject) => {
|
|
206
|
-
// 获取证书列表
|
|
207
|
-
IWSASkfGetCertList(
|
|
208
|
-
process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'WTSKFInterface.dll',
|
|
209
|
-
(CertListData, errorCode) => {
|
|
210
|
-
if (errorCode) {
|
|
211
|
-
Message.error(codeDate[errorCode])
|
|
212
|
-
reject()
|
|
213
|
-
} else {
|
|
214
|
-
checkRes = verifyDn(CertListData, dn)
|
|
215
|
-
resolve(checkRes)
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
)
|
|
219
|
-
})
|
|
220
206
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
207
|
+
if (checkRes) {
|
|
208
|
+
switch (checkRes) {
|
|
209
|
+
case 'dnListEmpty':
|
|
210
|
+
Message.warning('没有匹配到证书!')
|
|
211
|
+
break
|
|
212
|
+
case 'dnIsEmpty':
|
|
213
|
+
Message.warning('DN参数为空!')
|
|
214
|
+
break
|
|
215
|
+
case 'Empty':
|
|
216
|
+
Message.warning('当前Ukey不匹配!')
|
|
217
|
+
break
|
|
218
|
+
default:
|
|
219
|
+
Message.warning('没有匹配到证书!')
|
|
220
|
+
}
|
|
221
|
+
return ''
|
|
234
222
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
223
|
+
let answer
|
|
224
|
+
await MessageBox.prompt('请输入PIN码', '提示', {
|
|
225
|
+
confirmButtonText: '确定',
|
|
226
|
+
cancelButtonText: '取消',
|
|
227
|
+
inputType: 'password'
|
|
228
|
+
}).then(({value}) => {
|
|
229
|
+
return performSign(plainText, value).then((signedData) => {
|
|
230
|
+
answer = signedData;
|
|
231
|
+
});
|
|
232
|
+
})
|
|
233
|
+
// 签名
|
|
234
|
+
|
|
235
|
+
return answer;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* 获取证书信息
|
|
240
|
+
* @param dn
|
|
241
|
+
* @returns {Promise<*>}
|
|
242
|
+
*/
|
|
243
|
+
export async function getCertInfo(dn) {
|
|
244
|
+
return new Promise((resolve, reject) => {
|
|
245
|
+
// 获取证书列表
|
|
246
|
+
IWSASkfGetCertList(
|
|
247
|
+
process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'WTSKFInterface.dll',
|
|
248
|
+
(CertListData, errorCode) => {
|
|
249
|
+
if (errorCode) {
|
|
250
|
+
Message.error(codeDate[errorCode])
|
|
251
|
+
reject()
|
|
252
|
+
} else {
|
|
253
|
+
const checkRes = verifyDn(CertListData, dn)
|
|
254
|
+
resolve(checkRes)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
)
|
|
243
258
|
})
|
|
244
|
-
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* 执行签名
|
|
263
|
+
* @param plainText
|
|
264
|
+
* @param value
|
|
265
|
+
* @returns {Promise<*>}
|
|
266
|
+
*/
|
|
267
|
+
async function performSign(plainText, value) {
|
|
268
|
+
return new Promise((resolve, reject) => {
|
|
245
269
|
IWSASkfSignData(plainText, 0, value, 'SM3', (errorCode, signedData) => {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
270
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
271
|
+
resolve(signedData)
|
|
272
|
+
} else {
|
|
273
|
+
Message.error(codeDate[errorCode])
|
|
274
|
+
reject()
|
|
275
|
+
}
|
|
253
276
|
})
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
return Promise.resolve(answer)
|
|
277
|
+
.catch(() => {
|
|
278
|
+
resolve()
|
|
279
|
+
})
|
|
280
|
+
})
|
|
261
281
|
}
|
|
262
282
|
|
|
263
283
|
/* 签名解签 */
|
|
264
284
|
export async function verifySign(signedMsg) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
285
|
+
let plainText
|
|
286
|
+
await new Promise((resolve, reject) => {
|
|
287
|
+
IWSASkfVerifySignData(signedMsg, (errorCode, PlainText, certDN) => {
|
|
288
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
289
|
+
plainText = PlainText
|
|
290
|
+
resolve()
|
|
291
|
+
} else {
|
|
292
|
+
Message.error(codeDate[errorCode])
|
|
293
|
+
reject()
|
|
294
|
+
}
|
|
295
|
+
})
|
|
275
296
|
})
|
|
276
|
-
})
|
|
277
297
|
|
|
278
|
-
|
|
298
|
+
return Promise.resolve(plainText)
|
|
279
299
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import importG from '../../utils/importGlobal.js'
|
|
2
2
|
|
|
3
3
|
import CaMap from './CaMap.js'
|
|
4
|
+
import { getCertInfo } from "./sign";
|
|
5
|
+
import {getCertInfo as SkfSign } from './SkfSign/index'
|
|
6
|
+
import {getCertInfo as NetSM3 } from './NetSM3/index'
|
|
4
7
|
export async function getSign(p1, p2, p3) {
|
|
5
8
|
let signType = window.sessionStorage.getItem('signType')
|
|
6
9
|
if (!signType || !CaMap[signType]) {
|
|
@@ -105,3 +108,13 @@ export async function getSign(p1, p2, p3) {
|
|
|
105
108
|
|
|
106
109
|
return por
|
|
107
110
|
}
|
|
111
|
+
|
|
112
|
+
export function getCert(dn) {
|
|
113
|
+
if (signType === 'inetSign' /* 信安CA */) {
|
|
114
|
+
return getCertInfo(dn)
|
|
115
|
+
} else if (signType === 'SkfSign') {
|
|
116
|
+
return SkfSign(dn)
|
|
117
|
+
} else if (signType === 'NetSM3') {
|
|
118
|
+
return NetSM3(dn)
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/plugins/Sign/sign.js
CHANGED
|
@@ -61,6 +61,23 @@ export function verifySign(signedMsg) {
|
|
|
61
61
|
|
|
62
62
|
/* 给对象或字符串签名 */
|
|
63
63
|
export function getSign(plain, dn) {
|
|
64
|
+
let index = getCertInfo(dn)
|
|
65
|
+
let plainText = ''
|
|
66
|
+
if (typeof plain === 'object') {
|
|
67
|
+
plainText = JSON.stringify(plain)
|
|
68
|
+
} else {
|
|
69
|
+
plainText = plain
|
|
70
|
+
}
|
|
71
|
+
return performSign(plainText,index)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 获取证书信息
|
|
77
|
+
* @param dn
|
|
78
|
+
* @returns {*|string|boolean}
|
|
79
|
+
*/
|
|
80
|
+
export function getCertInfo(dn) {
|
|
64
81
|
if (dn === undefined) {
|
|
65
82
|
dn = getDN()
|
|
66
83
|
}
|
|
@@ -68,23 +85,28 @@ export function getSign(plain, dn) {
|
|
|
68
85
|
Message.error('签名参数DN错误!')
|
|
69
86
|
return false
|
|
70
87
|
}
|
|
71
|
-
let plainText = ''
|
|
72
|
-
if (typeof plain === 'object') {
|
|
73
|
-
plainText = JSON.stringify(plain)
|
|
74
|
-
} else {
|
|
75
|
-
plainText = plain
|
|
76
|
-
}
|
|
77
88
|
|
|
78
|
-
let
|
|
89
|
+
let certInfo
|
|
79
90
|
IWSAGetAllCertsListInfoByCertDN('', 'Sign', parseCA(dn), 0, (dnList) => {
|
|
80
|
-
|
|
91
|
+
certInfo = verifyDn(dnList, dn)
|
|
81
92
|
})
|
|
82
|
-
if (
|
|
93
|
+
if (certInfo === -1) {
|
|
83
94
|
Message.warning('没有匹配到证书!')
|
|
84
95
|
return ''
|
|
85
96
|
}
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
|
|
98
|
+
return certInfo
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 执行签名
|
|
103
|
+
* @param plain
|
|
104
|
+
* @param index
|
|
105
|
+
* @returns {*|string}
|
|
106
|
+
*/
|
|
107
|
+
export function performSign(plain, index) {
|
|
108
|
+
let answer
|
|
109
|
+
IWSAAttachedSign('1', plain, index, 'SHA1', (errorCode, signedData) => {
|
|
88
110
|
if (errorCode === 0 || errorCode === '0') {
|
|
89
111
|
answer = signedData
|
|
90
112
|
} else {
|