n20-common-lib 2.7.12 → 2.7.13
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
CHANGED
|
@@ -2,21 +2,19 @@
|
|
|
2
2
|
<el-button-group class="n20-icon-group-button">
|
|
3
3
|
<el-button
|
|
4
4
|
:icon="leftIcon"
|
|
5
|
-
:
|
|
6
|
-
:type="left"
|
|
5
|
+
:type="leftButtonType"
|
|
7
6
|
size="mini"
|
|
8
7
|
onlyicon
|
|
9
|
-
|
|
10
|
-
@click="handleClick(
|
|
8
|
+
:class="`el-button--${leftButtonType}`"
|
|
9
|
+
@click="handleClick(true)"
|
|
11
10
|
/>
|
|
12
11
|
<el-button
|
|
13
12
|
:icon="rightIcon"
|
|
14
|
-
:
|
|
15
|
-
:type="right"
|
|
13
|
+
:type="rightButtonType"
|
|
16
14
|
size="mini"
|
|
17
15
|
onlyicon
|
|
18
|
-
|
|
19
|
-
@click="handleClick(
|
|
16
|
+
:class="`el-button--${rightButtonType}`"
|
|
17
|
+
@click="handleClick(false)"
|
|
20
18
|
/>
|
|
21
19
|
</el-button-group>
|
|
22
20
|
</template>
|
|
@@ -38,26 +36,25 @@ export default {
|
|
|
38
36
|
default: true
|
|
39
37
|
}
|
|
40
38
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
computed: {
|
|
40
|
+
leftButtonType() {
|
|
41
|
+
return this.active ? 'primary' : 'default'
|
|
42
|
+
},
|
|
43
|
+
rightButtonType() {
|
|
44
|
+
return this.active ? 'default' : 'primary'
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
-
mounted() {
|
|
48
|
-
this.handleClick(this.active)
|
|
49
|
-
},
|
|
50
47
|
methods: {
|
|
51
|
-
handleClick(
|
|
52
|
-
this.$emit('click',
|
|
53
|
-
|
|
54
|
-
this.left = 'primary'
|
|
55
|
-
this.right = 'default'
|
|
56
|
-
} else {
|
|
57
|
-
this.left = 'default'
|
|
58
|
-
this.right = 'primary'
|
|
59
|
-
}
|
|
48
|
+
handleClick(value) {
|
|
49
|
+
this.$emit('click', value)
|
|
50
|
+
this.$emit('update:active', value)
|
|
60
51
|
}
|
|
61
52
|
}
|
|
62
53
|
}
|
|
63
54
|
</script>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
.n20-icon-group-button .icon-button {
|
|
58
|
+
width: 31.5px;
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Message, MessageBox, Notification } from 'element-ui'
|
|
2
|
+
import { IWSAgent } from './InfosecNetSignCNGAgent.min.js'
|
|
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,265 +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 = 0
|
|
172
|
+
let userDnAttrsArr = dn.split(',').map((c) => c.trim())
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
if (!isIn) {
|
|
182
|
-
checkRes = 'checkRes'
|
|
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)
|
|
183
179
|
}
|
|
180
|
+
})
|
|
181
|
+
if (!isIn) {
|
|
182
|
+
checkRes = -1
|
|
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
|
-
|
|
204
|
-
|
|
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()
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
return ''
|
|
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('没有匹配到证书!')
|
|
221
219
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
220
|
+
return ''
|
|
221
|
+
}
|
|
222
|
+
// 签名
|
|
223
|
+
await MessageBox.prompt('请输入PIN码', '提示', {
|
|
224
|
+
confirmButtonText: '确定',
|
|
225
|
+
cancelButtonText: '取消',
|
|
226
|
+
inputType: 'password'
|
|
227
|
+
})
|
|
228
|
+
.then(({ value }) => {
|
|
229
|
+
return performSign(plainText, value).then((signedData) => {
|
|
230
|
+
answer = signedData
|
|
231
|
+
})
|
|
232
|
+
})
|
|
233
|
+
.catch(() => {
|
|
234
|
+
resolve()
|
|
233
235
|
})
|
|
234
|
-
|
|
236
|
+
return answer
|
|
235
237
|
}
|
|
236
238
|
|
|
237
239
|
export async function getCertInfo(dn) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
240
|
+
return new Promise((resolve, reject) => {
|
|
241
|
+
// 获取证书列表
|
|
242
|
+
IWSASkfGetCertList(
|
|
243
|
+
process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'ShuttleCsp11_3000GM.dll',
|
|
244
|
+
(CertListData, errorCode) => {
|
|
245
|
+
if (errorCode) {
|
|
246
|
+
Message.error(codeDate[errorCode])
|
|
247
|
+
reject()
|
|
248
|
+
} else {
|
|
249
|
+
const checkRes = verifyDn(CertListData, dn)
|
|
250
|
+
resolve(checkRes)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
)
|
|
254
|
+
})
|
|
253
255
|
}
|
|
254
256
|
|
|
255
|
-
|
|
256
257
|
async function performSign(plainText, value) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
})
|
|
258
|
+
return new Promise((resolve, reject) => {
|
|
259
|
+
IWSASkfDetachedSign(plainText, 0, value, 'SM3', (errorCode, signedData) => {
|
|
260
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
261
|
+
resolve(signedData)
|
|
262
|
+
} else {
|
|
263
|
+
Message.error(codeDate[errorCode])
|
|
264
|
+
reject()
|
|
265
|
+
}
|
|
266
266
|
})
|
|
267
|
+
})
|
|
267
268
|
}
|
|
268
269
|
|
|
269
|
-
|
|
270
270
|
/* 签名解签 */
|
|
271
271
|
export async function verifySign(signedMsg) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
})
|
|
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
|
+
}
|
|
283
282
|
})
|
|
283
|
+
})
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
return Promise.resolve(plainText)
|
|
286
286
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Message, MessageBox, Notification } from 'element-ui'
|
|
2
|
+
import { IWSAgent } from './InfosecNetSignCNGAgent.min.js'
|
|
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,217 +22,216 @@ 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 = 0
|
|
172
|
+
let userDnAttrsArr = dn.split(',').map((c) => c.trim())
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
if (!isIn) {
|
|
182
|
-
checkRes = 'checkRes'
|
|
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)
|
|
183
179
|
}
|
|
180
|
+
})
|
|
181
|
+
if (!isIn) {
|
|
182
|
+
checkRes = -1
|
|
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
|
-
let plainText = ''
|
|
199
|
-
if (typeof plain === 'object') {
|
|
200
|
-
plainText = JSON.stringify(plain)
|
|
201
|
-
} else {
|
|
202
|
-
plainText = plain
|
|
203
|
-
}
|
|
204
|
-
const checkRes = await getCertInfo(dn)
|
|
190
|
+
if (dn === undefined) {
|
|
191
|
+
dn = getDN()
|
|
192
|
+
}
|
|
193
|
+
if (!dn) {
|
|
194
|
+
Message.error('签名参数DN错误!')
|
|
195
|
+
return false
|
|
196
|
+
}
|
|
205
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)
|
|
206
205
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
return ''
|
|
206
|
+
if (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('没有匹配到证书!')
|
|
222
219
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
220
|
+
return ''
|
|
221
|
+
}
|
|
222
|
+
let answer
|
|
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
|
|
232
230
|
})
|
|
233
|
-
|
|
231
|
+
})
|
|
232
|
+
// 签名
|
|
234
233
|
|
|
235
|
-
|
|
234
|
+
return answer
|
|
236
235
|
}
|
|
237
236
|
|
|
238
237
|
/**
|
|
@@ -241,21 +240,21 @@ export async function getSign(plain, dn) {
|
|
|
241
240
|
* @returns {Promise<*>}
|
|
242
241
|
*/
|
|
243
242
|
export async function getCertInfo(dn) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
243
|
+
return new Promise((resolve, reject) => {
|
|
244
|
+
// 获取证书列表
|
|
245
|
+
IWSASkfGetCertList(
|
|
246
|
+
process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'WTSKFInterface.dll',
|
|
247
|
+
(CertListData, errorCode) => {
|
|
248
|
+
if (errorCode) {
|
|
249
|
+
Message.error(codeDate[errorCode])
|
|
250
|
+
reject()
|
|
251
|
+
} else {
|
|
252
|
+
const checkRes = verifyDn(CertListData, dn)
|
|
253
|
+
resolve(checkRes)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
)
|
|
257
|
+
})
|
|
259
258
|
}
|
|
260
259
|
|
|
261
260
|
/**
|
|
@@ -265,35 +264,34 @@ export async function getCertInfo(dn) {
|
|
|
265
264
|
* @returns {Promise<*>}
|
|
266
265
|
*/
|
|
267
266
|
async function performSign(plainText, value) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
resolve()
|
|
279
|
-
})
|
|
267
|
+
return new Promise((resolve, reject) => {
|
|
268
|
+
IWSASkfSignData(plainText, 0, value, 'SM3', (errorCode, signedData) => {
|
|
269
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
270
|
+
resolve(signedData)
|
|
271
|
+
} else {
|
|
272
|
+
Message.error(codeDate[errorCode])
|
|
273
|
+
reject()
|
|
274
|
+
}
|
|
275
|
+
}).catch(() => {
|
|
276
|
+
resolve()
|
|
280
277
|
})
|
|
278
|
+
})
|
|
281
279
|
}
|
|
282
280
|
|
|
283
281
|
/* 签名解签 */
|
|
284
282
|
export async function verifySign(signedMsg) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
})
|
|
283
|
+
let plainText
|
|
284
|
+
await new Promise((resolve, reject) => {
|
|
285
|
+
IWSASkfVerifySignData(signedMsg, (errorCode, PlainText, certDN) => {
|
|
286
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
287
|
+
plainText = PlainText
|
|
288
|
+
resolve()
|
|
289
|
+
} else {
|
|
290
|
+
Message.error(codeDate[errorCode])
|
|
291
|
+
reject()
|
|
292
|
+
}
|
|
296
293
|
})
|
|
294
|
+
})
|
|
297
295
|
|
|
298
|
-
|
|
296
|
+
return Promise.resolve(plainText)
|
|
299
297
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import importG from '../../utils/importGlobal.js'
|
|
2
2
|
|
|
3
3
|
import CaMap from './CaMap.js'
|
|
4
|
-
import { getCertInfo } from
|
|
5
|
-
import {getCertInfo as SkfSign } from './SkfSign/index'
|
|
6
|
-
import
|
|
4
|
+
import { getCertInfo as NetSM3 } from './NetSM3/index'
|
|
5
|
+
import { getCertInfo as SkfSign } from './SkfSign/index'
|
|
6
|
+
import { getCertInfo } from './sign'
|
|
7
7
|
export async function getSign(p1, p2, p3) {
|
|
8
8
|
let signType = window.sessionStorage.getItem('signType')
|
|
9
9
|
if (!signType || !CaMap[signType]) {
|
|
@@ -110,11 +110,12 @@ export async function getSign(p1, p2, p3) {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
export function getCert(dn) {
|
|
113
|
+
let signType = window.sessionStorage.getItem('signType')
|
|
113
114
|
if (signType === 'inetSign' /* 信安CA */) {
|
|
114
115
|
return getCertInfo(dn)
|
|
115
116
|
} else if (signType === 'SkfSign') {
|
|
116
|
-
return
|
|
117
|
+
return SkfSign(dn)
|
|
117
118
|
} else if (signType === 'NetSM3') {
|
|
118
|
-
return
|
|
119
|
+
return NetSM3(dn)
|
|
119
120
|
}
|
|
120
121
|
}
|