Актуализировал пример использования с Angular

This commit is contained in:
vgoma 2020-09-01 18:39:43 +03:00
parent d9797b31a5
commit 3d71049078
2 changed files with 155 additions and 38 deletions

View File

@ -1,34 +1,106 @@
<select name="certificate"
[(ngModel)]="thumbprint">
<option value="null" disabled>Не выбран</option>
<form
#signatureForm="ngForm"
novalidate
(ngSubmit)="createSignature(thumbprint)">
<fieldset>
<legend>Создание подписи</legend>
<label for="message">Подписываемое сообщение: *</label>
<br>
<textarea
id="message"
name="message"
cols="80"
rows="5"
placeholder="Введите сообщение"
autofocus
required
[(ngModel)]="message">Привет мир!</textarea>
<br><br>
<option *ngFor="let cert of certificateList"
[value]="cert.thumbprint">
{{cert.name}}
</option>
</select>
<label for="certificate">Сертификат: *</label>
<br>
<select
id="certificate"
name="certificate"
required
[(ngModel)]="thumbprint">
<option value="null" disabled>Не выбран</option>
<option *ngFor="let cert of certificateList" [value]="cert.thumbprint">
{{cert.name + ' (действителен до: ' + cert.validTo + ')'}}
</option>
</select>
<pre>{{certificateListError}}</pre>
<button type="button"
[disabled]="!thumbprint"
(click)="createSignature(thumbprint)">
Создать подпись
</button>
<details
*ngIf="thumbprint"
(click)="showCertInfo(thumbprint)">
<summary>Информация о сертификате</summary>
<pre *ngIf="certInfo">{{certInfo | json}}</pre>
<pre *ngIf="!certInfo">Запрашивается...</pre>
</details>
<pre>{{certificateInfoError}}</pre>
<button type="button"
[disabled]="!thumbprint"
(click)="showCertInfo(thumbprint)">
Информация о сертификате
</button>
<label>Тип подписи: *</label>
<br>
<label>
<input
type="radio"
name="detachedSignature"
[value]="false"
[(ngModel)]="detachedSignature">Совмещенная</label>
<br>
<label>
<input
type="radio"
name="detachedSignature"
[value]="true"
[(ngModel)]="detachedSignature">Отделенная</label>
<br><br>
<pre *ngIf="certInfo">{{certInfo | json}}</pre>
<hr>
<button
type="submit"
[disabled]="!signatureForm.valid">Создать подпись</button>
</fieldset>
</form>
<br>
<fieldset>
<legend>Результат</legend>
<label for="hash">Хэш (ГОСТ Р 34.11-2012 256 бит):</label><br>
<textarea
id="hash"
cols="80"
rows="5"
[(ngModel)]="hash"
[placeholder]="hashStatus"
></textarea>
<pre>{{hashError}}</pre>
<textarea name="signature"
[(ngModel)]="signature"
cols="100"
rows="30"></textarea>
<label for="signature">Подпись (PKCS7):</label><br>
<textarea
id="signature"
name="signature"
cols="80"
rows="30"
[placeholder]="signatureStatus"
[(ngModel)]="signature"
></textarea>
<pre>{{signatureError}}</pre>
<pre *ngIf="error">{{error}}</pre>
<p>
Для
<a href="https://www.gosuslugi.ru/pgu/eds/"
target="_blank"
rel="nofollow noopener noreferrer"
title="Перейти к проверке подписи">проверки</a>
нужно создать файл со сгенерированной подписью в кодировке UTF-8 с расширением *.sgn
<br>
для отделенной подписи (или *.sig для совмещенной).
</p>
</fieldset>
<pre *ngIf="systemInfo">{{systemInfo | json}}</pre>
<fieldset>
<legend>Информация о системе</legend>
<pre *ngIf="systemInfo">{{systemInfo | json}}</pre>
<pre>{{systemInfoError}}</pre>
</fieldset>

View File

@ -4,7 +4,9 @@ import {
getUserCertificates,
getSystemInfo,
isValidSystemSetup,
createSignature,
createHash,
createDetachedSignature,
createAttachedSignature,
SystemInfo,
Certificate
} from 'crypto-pro';
@ -15,14 +17,23 @@ import {
styleUrls: ['./crypto-pro.component.css']
})
export class CryptoProComponent implements OnInit {
public message = 'Привет мир!';
public certificateList: Certificate[] = [];
public hash: string = null;
public hashStatus = 'Не вычислен';
public detachedSignature = true;
public thumbprint: string = null;
public signature: string;
public signature: string = null;
public signatureStatus = 'Не создана';
public systemInfo: SystemInfo & {
isValidSystemSetup: boolean;
};
public error: string;
public certInfo;
public certificateListError: string = null;
public certificateInfoError: string = null;
public hashError: string = null;
public signatureError: string = null;
public systemInfoError: string = null;
public certInfo = null;
constructor() { }
@ -32,18 +43,48 @@ export class CryptoProComponent implements OnInit {
}
public async createSignature(thumbprint) {
// Вычислинный hash по ГОСТ Р 34.11-94 для строки: "abc"
const hash = 'b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c';
const hashBase64 = window.btoa(hash);
this.hash = null;
this.hashError = null;
this.signature = null;
this.signatureError = null;
this.hashStatus = 'Вычисляется...';
try {
this.signature = await createSignature(thumbprint, hashBase64);
this.hash = await createHash(this.message);
} catch (error) {
this.error = error.message;
this.hashError = error.message;
return;
}
this.hashStatus = 'Не вычислен';
this.signatureStatus = 'Создается...';
if (this.detachedSignature) {
try {
this.signature = await createDetachedSignature(thumbprint, this.hash);
} catch (error) {
this.signatureError = error.message;
}
this.signatureStatus = 'Не создана';
return;
}
try {
this.signature = await createAttachedSignature(thumbprint, this.message);
} catch (error) {
this.signatureError = error.message;
}
this.signatureStatus = 'Не создана';
}
public async showCertInfo(thumbprint) {
this.certInfo = null;
this.certificateInfoError = null;
try {
const certificate = await getCertificate(thumbprint);
@ -74,26 +115,30 @@ export class CryptoProComponent implements OnInit {
]),
};
} catch (error) {
this.error = error.message;
this.certificateInfoError = error.message;
}
}
private async displayCertificates() {
this.certificateListError = null;
try {
this.certificateList = await getUserCertificates();
} catch (error) {
this.error = error.message;
this.certificateListError = error.message;
}
}
private async displaySystemInfo() {
this.systemInfoError = null;
try {
this.systemInfo = {
...await getSystemInfo(),
isValidSystemSetup: await isValidSystemSetup()
};
} catch (error) {
this.error = error.message;
this.systemInfoError = error.message;
}
}
}