@it-enterprise/digital-signature 1.0.1 → 1.1.5
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/.eslintrc.js +14 -3
- package/euscp/EndUserConstants.d.ts +50 -0
- package/euscp/euscp.d.ts +90 -1
- package/euscp/euscp.js +2 -2
- package/package.json +1 -1
- package/readme.md +30 -0
- package/src/DigitalSignature.js +230 -66
- package/src/GlSign.js +1 -4
- package/src/Models.js +80 -15
- package/.gitlab-ci.yml +0 -12
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -102,6 +102,7 @@ import auth from '@it-enterprise/jwtauthentication';
|
|
|
102
102
|
const ds = new DigitalSignature(
|
|
103
103
|
new Models.GraphQlSettingProvider(
|
|
104
104
|
"uk", // Язык ошибок
|
|
105
|
+
userId, // id пользователя (для сохранения ключей и предпочитаемого типа ключа)
|
|
105
106
|
"https://m.it.ua/GraphQlServer/", // Адрес сервера GraphQl
|
|
106
107
|
"https://m.it.ua/ws/", // Адрес веб-сервисов
|
|
107
108
|
auth) // Библиотека @it-enterprise/jwtauthentication
|
|
@@ -115,6 +116,7 @@ await ds.initialise();
|
|
|
115
116
|
const ds = new DigitalSignature(
|
|
116
117
|
new Models.DefaultSettingProvider(
|
|
117
118
|
"uk", // Язык ошибок
|
|
119
|
+
userId, // id пользователя (для сохранения ключей и предпочитаемого типа ключа)
|
|
118
120
|
location.pathname + "api/ds/", // Путь к API ЕЦП
|
|
119
121
|
glSign) // Значение глобального параметра GlSign в виде строки или обьекта Models.GlSign
|
|
120
122
|
);
|
|
@@ -222,6 +224,34 @@ const keyInfo = await ds.readPrivateKeyKSP(
|
|
|
222
224
|
false);
|
|
223
225
|
```
|
|
224
226
|
|
|
227
|
+
# Сохранение ключей
|
|
228
|
+
|
|
229
|
+
Сохранить ключ
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
await ds.storePrivateKeyInfo(
|
|
233
|
+
// Информация о ключе
|
|
234
|
+
privateKeyInfo,
|
|
235
|
+
// Будет ли ключ сохранён после закрытия вкладки
|
|
236
|
+
toLocalStorage,
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Считать сохранённые ключи
|
|
240
|
+
|
|
241
|
+
```javascript
|
|
242
|
+
const keyInfo = await ds.getStoredPrivateKeyInfo(
|
|
243
|
+
// Тип ключа (необязательно)
|
|
244
|
+
keyType
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Удалить сохранённые ключи
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
await ds.removeStoredPrivateKeyInfo(
|
|
251
|
+
// Идентификатор ключа (необязательно)
|
|
252
|
+
keyId
|
|
253
|
+
```
|
|
254
|
+
|
|
225
255
|
# Подписание
|
|
226
256
|
|
|
227
257
|
Подписание данных
|
package/src/DigitalSignature.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EndUser, EndUserConstants, EndUserProxySettings, EndUserError, KSPSettings } from "../euscp/euscp";
|
|
2
|
-
import { DigitalSignatureKeyType, PrivateKeyInfo } from "./Models";
|
|
1
|
+
import { EndUser, EndUserConstants, EndUserProxySettings, EndUserError, KSPSettings, EndUserCertificate, EndUserKeyMedia } from "../euscp/euscp";
|
|
2
|
+
import { DigitalSignatureKeyType, PrivateKeyInfo, FilePrivateKeyInfo, HardwarePrivateKeyInfo, KspPrivateKeyInfo } from "./Models";
|
|
3
3
|
import { downloadData, readFile } from "./Utils";
|
|
4
4
|
import Resourses from "./Resourses.json";
|
|
5
5
|
import GlSign from "./GlSign";
|
|
@@ -34,20 +34,29 @@ export default class DigitalSignature {
|
|
|
34
34
|
depositsign.address = "https://depositsign.com/api/v1/it-enterprise/sign-server";
|
|
35
35
|
depositsign.directAccess = true;
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
const diia = new KSPSettings();
|
|
38
|
+
diia.name = "ДіЯ";
|
|
39
|
+
diia.ksp = EndUserConstants.EU_KSP_DIIA;
|
|
40
|
+
diia.directAccess = true;
|
|
41
|
+
diia.mobileAppName = "ДіЯ";
|
|
42
|
+
diia.address = "https://diia-sign.it.ua/KSPSign";
|
|
43
|
+
diia.systemId = "diia-sign-it-ent";
|
|
43
44
|
|
|
44
45
|
/** @type {KSPSettings} */
|
|
45
|
-
this._KSPs = [depositsign];
|
|
46
|
+
this._KSPs = [depositsign, diia];
|
|
46
47
|
|
|
47
48
|
/** @type {PrivateKeyInfo} */
|
|
48
49
|
this._readedKey = null;
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
get PRIVATE_KEY_TYPE() {
|
|
53
|
+
return "_PrivateKeyType";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get PRIVATE_KEY_INFO() {
|
|
57
|
+
return "_PrivateKeyInfo";
|
|
58
|
+
}
|
|
59
|
+
|
|
51
60
|
/**
|
|
52
61
|
* Считанный приватный ключ
|
|
53
62
|
* @type {PrivateKeyInfo}
|
|
@@ -83,6 +92,8 @@ export default class DigitalSignature {
|
|
|
83
92
|
break;
|
|
84
93
|
}
|
|
85
94
|
|
|
95
|
+
this._preferredKeyType = type;
|
|
96
|
+
|
|
86
97
|
await this.initialise();
|
|
87
98
|
this.keyType = type;
|
|
88
99
|
}
|
|
@@ -92,6 +103,7 @@ export default class DigitalSignature {
|
|
|
92
103
|
* @returns {Promise<number>} Текущий тип библиотеки
|
|
93
104
|
*/
|
|
94
105
|
async initialise() {
|
|
106
|
+
|
|
95
107
|
if (!this._glSign) {
|
|
96
108
|
this._glSign = await Promise.resolve(this._settingsProvider.getGlSign());
|
|
97
109
|
}
|
|
@@ -110,7 +122,7 @@ export default class DigitalSignature {
|
|
|
110
122
|
|
|
111
123
|
if (!this._euSign) {
|
|
112
124
|
this._euSign = this._glSign.PreferHarware ? this._euSignKeyMedia : this._euSignFile;
|
|
113
|
-
this.keyType = this._glSign.PreferHarware ? DigitalSignatureKeyType.Token :
|
|
125
|
+
this.keyType = this._glSign.PreferHarware ? DigitalSignatureKeyType.Token : this._preferredKeyType;
|
|
114
126
|
}
|
|
115
127
|
|
|
116
128
|
const euSign = this._euSign;
|
|
@@ -255,10 +267,11 @@ export default class DigitalSignature {
|
|
|
255
267
|
certs = await Promise.all(certs.map(cert => cert instanceof File || cert instanceof Blob ? readFile(cert) : cert));
|
|
256
268
|
}
|
|
257
269
|
const ownerInfo = await this._euSign.ReadPrivateKey(keyMedia, certs, this._selectedIssuerCN);
|
|
258
|
-
this._readedKey = new
|
|
270
|
+
this._readedKey = new HardwarePrivateKeyInfo(
|
|
259
271
|
DigitalSignatureKeyType.Token,
|
|
260
272
|
ownerInfo,
|
|
261
|
-
await this._euSign.GetOwnCertificates()
|
|
273
|
+
await this._euSign.GetOwnCertificates(),
|
|
274
|
+
keyMedia
|
|
262
275
|
);
|
|
263
276
|
return this._readedKey;
|
|
264
277
|
}
|
|
@@ -270,20 +283,24 @@ export default class DigitalSignature {
|
|
|
270
283
|
* @param {Array<Uint8Array|File>?} certs - Сертификаты ключа (при необходимости)
|
|
271
284
|
*/
|
|
272
285
|
async readFileKey(privateKey, password, certs) {
|
|
286
|
+
let keyName = "Key";
|
|
273
287
|
if (this._euSign != this._euSignFile) {
|
|
274
288
|
await this.setLibraryType(DigitalSignatureKeyType.File);
|
|
275
289
|
}
|
|
276
290
|
if (privateKey instanceof File || privateKey instanceof Blob) {
|
|
291
|
+
keyName = privateKey.name;
|
|
277
292
|
privateKey = await readFile(privateKey);
|
|
278
293
|
}
|
|
279
294
|
if (Array.isArray(certs)) {
|
|
280
295
|
certs = await Promise.all(certs.map(cert => cert instanceof File || cert instanceof Blob ? readFile(cert) : cert));
|
|
281
296
|
}
|
|
282
297
|
const ownerInfo = await this._euSign.ReadPrivateKeyBinary(privateKey, password, certs, this._selectedIssuerCN);
|
|
283
|
-
this._readedKey = new
|
|
298
|
+
this._readedKey = new FilePrivateKeyInfo(
|
|
284
299
|
DigitalSignatureKeyType.File,
|
|
285
300
|
ownerInfo,
|
|
286
|
-
await this._euSign.GetOwnCertificates()
|
|
301
|
+
await this._euSign.GetOwnCertificates(),
|
|
302
|
+
privateKey,
|
|
303
|
+
this.glSign.AllowSavePassword ? password : undefined
|
|
287
304
|
);
|
|
288
305
|
return this._readedKey;
|
|
289
306
|
}
|
|
@@ -311,31 +328,6 @@ export default class DigitalSignature {
|
|
|
311
328
|
return file.name.endsWith(".jks");
|
|
312
329
|
}
|
|
313
330
|
|
|
314
|
-
/**
|
|
315
|
-
* Считать ключ через MobileId
|
|
316
|
-
* @param {string} phone - Номер телефона
|
|
317
|
-
* @param {EndUserConstants.EndUserMobileOperatorID} operatorId - Оператор
|
|
318
|
-
* @param {number} keyId - Для Lifecell и Vodafone - физ. (1) или юр. (2) лицо, для Kyivstar - 0
|
|
319
|
-
* @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
|
|
320
|
-
*/
|
|
321
|
-
async readPrivateKeySIM(phone, operatorId, keyId, getCerts = false) {
|
|
322
|
-
if (this._euSign != this._euSignFile) {
|
|
323
|
-
await this.setLibraryType(DigitalSignatureKeyType.MobileID);
|
|
324
|
-
}
|
|
325
|
-
const ownerInfo = await this._euSign.ReadPrivateKeySIM(phone, operatorId, getCerts, keyId);
|
|
326
|
-
if (getCerts && !ownerInfo) {
|
|
327
|
-
throw {
|
|
328
|
-
message: this._resourses.PrivateKeyNotReaded
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
this._readedKey = new PrivateKeyInfo(
|
|
332
|
-
DigitalSignatureKeyType.MobileID,
|
|
333
|
-
ownerInfo,
|
|
334
|
-
getCerts ? await this._euSign.GetOwnCertificates() : []
|
|
335
|
-
);
|
|
336
|
-
return this._readedKey;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
331
|
/**
|
|
340
332
|
* Считать ключ с облачного провайдера
|
|
341
333
|
* @param {string} userId - Идентификатор пользователя
|
|
@@ -346,7 +338,7 @@ export default class DigitalSignature {
|
|
|
346
338
|
if (this._euSign != this._euSignFile) {
|
|
347
339
|
await this.setLibraryType(DigitalSignatureKeyType.KSP);
|
|
348
340
|
}
|
|
349
|
-
if (typeof ksp !== "string") {
|
|
341
|
+
if (ksp != EndUserConstants.EndUserKSP.DIIA && typeof ksp !== "string") {
|
|
350
342
|
ksp = ksp.name;
|
|
351
343
|
}
|
|
352
344
|
const ownerInfo = await this._euSign.ReadPrivateKeyKSP(userId, ksp, getCerts);
|
|
@@ -355,14 +347,36 @@ export default class DigitalSignature {
|
|
|
355
347
|
message: this._resourses.PrivateKeyNotReaded
|
|
356
348
|
};
|
|
357
349
|
}
|
|
358
|
-
this._readedKey = new
|
|
350
|
+
this._readedKey = new KspPrivateKeyInfo(
|
|
359
351
|
DigitalSignatureKeyType.KSP,
|
|
360
352
|
ownerInfo,
|
|
361
|
-
getCerts ? await this._euSign.GetOwnCertificates() : []
|
|
353
|
+
getCerts ? await this._euSign.GetOwnCertificates() : [],
|
|
354
|
+
userId,
|
|
355
|
+
ksp
|
|
362
356
|
);
|
|
363
357
|
return this._readedKey;
|
|
364
358
|
}
|
|
365
359
|
|
|
360
|
+
/**
|
|
361
|
+
* Коллбэк для идентификации
|
|
362
|
+
* @callback authenticationCallback
|
|
363
|
+
* @param {EndUserConfirmKSPOperationEvent} data - Данные для идентификации (Qr-код, ссылка и тд.)
|
|
364
|
+
*/
|
|
365
|
+
/**
|
|
366
|
+
* Добавить коллбэк идентификации для облачных провайдеров
|
|
367
|
+
* @param {authenticationCallback} event - Коллбэк. Вызывается при запросе на подписание.
|
|
368
|
+
*/
|
|
369
|
+
async addConfirmKSPOperationEventListener(event) {
|
|
370
|
+
if (this._euSign != this._euSignFile) {
|
|
371
|
+
await this.setLibraryType(DigitalSignatureKeyType.KSP);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
await this._euSign.AddEventListener(EndUserConstants.EndUserEventType.ConfirmKSPOperation, function(data) {
|
|
375
|
+
data.qrCode = "data:image/bmp;base64," + data.qrCode;
|
|
376
|
+
event(data);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
366
380
|
/**
|
|
367
381
|
* Получить список облачных провайдеров
|
|
368
382
|
* @returns {KSPSettings[]} Список поддержирживаемых облачных провайдеров
|
|
@@ -384,8 +398,7 @@ export default class DigitalSignature {
|
|
|
384
398
|
*/
|
|
385
399
|
async resetPrivateKey() {
|
|
386
400
|
await Promise.all([
|
|
387
|
-
this.
|
|
388
|
-
this._euSignKeyMedia.ResetPrivateKey()
|
|
401
|
+
this._euSign.ResetPrivateKey()
|
|
389
402
|
]);
|
|
390
403
|
this._readedKey = null;
|
|
391
404
|
}
|
|
@@ -419,7 +432,7 @@ export default class DigitalSignature {
|
|
|
419
432
|
|
|
420
433
|
/**
|
|
421
434
|
* Подписать данные
|
|
422
|
-
* @param {Uint8Array | string | Array<Uint8Array | string>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
|
|
435
|
+
* @param {Uint8Array | string | NamedeData | Array<Uint8Array | string | NamedeData>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
|
|
423
436
|
* @param {boolean?} internal - Внутренняя или внешняя подпись
|
|
424
437
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байтов. По умолчанию подпись возвращается в виде строки в base64
|
|
425
438
|
*/
|
|
@@ -435,7 +448,7 @@ export default class DigitalSignature {
|
|
|
435
448
|
|
|
436
449
|
/**
|
|
437
450
|
* Подписать файл
|
|
438
|
-
* @param {string | Array<string>} fileUrl - Ссылка на загрузку файла. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
451
|
+
* @param {string | NamedeData | Array<string | NamedeData>} fileUrl - Ссылка на загрузку файла. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
439
452
|
* @param {boolean?} internal - Внутренняя или внешняя подпись
|
|
440
453
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
441
454
|
*/
|
|
@@ -446,18 +459,23 @@ export default class DigitalSignature {
|
|
|
446
459
|
if (typeof asByteArray !== "boolean") {
|
|
447
460
|
asByteArray = false;
|
|
448
461
|
}
|
|
462
|
+
const isNamedData = Array.isArray(fileUrl) && fileUrl.every(url => typeof url === "object") || typeof fileUrl === "object";
|
|
449
463
|
let data;
|
|
450
464
|
if (Array.isArray(fileUrl)) {
|
|
451
|
-
data = await Promise.all(fileUrl.map(
|
|
465
|
+
data = await Promise.all(fileUrl.map(function(url) {
|
|
466
|
+
const downloadedData = downloadData(isNamedData ? url.val : url, "binary");
|
|
467
|
+
return isNamedData ? {name: url.name, val: downloadedData} : downloadedData;
|
|
468
|
+
}));
|
|
452
469
|
} else {
|
|
453
|
-
|
|
470
|
+
const downloadedData = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
|
|
471
|
+
data = isNamedData ? {name: fileUrl.name, val: downloadedData} : downloadedData;
|
|
454
472
|
}
|
|
455
473
|
return await this.signData(data, internal, asByteArray);
|
|
456
474
|
}
|
|
457
475
|
|
|
458
476
|
/**
|
|
459
477
|
* Подписать хеш
|
|
460
|
-
* @param {Uint8Array | string | Array<Uint8Array | string>} hash - Хеш файла. Можно передавать несколько хешей в массиве для наложения нескольких подписей за раз
|
|
478
|
+
* @param {Uint8Array | string | NamedData | Array<Uint8Array | string> | NamedData} hash - Хеш файла. Можно передавать несколько хешей в массиве для наложения нескольких подписей за раз
|
|
461
479
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
462
480
|
*/
|
|
463
481
|
async signHash(hash, asByteArray) {
|
|
@@ -469,18 +487,23 @@ export default class DigitalSignature {
|
|
|
469
487
|
|
|
470
488
|
/**
|
|
471
489
|
* Подписать хеш из файла
|
|
472
|
-
* @param {string | Array<string>} hashUrl - Ссылка на скачивание хеша. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
490
|
+
* @param {string | NamedData | Array<string | NamedData>} hashUrl - Ссылка на скачивание хеша. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
473
491
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
474
492
|
*/
|
|
475
493
|
async signFileHash(hashUrl, asByteArray) {
|
|
476
494
|
if (typeof asByteArray !== "boolean") {
|
|
477
495
|
asByteArray = false;
|
|
478
496
|
}
|
|
497
|
+
const isNamedData = Array.isArray(hashUrl) && hashUrl.every(url => typeof url === "object") || typeof hashUrl === "object";
|
|
479
498
|
let hash;
|
|
480
499
|
if (Array.isArray(hashUrl)) {
|
|
481
|
-
hash = await Promise.all(hashUrl.map(
|
|
500
|
+
hash = await Promise.all(hashUrl.map(function(url) {
|
|
501
|
+
const downloadedData = downloadData(isNamedData ? url.val : url, "binary");
|
|
502
|
+
return isNamedData ? {name: url.name, val: downloadedData} : downloadedData;
|
|
503
|
+
}));
|
|
482
504
|
} else {
|
|
483
|
-
|
|
505
|
+
const downloadedData = await downloadData(hashUrl, "binary");
|
|
506
|
+
hash = isNamedData ? {name: hashUrl.name, val: downloadedData} : downloadedData;
|
|
484
507
|
}
|
|
485
508
|
return await this.signHash(hash, asByteArray);
|
|
486
509
|
}
|
|
@@ -563,22 +586,27 @@ export default class DigitalSignature {
|
|
|
563
586
|
|
|
564
587
|
/**
|
|
565
588
|
* Выполнить подписание данных с проверкой подписи
|
|
566
|
-
* @param {Uint8Array | string} data - данные для подписи
|
|
589
|
+
* @param {Uint8Array | string | NamedData} data - данные для подписи
|
|
567
590
|
* @param {boolean?} internal - Накладывать внутреннюю или внешнюю подпись. По умолчанию накладывается внешняя.
|
|
568
591
|
*/
|
|
569
592
|
async signDataEx(data, internal) {
|
|
570
593
|
if (typeof internal !== "boolean") {
|
|
571
594
|
internal = false;
|
|
572
595
|
}
|
|
573
|
-
|
|
596
|
+
const isNamedData = typeof data === "object" && !(data instanceof Uint8Array);
|
|
574
597
|
if (!internal) {
|
|
575
|
-
|
|
598
|
+
const hashedData = await this._euSign.HashData(this._readedKey.getHashAlgo(), isNamedData ? data.val : data, false);
|
|
599
|
+
if(isNamedData) {
|
|
600
|
+
data.val = hashedData;
|
|
601
|
+
} else {
|
|
602
|
+
data = hashedData;
|
|
603
|
+
}
|
|
576
604
|
}
|
|
577
605
|
const signature = internal ? await this.signData(data, internal) : await this.signHash(data);
|
|
578
|
-
const signatureInfo = internal ? await this.verifyDataInternal(signature, 0) : await this.verifyHash(data, signature);
|
|
606
|
+
const signatureInfo = internal ? await this.verifyDataInternal(isNamedData ? signature.val : signature, 0) : await this.verifyHash(isNamedData ? data.val : data, isNamedData ? signature.val : signature);
|
|
579
607
|
return {
|
|
580
608
|
Success: true,
|
|
581
|
-
Sign: signature,
|
|
609
|
+
Sign: isNamedData ? signature.val : signature,
|
|
582
610
|
SignatureInfo: {
|
|
583
611
|
Success: true,
|
|
584
612
|
DateTimeStr: signatureInfo.timeInfo.time,
|
|
@@ -590,16 +618,23 @@ export default class DigitalSignature {
|
|
|
590
618
|
|
|
591
619
|
/**
|
|
592
620
|
* Выполнить подписание с проверкой подписи
|
|
593
|
-
* @param {string} fileUrl - ссылка на загрузку файла для подписания
|
|
621
|
+
* @param {string | NamedData} fileUrl - ссылка на загрузку файла для подписания
|
|
594
622
|
* @param {boolean} hash - подписывать хеш
|
|
595
623
|
*/
|
|
596
624
|
async signFileEx(fileUrl, hash) {
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
625
|
+
const isNamedData = typeof fileUrl === "object";
|
|
626
|
+
let data = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
|
|
627
|
+
if(!hash) {
|
|
628
|
+
data = await this._euSign.HashData(this._readedKey.getHashAlgo(), data, false);
|
|
629
|
+
if(isNamedData) {
|
|
630
|
+
data = {name: fileUrl.name, val: data};
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
const signature = await this.signHash(data);
|
|
634
|
+
const signatureInfo = await this.verifyHash(isNamedData ? data.val : data, isNamedData ? signature.val : signature);
|
|
600
635
|
return {
|
|
601
636
|
Success: true,
|
|
602
|
-
Sign: signature,
|
|
637
|
+
Sign: isNamedData ? signature.val : signature,
|
|
603
638
|
SignatureInfo: {
|
|
604
639
|
Success: true,
|
|
605
640
|
DateTimeStr: signatureInfo.timeInfo.time,
|
|
@@ -611,14 +646,15 @@ export default class DigitalSignature {
|
|
|
611
646
|
|
|
612
647
|
/**
|
|
613
648
|
* Выполнить подписание хеша с проверкой подписи
|
|
614
|
-
* @param {string} hash - хеш для подписания
|
|
649
|
+
* @param {string | NamedData} hash - хеш для подписания
|
|
615
650
|
*/
|
|
616
651
|
async signHashEx(hash) {
|
|
617
|
-
const
|
|
618
|
-
const
|
|
652
|
+
const isNamedData = typeof hash === "object";
|
|
653
|
+
const signature = await this.signHash(isNamedData ? hash.val : hash);
|
|
654
|
+
const signatureInfo = await this.verifyHash(isNamedData ? hash.val : hash, isNamedData ? signature.val : signature);
|
|
619
655
|
return {
|
|
620
656
|
Success: true,
|
|
621
|
-
Sign: signature,
|
|
657
|
+
Sign: isNamedData ? signature.val : signature,
|
|
622
658
|
SignatureInfo: {
|
|
623
659
|
Success: true,
|
|
624
660
|
DateTimeStr: signatureInfo.timeInfo.time,
|
|
@@ -680,7 +716,135 @@ export default class DigitalSignature {
|
|
|
680
716
|
return await this.developData(data, senderCert);
|
|
681
717
|
}
|
|
682
718
|
|
|
719
|
+
/**
|
|
720
|
+
* Сохранить ключ
|
|
721
|
+
* @param {PrivateKeyInfo} privateKeyInfo - Ключ
|
|
722
|
+
* @param {boolean} toLocalStorage - Будет ли ключ сохранён после закрытия вкладки
|
|
723
|
+
*/
|
|
724
|
+
async storePrivateKeyInfo(privateKeyInfo, toLocalStorage) {
|
|
725
|
+
if(privateKeyInfo.ksp && privateKeyInfo.ksp == EndUserConstants.EndUserKSP.DIIA) {
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const storage = toLocalStorage ? localStorage : sessionStorage;
|
|
730
|
+
const keys = await this.getStoredPrivateKeyInfo();
|
|
731
|
+
|
|
732
|
+
if(keys.length == 0 || keys.filter(key => key.id == privateKeyInfo.id).length < 1) {
|
|
733
|
+
const keys = await this.getPrivateKeyInfoFromStorage(toLocalStorage);
|
|
734
|
+
keys.push(privateKeyInfo);
|
|
735
|
+
const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
|
|
736
|
+
storage[this._userId + this.PRIVATE_KEY_INFO] = data;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Получить сохранённые ключи
|
|
742
|
+
* @param {number?} keyType - Вид ключа
|
|
743
|
+
* @returns {Array<PrivateKeyInfo>} Сохранённые ключи
|
|
744
|
+
*/
|
|
745
|
+
async getStoredPrivateKeyInfo(keyType) {
|
|
746
|
+
const local = await this.getPrivateKeyInfoFromStorage(true, keyType);
|
|
747
|
+
const session = await this.getPrivateKeyInfoFromStorage(false, keyType);
|
|
748
|
+
return local.concat(session);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
async getPrivateKeyInfoFromStorage(fromLocalStorage, keyType) {
|
|
752
|
+
const storage = fromLocalStorage ? localStorage : sessionStorage;
|
|
753
|
+
const storedKeys = storage[this._userId + this.PRIVATE_KEY_INFO];
|
|
754
|
+
|
|
755
|
+
let ls;
|
|
756
|
+
const result = [];
|
|
757
|
+
if(!storedKeys) {
|
|
758
|
+
return result;
|
|
759
|
+
}
|
|
760
|
+
const data = await this._euSignFile.UnprotectDataByPassword(storedKeys, "", true);
|
|
761
|
+
try{
|
|
762
|
+
ls = JSON.parse(data);
|
|
763
|
+
if(keyType >= 0) {
|
|
764
|
+
ls = ls.filter(key => key.keyType == keyType);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
catch{
|
|
768
|
+
ls = [];
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
ls.forEach(key => {
|
|
772
|
+
const password = key.password;
|
|
773
|
+
if(key.keyType == DigitalSignatureKeyType.File) {
|
|
774
|
+
key.privateKey = new Uint8Array(Object.assign(new Array(), key.privateKey));
|
|
775
|
+
key = new FilePrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.privateKey, key.password);
|
|
776
|
+
}
|
|
777
|
+
else if (key.keyType == DigitalSignatureKeyType.Token) {
|
|
778
|
+
key = new HardwarePrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.keyMedia);
|
|
779
|
+
}
|
|
780
|
+
else if (key.keyType == DigitalSignatureKeyType.KSP) {
|
|
781
|
+
key = new KspPrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.userId, key.ksp);
|
|
782
|
+
}
|
|
783
|
+
const certs = [];
|
|
784
|
+
key.certificates.forEach(cert => {
|
|
785
|
+
const certObj = Object.assign(new EndUserCertificate(), cert);
|
|
786
|
+
certObj.data = new Uint8Array(Object.assign(new Array(), cert.data));
|
|
787
|
+
certs.push(certObj);
|
|
788
|
+
});
|
|
789
|
+
key.certificates = certs;
|
|
790
|
+
key.password = password;
|
|
791
|
+
result.push(key);
|
|
792
|
+
});
|
|
793
|
+
return result;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Удалить сохранённые ключи
|
|
798
|
+
* @param {string} keyId - Идентификатор ключа
|
|
799
|
+
*/
|
|
800
|
+
async removeStoredPrivateKeyInfo(keyId) {
|
|
801
|
+
if (keyId === undefined) {
|
|
802
|
+
localStorage.removeItem(this._userId + this.PRIVATE_KEY_INFO);
|
|
803
|
+
sessionStorage.removeItem(this._userId + this.PRIVATE_KEY_INFO);
|
|
804
|
+
}
|
|
805
|
+
else{
|
|
806
|
+
const localStoredKeys = await this.getPrivateKeyInfoFromStorage(true);
|
|
807
|
+
const sessionStoredKeys = await this.getPrivateKeyInfoFromStorage(false);
|
|
808
|
+
const storage = localStoredKeys.filter(item => item.id == keyId).length > 0 ? localStorage : sessionStorage;
|
|
809
|
+
const keys = storage == localStorage ? localStoredKeys : sessionStoredKeys;
|
|
810
|
+
const keyIndex = keys.findIndex((element) => element.id == keyId);
|
|
811
|
+
|
|
812
|
+
if(keyIndex > -1) {
|
|
813
|
+
keys.splice(keyIndex, 1);
|
|
814
|
+
const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
|
|
815
|
+
storage[this._userId + this.PRIVATE_KEY_INFO] = data;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Получить предпочитаемый тип ключа
|
|
822
|
+
*/
|
|
823
|
+
get _preferredKeyType () {
|
|
824
|
+
const keyType = parseInt(localStorage[this._userId + this.PRIVATE_KEY_TYPE]);
|
|
825
|
+
if (typeof keyType === "number" && keyType > -1) {
|
|
826
|
+
return keyType;
|
|
827
|
+
} else {
|
|
828
|
+
localStorage[this._userId + this.PRIVATE_KEY_TYPE] = DigitalSignatureKeyType.File;
|
|
829
|
+
return DigitalSignatureKeyType.File;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Задать предпочитаемый тип ключа
|
|
835
|
+
* @param {DigitalSignatureKeyType | number} keyType - Тип ключа
|
|
836
|
+
*/
|
|
837
|
+
set _preferredKeyType (keyType) {
|
|
838
|
+
if (typeof keyType === "number" && keyType > -1) {
|
|
839
|
+
localStorage[this._userId + this.PRIVATE_KEY_TYPE] = keyType;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
683
843
|
get _resourses() {
|
|
684
844
|
return Resourses[this._settings.language];
|
|
685
845
|
}
|
|
846
|
+
|
|
847
|
+
get _userId () {
|
|
848
|
+
return typeof this._settings.userId === "function" ? this._settings.userId() : this._settings.userId;
|
|
849
|
+
}
|
|
686
850
|
}
|
package/src/GlSign.js
CHANGED
|
@@ -48,7 +48,7 @@ export default class GlSign {
|
|
|
48
48
|
this.IdleTimeout = parseInt(this._getZoneValue(settingArray, 12));
|
|
49
49
|
this.DeviceType = this._getZoneValue(settingArray, 13);
|
|
50
50
|
this.PreferHarware = this._getZoneValue(settingArray, 16);
|
|
51
|
-
this.HideMobileId =
|
|
51
|
+
this.HideMobileId = true;
|
|
52
52
|
|
|
53
53
|
this.UseProxy = this._getSubZoneValue(settingArray, 19, ",", 1) === "+";
|
|
54
54
|
this.ProxyAddress = this._getSubZoneValue(settingArray, 19, ",", 2);
|
|
@@ -85,6 +85,3 @@ export default class GlSign {
|
|
|
85
85
|
return this._getZoneValue(subZones, subzone);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|