n20-common-lib 2.22.17 → 2.22.18
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/components/ApprovalButtons/showOtherAttrNew.vue +16 -17
- package/src/components/HandlingAdvice/index.vue +5 -0
- package/src/plugins/Sign/signV3/sign.js +281 -281
- package/theme/blue.css +1 -1
- package/theme/cctcRed.css +1 -1
- package/theme/green.css +1 -1
- package/theme/lightBlue.css +1 -1
- package/theme/orange.css +1 -1
- package/theme/purple.css +1 -1
- package/theme/red.css +1 -1
- package/theme/yellow.css +1 -1
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
class="w-100p flex-box"
|
|
4
|
-
style="
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
gap: 16px
|
|
9
|
-
padding: 0
|
|
10
|
-
|
|
11
|
-
"
|
|
4
|
+
:style="{
|
|
5
|
+
display: 'grid',
|
|
6
|
+
flexWrap: 'wrap',
|
|
7
|
+
gridTemplateColumns: `repeat(${columns}, 1fr)`,
|
|
8
|
+
gap: '16px',
|
|
9
|
+
padding: '0',
|
|
10
|
+
overflowX: 'hidden'
|
|
11
|
+
}"
|
|
12
12
|
>
|
|
13
|
-
<div v-for="(item, i) in otherAttData" :key="i" class="flex-box
|
|
13
|
+
<div v-for="(item, i) in otherAttData" :key="i" class="flex-box" style="width: 100%; padding: 0 20px">
|
|
14
14
|
<el-form-item
|
|
15
15
|
class="m-r-ss m-b-s"
|
|
16
16
|
:label-width="labelWidth"
|
|
@@ -20,12 +20,7 @@
|
|
|
20
20
|
<span slot="label">
|
|
21
21
|
<span
|
|
22
22
|
v-title="item.cfgName"
|
|
23
|
-
style="
|
|
24
|
-
display: inline-block;
|
|
25
|
-
white-space: nowrap;
|
|
26
|
-
overflow: hidden;
|
|
27
|
-
text-overflow: ellipsis;
|
|
28
|
-
"
|
|
23
|
+
style="display: inline-block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis"
|
|
29
24
|
:style="{ maxWidth: labelWidth }"
|
|
30
25
|
>
|
|
31
26
|
<span v-if="required" style="color: red">*</span>
|
|
@@ -93,13 +88,13 @@
|
|
|
93
88
|
v-model="item.cfgVal"
|
|
94
89
|
:type="'textarea'"
|
|
95
90
|
placeholder="请输入"
|
|
96
|
-
class="w-100p m-r-
|
|
91
|
+
class="w-100p m-r-s m-b-s flex-1"
|
|
97
92
|
clearable
|
|
98
93
|
/>
|
|
99
94
|
<el-input
|
|
100
95
|
v-if="item.cfgHasRemark === '1' && !['11', '12'].includes(item.cfgType)"
|
|
101
96
|
v-model="item.cfgRemark"
|
|
102
|
-
class="w-100p m-r-
|
|
97
|
+
class="w-100p m-r-lg m-b-s flex-1"
|
|
103
98
|
placeholder="请输入备注"
|
|
104
99
|
/>
|
|
105
100
|
</div>
|
|
@@ -118,6 +113,10 @@ export default {
|
|
|
118
113
|
type: [String, Number],
|
|
119
114
|
default: ''
|
|
120
115
|
},
|
|
116
|
+
columns: {
|
|
117
|
+
type: Number,
|
|
118
|
+
default: 1
|
|
119
|
+
},
|
|
121
120
|
form: {
|
|
122
121
|
type: Object,
|
|
123
122
|
default: () => ({})
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
:other-att-data-a="otherAttDataA"
|
|
45
45
|
:proc-inst-id="procInstId || this.$route.query.processInstanceId"
|
|
46
46
|
:required="true"
|
|
47
|
+
:columns="columns"
|
|
47
48
|
:label-width="labelWidth"
|
|
48
49
|
/>
|
|
49
50
|
</div>
|
|
@@ -74,6 +75,10 @@ export default {
|
|
|
74
75
|
type: String,
|
|
75
76
|
default: '12em'
|
|
76
77
|
},
|
|
78
|
+
columns: {
|
|
79
|
+
type: Number,
|
|
80
|
+
default: 1
|
|
81
|
+
},
|
|
77
82
|
afterGetConf: {
|
|
78
83
|
type: Function,
|
|
79
84
|
default: undefined
|
|
@@ -1,281 +1,281 @@
|
|
|
1
|
-
// Attached方式签名
|
|
2
|
-
import { Message, MessageBox,Notification } from 'element-ui'
|
|
3
|
-
import { IWSAgent } from './InfosecNetSignCNGAgent.min.js'
|
|
4
|
-
|
|
5
|
-
const {
|
|
6
|
-
IWSASetTimeOut,
|
|
7
|
-
IWSADetachedSign,
|
|
8
|
-
IWSAAttachedVerify,
|
|
9
|
-
IWSASendAvailable,
|
|
10
|
-
IWSAGetAvailable,
|
|
11
|
-
IWSAGetAllCertsListInfo,
|
|
12
|
-
IWSASkfGetCertList,
|
|
13
|
-
IWSASkfDetachedSignDefaultDN
|
|
14
|
-
} = new IWSAgent()
|
|
15
|
-
IWSASetTimeOut(6000)
|
|
16
|
-
let certIndex = 0
|
|
17
|
-
let certDN = ''
|
|
18
|
-
let certType='SHA1'
|
|
19
|
-
function getDN() {
|
|
20
|
-
let dn
|
|
21
|
-
let userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
|
|
22
|
-
if (userInfo && userInfo.dn) {
|
|
23
|
-
dn = userInfo.dn
|
|
24
|
-
}
|
|
25
|
-
return dn
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/* 检测本地签名端口是否可用 */
|
|
29
|
-
export function availableSign(fn, url) {
|
|
30
|
-
let available = IWSAGetAvailable()
|
|
31
|
-
if (available) {
|
|
32
|
-
fn && fn(available)
|
|
33
|
-
} else {
|
|
34
|
-
IWSASendAvailable()
|
|
35
|
-
let count = 0
|
|
36
|
-
checkAvailable(fn, url, count)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function checkAvailable(fn, url, count) {
|
|
41
|
-
let name = window.NetSignDownloadName || 'NetSignCNG签名助手'
|
|
42
|
-
let available = IWSAGetAvailable()
|
|
43
|
-
if (available) {
|
|
44
|
-
fn && fn(available)
|
|
45
|
-
} else if (count == 10) {
|
|
46
|
-
fn && fn(available)
|
|
47
|
-
Notification({
|
|
48
|
-
title: '提示',
|
|
49
|
-
dangerouslyUseHTMLString: true,
|
|
50
|
-
message: `<div>检测到您的电脑中没有安装签名助手,为了不影响使用请使用管理员权限<a class="color-primary" href="${url}" download>下载安装</a>${name}</div>`,
|
|
51
|
-
duration: 5000
|
|
52
|
-
})
|
|
53
|
-
} else {
|
|
54
|
-
count++
|
|
55
|
-
setTimeout(() => {
|
|
56
|
-
checkAvailable(fn, url, count)
|
|
57
|
-
}, 200)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* 签名解签函数
|
|
63
|
-
* @param {string} signedMsg 要解签的密文
|
|
64
|
-
* @returns {string} 解签后的明文
|
|
65
|
-
*/
|
|
66
|
-
export function verifySign(signedMsg) {
|
|
67
|
-
let plainText
|
|
68
|
-
IWSAAttachedVerify('1', signedMsg, (errorCode, PlainText) => {
|
|
69
|
-
if (errorCode === 0 || errorCode === '0') {
|
|
70
|
-
plainText = PlainText
|
|
71
|
-
} else {
|
|
72
|
-
Message.error('签名解签失败!')
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
return plainText
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* 签名函数
|
|
80
|
-
* @param {string} plain 要签名的明文
|
|
81
|
-
* @param {string} dn 用户对应的Dn
|
|
82
|
-
* @returns {Promise<string>} 签名后的密文信息
|
|
83
|
-
*/
|
|
84
|
-
export async function getSign(plain, dn) {
|
|
85
|
-
let index = await getCertInfo(dn)
|
|
86
|
-
if (index === -1) return
|
|
87
|
-
let plainText = typeof plain === 'object' ? JSON.stringify(plain) : plain
|
|
88
|
-
if (
|
|
89
|
-
navigator.platform.toLowerCase().includes('linux') ||
|
|
90
|
-
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
91
|
-
// 检查是否为银河麒麟特有的环境变量或特征
|
|
92
|
-
typeof window.KylinOS !== 'undefined' ||
|
|
93
|
-
document.documentElement.dataset.osType === 'kylin'||certType==='SM3'
|
|
94
|
-
) {
|
|
95
|
-
// 签名
|
|
96
|
-
return await MessageBox.prompt('请输入PIN码', '提示', {
|
|
97
|
-
confirmButtonText: '确定',
|
|
98
|
-
cancelButtonText: '取消',
|
|
99
|
-
closeOnClickModal: false,
|
|
100
|
-
inputType: 'password'
|
|
101
|
-
}).then(({ value }) => {
|
|
102
|
-
return performSignSkf(plainText, value)
|
|
103
|
-
})
|
|
104
|
-
}else{
|
|
105
|
-
return await performSign(plainText, index)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* 获取证书信息
|
|
112
|
-
* @param {string} dn 要验证的Dn
|
|
113
|
-
* @returns {Promise} - 解析后的证书信息
|
|
114
|
-
*/
|
|
115
|
-
export function getCertInfo(dn) {
|
|
116
|
-
if (dn === undefined) {
|
|
117
|
-
dn = getDN()
|
|
118
|
-
}
|
|
119
|
-
if (!dn) {
|
|
120
|
-
Message.error('没有获取到签名参数DN!')
|
|
121
|
-
return false
|
|
122
|
-
}
|
|
123
|
-
if (
|
|
124
|
-
navigator.platform.toLowerCase().includes('linux') ||
|
|
125
|
-
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
126
|
-
// 检查是否为银河麒麟特有的环境变量或特征
|
|
127
|
-
typeof window.KylinOS !== 'undefined' ||
|
|
128
|
-
document.documentElement.dataset.osType === 'kylin'
|
|
129
|
-
) {
|
|
130
|
-
return getCertInfoSkf(dn)
|
|
131
|
-
}
|
|
132
|
-
return new Promise((resolve, reject) => {
|
|
133
|
-
let certInfo
|
|
134
|
-
IWSAGetAllCertsListInfo('infosec.sm2', 'Sign', 0, (dnList) => {
|
|
135
|
-
if (!dn) {
|
|
136
|
-
Message.error('没有获取到签名参数DN!')
|
|
137
|
-
reject()
|
|
138
|
-
}
|
|
139
|
-
if (!dnList) {
|
|
140
|
-
Message.error('没有获取到证书列表!')
|
|
141
|
-
reject()
|
|
142
|
-
}
|
|
143
|
-
if (dnList.length === 0) {
|
|
144
|
-
Message.error('用户证书信息与当前用户不匹配!')
|
|
145
|
-
reject()
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
certInfo = verifyDn(dnList, dn)
|
|
149
|
-
resolve(certInfo)
|
|
150
|
-
})
|
|
151
|
-
})
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* 获取证书信息
|
|
156
|
-
* @param dn
|
|
157
|
-
* @returns {Promise<*>}
|
|
158
|
-
*/
|
|
159
|
-
export async function getCertInfoSkf(dn) {
|
|
160
|
-
return new Promise((resolve, reject) => {
|
|
161
|
-
let arg
|
|
162
|
-
if (
|
|
163
|
-
navigator.platform.toLowerCase().includes('linux') ||
|
|
164
|
-
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
165
|
-
// 检查是否为银河麒麟特有的环境变量或特征
|
|
166
|
-
typeof window.KylinOS !== 'undefined' ||
|
|
167
|
-
document.documentElement.dataset.osType === 'kylin'
|
|
168
|
-
) {
|
|
169
|
-
arg = window.VUE_APP_NetSign_ARG_Linux
|
|
170
|
-
} else {
|
|
171
|
-
arg = process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'WTSKFInterface.dll'
|
|
172
|
-
}
|
|
173
|
-
// 获取证书列表
|
|
174
|
-
IWSASkfGetCertList(arg, (CertListData, errorCode) => {
|
|
175
|
-
if (errorCode) {
|
|
176
|
-
Message.error(codeDate[errorCode])
|
|
177
|
-
reject()
|
|
178
|
-
} else {
|
|
179
|
-
const checkRes = verifyDn(CertListData, dn)
|
|
180
|
-
resolve(checkRes)
|
|
181
|
-
}
|
|
182
|
-
})
|
|
183
|
-
})
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* 执行签名函数
|
|
188
|
-
* @param {string} plain 要签名的明文
|
|
189
|
-
* @param index 签名的证书索引
|
|
190
|
-
* @returns {Promise<string>} 签名后的密文信息
|
|
191
|
-
*/
|
|
192
|
-
export async function performSign(plain, index) {
|
|
193
|
-
return new Promise((resolve, reject) => {
|
|
194
|
-
IWSADetachedSign(2, plain, certIndex, certType, (errorCode, signedData) => {
|
|
195
|
-
if (errorCode === 0 || errorCode === '0') {
|
|
196
|
-
resolve(signedData)
|
|
197
|
-
} else {
|
|
198
|
-
Message.error('签名失败!')
|
|
199
|
-
reject(errorCode)
|
|
200
|
-
}
|
|
201
|
-
})
|
|
202
|
-
})
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
async function performSignSkf(plainText, value) {
|
|
206
|
-
return new Promise((resolve, reject) => {
|
|
207
|
-
let arg
|
|
208
|
-
if (
|
|
209
|
-
navigator.platform.toLowerCase().includes('linux') ||
|
|
210
|
-
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
211
|
-
// 检查是否为银河麒麟特有的环境变量或特征
|
|
212
|
-
typeof window.KylinOS !== 'undefined' ||
|
|
213
|
-
document.documentElement.dataset.osType === 'kylin'
|
|
214
|
-
) {
|
|
215
|
-
arg = window.VUE_APP_NetSign_ARG_Linux
|
|
216
|
-
} else {
|
|
217
|
-
arg = process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'WTSKFInterface.dll'
|
|
218
|
-
}
|
|
219
|
-
IWSASkfDetachedSignDefaultDN(plainText, certDN, value, certType,arg,'1', (errorCode, signedData) => {
|
|
220
|
-
if (errorCode === 0 || errorCode === '0') {
|
|
221
|
-
resolve(signedData)
|
|
222
|
-
} else {
|
|
223
|
-
Message.error('签名失败!')
|
|
224
|
-
reject()
|
|
225
|
-
}
|
|
226
|
-
})
|
|
227
|
-
})
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* 验证Dn是否存在于Dn列表中
|
|
232
|
-
* @param {Array} dnList 获取到的Dn列表
|
|
233
|
-
* @param {string} dn 要验证的Dn
|
|
234
|
-
* @returns {number} - 如果找到匹配的 DN,则返回其在 dnList 中的索引;如果未找到,则返回 -1
|
|
235
|
-
*/
|
|
236
|
-
function verifyDn(dnList, dn) {
|
|
237
|
-
let userDnAttrsArr = dn.split(',').map((c) => c.trim())
|
|
238
|
-
let index = -1
|
|
239
|
-
// 先过滤满足证书的条件
|
|
240
|
-
let dnListA = JSON.parse(JSON.stringify(dnList)).filter((C, i) => {
|
|
241
|
-
let dnAttrsArr = C.certDN.split(',').map((c) => c.trim())
|
|
242
|
-
if (dnAttrsArr.every((dnAttr) => userDnAttrsArr.includes(dnAttr))) {
|
|
243
|
-
C.index = i
|
|
244
|
-
certDN = C.certDN
|
|
245
|
-
return C
|
|
246
|
-
}
|
|
247
|
-
})
|
|
248
|
-
console.log(dnListA)
|
|
249
|
-
if (dnListA.length > 0) {
|
|
250
|
-
for (let i = 0; i < dnListA.length; i++) {
|
|
251
|
-
if (dnListA[i].CertType === 'SM2' && dnListA[i].KeyUsage === 'signature') {
|
|
252
|
-
index = dnListA[i].index
|
|
253
|
-
certIndex = dnListA[i].index
|
|
254
|
-
certType = 'SM3'
|
|
255
|
-
break
|
|
256
|
-
} else {
|
|
257
|
-
index = -1
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (index === -1) {
|
|
262
|
-
if (dnListA.length > 0) {
|
|
263
|
-
for (let i = 0; i < dnListA.length; i++) {
|
|
264
|
-
if (dnListA[i].CertType === 'RSA') {
|
|
265
|
-
index = dnListA[i].index
|
|
266
|
-
certIndex = dnListA[i].index
|
|
267
|
-
certType = 'SHA1'
|
|
268
|
-
break
|
|
269
|
-
} else {
|
|
270
|
-
index = -1
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
if (index === -1) {
|
|
276
|
-
let dnListB = dnList?.map((res) => res.certDN)?.join(',')
|
|
277
|
-
Message.error(`证书Dn不匹配:${dnListB}里面无法匹配===>${dn}`)
|
|
278
|
-
return index
|
|
279
|
-
}
|
|
280
|
-
return index
|
|
281
|
-
}
|
|
1
|
+
// Attached方式签名
|
|
2
|
+
import { Message, MessageBox,Notification } from 'element-ui'
|
|
3
|
+
import { IWSAgent } from './InfosecNetSignCNGAgent.min.js'
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
IWSASetTimeOut,
|
|
7
|
+
IWSADetachedSign,
|
|
8
|
+
IWSAAttachedVerify,
|
|
9
|
+
IWSASendAvailable,
|
|
10
|
+
IWSAGetAvailable,
|
|
11
|
+
IWSAGetAllCertsListInfo,
|
|
12
|
+
IWSASkfGetCertList,
|
|
13
|
+
IWSASkfDetachedSignDefaultDN
|
|
14
|
+
} = new IWSAgent()
|
|
15
|
+
IWSASetTimeOut(6000)
|
|
16
|
+
let certIndex = 0
|
|
17
|
+
let certDN = ''
|
|
18
|
+
let certType='SHA1'
|
|
19
|
+
function getDN() {
|
|
20
|
+
let dn
|
|
21
|
+
let userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
|
|
22
|
+
if (userInfo && userInfo.dn) {
|
|
23
|
+
dn = userInfo.dn
|
|
24
|
+
}
|
|
25
|
+
return dn
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* 检测本地签名端口是否可用 */
|
|
29
|
+
export function availableSign(fn, url) {
|
|
30
|
+
let available = IWSAGetAvailable()
|
|
31
|
+
if (available) {
|
|
32
|
+
fn && fn(available)
|
|
33
|
+
} else {
|
|
34
|
+
IWSASendAvailable()
|
|
35
|
+
let count = 0
|
|
36
|
+
checkAvailable(fn, url, count)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function checkAvailable(fn, url, count) {
|
|
41
|
+
let name = window.NetSignDownloadName || 'NetSignCNG签名助手'
|
|
42
|
+
let available = IWSAGetAvailable()
|
|
43
|
+
if (available) {
|
|
44
|
+
fn && fn(available)
|
|
45
|
+
} else if (count == 10) {
|
|
46
|
+
fn && fn(available)
|
|
47
|
+
Notification({
|
|
48
|
+
title: '提示',
|
|
49
|
+
dangerouslyUseHTMLString: true,
|
|
50
|
+
message: `<div>检测到您的电脑中没有安装签名助手,为了不影响使用请使用管理员权限<a class="color-primary" href="${url}" download>下载安装</a>${name}</div>`,
|
|
51
|
+
duration: 5000
|
|
52
|
+
})
|
|
53
|
+
} else {
|
|
54
|
+
count++
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
checkAvailable(fn, url, count)
|
|
57
|
+
}, 200)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 签名解签函数
|
|
63
|
+
* @param {string} signedMsg 要解签的密文
|
|
64
|
+
* @returns {string} 解签后的明文
|
|
65
|
+
*/
|
|
66
|
+
export function verifySign(signedMsg) {
|
|
67
|
+
let plainText
|
|
68
|
+
IWSAAttachedVerify('1', signedMsg, (errorCode, PlainText) => {
|
|
69
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
70
|
+
plainText = PlainText
|
|
71
|
+
} else {
|
|
72
|
+
Message.error('签名解签失败!')
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
return plainText
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 签名函数
|
|
80
|
+
* @param {string} plain 要签名的明文
|
|
81
|
+
* @param {string} dn 用户对应的Dn
|
|
82
|
+
* @returns {Promise<string>} 签名后的密文信息
|
|
83
|
+
*/
|
|
84
|
+
export async function getSign(plain, dn) {
|
|
85
|
+
let index = await getCertInfo(dn)
|
|
86
|
+
if (index === -1) return
|
|
87
|
+
let plainText = typeof plain === 'object' ? JSON.stringify(plain) : plain
|
|
88
|
+
if (
|
|
89
|
+
navigator.platform.toLowerCase().includes('linux') ||
|
|
90
|
+
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
91
|
+
// 检查是否为银河麒麟特有的环境变量或特征
|
|
92
|
+
typeof window.KylinOS !== 'undefined' ||
|
|
93
|
+
document.documentElement.dataset.osType === 'kylin'||certType==='SM3'
|
|
94
|
+
) {
|
|
95
|
+
// 签名
|
|
96
|
+
return await MessageBox.prompt('请输入PIN码', '提示', {
|
|
97
|
+
confirmButtonText: '确定',
|
|
98
|
+
cancelButtonText: '取消',
|
|
99
|
+
closeOnClickModal: false,
|
|
100
|
+
inputType: 'password'
|
|
101
|
+
}).then(({ value }) => {
|
|
102
|
+
return performSignSkf(plainText, value)
|
|
103
|
+
})
|
|
104
|
+
}else{
|
|
105
|
+
return await performSign(plainText, index)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 获取证书信息
|
|
112
|
+
* @param {string} dn 要验证的Dn
|
|
113
|
+
* @returns {Promise} - 解析后的证书信息
|
|
114
|
+
*/
|
|
115
|
+
export function getCertInfo(dn) {
|
|
116
|
+
if (dn === undefined) {
|
|
117
|
+
dn = getDN()
|
|
118
|
+
}
|
|
119
|
+
if (!dn) {
|
|
120
|
+
Message.error('没有获取到签名参数DN!')
|
|
121
|
+
return false
|
|
122
|
+
}
|
|
123
|
+
if (
|
|
124
|
+
navigator.platform.toLowerCase().includes('linux') ||
|
|
125
|
+
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
126
|
+
// 检查是否为银河麒麟特有的环境变量或特征
|
|
127
|
+
typeof window.KylinOS !== 'undefined' ||
|
|
128
|
+
document.documentElement.dataset.osType === 'kylin'
|
|
129
|
+
) {
|
|
130
|
+
return getCertInfoSkf(dn)
|
|
131
|
+
}
|
|
132
|
+
return new Promise((resolve, reject) => {
|
|
133
|
+
let certInfo
|
|
134
|
+
IWSAGetAllCertsListInfo('infosec.sm2', 'Sign', 0, (dnList) => {
|
|
135
|
+
if (!dn) {
|
|
136
|
+
Message.error('没有获取到签名参数DN!')
|
|
137
|
+
reject()
|
|
138
|
+
}
|
|
139
|
+
if (!dnList) {
|
|
140
|
+
Message.error('没有获取到证书列表!')
|
|
141
|
+
reject()
|
|
142
|
+
}
|
|
143
|
+
if (dnList.length === 0) {
|
|
144
|
+
Message.error('用户证书信息与当前用户不匹配!')
|
|
145
|
+
reject()
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
certInfo = verifyDn(dnList, dn)
|
|
149
|
+
resolve(certInfo)
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 获取证书信息
|
|
156
|
+
* @param dn
|
|
157
|
+
* @returns {Promise<*>}
|
|
158
|
+
*/
|
|
159
|
+
export async function getCertInfoSkf(dn) {
|
|
160
|
+
return new Promise((resolve, reject) => {
|
|
161
|
+
let arg
|
|
162
|
+
if (
|
|
163
|
+
navigator.platform.toLowerCase().includes('linux') ||
|
|
164
|
+
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
165
|
+
// 检查是否为银河麒麟特有的环境变量或特征
|
|
166
|
+
typeof window.KylinOS !== 'undefined' ||
|
|
167
|
+
document.documentElement.dataset.osType === 'kylin'
|
|
168
|
+
) {
|
|
169
|
+
arg = window.VUE_APP_NetSign_ARG_Linux
|
|
170
|
+
} else {
|
|
171
|
+
arg = process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'WTSKFInterface.dll'
|
|
172
|
+
}
|
|
173
|
+
// 获取证书列表
|
|
174
|
+
IWSASkfGetCertList(arg, (CertListData, errorCode) => {
|
|
175
|
+
if (errorCode) {
|
|
176
|
+
Message.error(codeDate[errorCode])
|
|
177
|
+
reject()
|
|
178
|
+
} else {
|
|
179
|
+
const checkRes = verifyDn(CertListData, dn)
|
|
180
|
+
resolve(checkRes)
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 执行签名函数
|
|
188
|
+
* @param {string} plain 要签名的明文
|
|
189
|
+
* @param index 签名的证书索引
|
|
190
|
+
* @returns {Promise<string>} 签名后的密文信息
|
|
191
|
+
*/
|
|
192
|
+
export async function performSign(plain, index) {
|
|
193
|
+
return new Promise((resolve, reject) => {
|
|
194
|
+
IWSADetachedSign(2, plain, certIndex, certType, (errorCode, signedData) => {
|
|
195
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
196
|
+
resolve(signedData)
|
|
197
|
+
} else {
|
|
198
|
+
Message.error('签名失败!')
|
|
199
|
+
reject(errorCode)
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async function performSignSkf(plainText, value) {
|
|
206
|
+
return new Promise((resolve, reject) => {
|
|
207
|
+
let arg
|
|
208
|
+
if (
|
|
209
|
+
navigator.platform.toLowerCase().includes('linux') ||
|
|
210
|
+
navigator.userAgent.toLowerCase().includes('linux') ||
|
|
211
|
+
// 检查是否为银河麒麟特有的环境变量或特征
|
|
212
|
+
typeof window.KylinOS !== 'undefined' ||
|
|
213
|
+
document.documentElement.dataset.osType === 'kylin'
|
|
214
|
+
) {
|
|
215
|
+
arg = window.VUE_APP_NetSign_ARG_Linux
|
|
216
|
+
} else {
|
|
217
|
+
arg = process.env.VUE_APP_NetSign_ARG || window.VUE_APP_NetSign_ARG || 'WTSKFInterface.dll'
|
|
218
|
+
}
|
|
219
|
+
IWSASkfDetachedSignDefaultDN(plainText, certDN, value, certType,arg,'1', (errorCode, signedData) => {
|
|
220
|
+
if (errorCode === 0 || errorCode === '0') {
|
|
221
|
+
resolve(signedData)
|
|
222
|
+
} else {
|
|
223
|
+
Message.error('签名失败!')
|
|
224
|
+
reject()
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* 验证Dn是否存在于Dn列表中
|
|
232
|
+
* @param {Array} dnList 获取到的Dn列表
|
|
233
|
+
* @param {string} dn 要验证的Dn
|
|
234
|
+
* @returns {number} - 如果找到匹配的 DN,则返回其在 dnList 中的索引;如果未找到,则返回 -1
|
|
235
|
+
*/
|
|
236
|
+
function verifyDn(dnList, dn) {
|
|
237
|
+
let userDnAttrsArr = dn.split(',').map((c) => c.trim())
|
|
238
|
+
let index = -1
|
|
239
|
+
// 先过滤满足证书的条件
|
|
240
|
+
let dnListA = JSON.parse(JSON.stringify(dnList)).filter((C, i) => {
|
|
241
|
+
let dnAttrsArr = C.certDN.split(',').map((c) => c.trim())
|
|
242
|
+
if (dnAttrsArr.every((dnAttr) => userDnAttrsArr.includes(dnAttr))) {
|
|
243
|
+
C.index = i
|
|
244
|
+
certDN = C.certDN
|
|
245
|
+
return C
|
|
246
|
+
}
|
|
247
|
+
})
|
|
248
|
+
console.log(dnListA)
|
|
249
|
+
if (dnListA.length > 0) {
|
|
250
|
+
for (let i = 0; i < dnListA.length; i++) {
|
|
251
|
+
if (dnListA[i].CertType === 'SM2' && dnListA[i].KeyUsage === 'signature') {
|
|
252
|
+
index = dnListA[i].index
|
|
253
|
+
certIndex = dnListA[i].index
|
|
254
|
+
certType = 'SM3'
|
|
255
|
+
break
|
|
256
|
+
} else {
|
|
257
|
+
index = -1
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (index === -1) {
|
|
262
|
+
if (dnListA.length > 0) {
|
|
263
|
+
for (let i = 0; i < dnListA.length; i++) {
|
|
264
|
+
if (dnListA[i].CertType === 'RSA') {
|
|
265
|
+
index = dnListA[i].index
|
|
266
|
+
certIndex = dnListA[i].index
|
|
267
|
+
certType = 'SHA1'
|
|
268
|
+
break
|
|
269
|
+
} else {
|
|
270
|
+
index = -1
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (index === -1) {
|
|
276
|
+
let dnListB = dnList?.map((res) => res.certDN)?.join(',')
|
|
277
|
+
Message.error(`证书Dn不匹配:${dnListB}里面无法匹配===>${dn}`)
|
|
278
|
+
return index
|
|
279
|
+
}
|
|
280
|
+
return index
|
|
281
|
+
}
|