Работа с электронной подписью

Формирование электронной подписи

Для формирования электронной подписи используется метод JCSDevice.createSignature. При помощи этого метода можно создавать два вида подписи:

  • присоединенную подпись (подписываемые данные включаются в подпись);
  • отсоединенную подпись (подписываемые данные не включаются в подпись).

За выбор вида подписи отвечает аргумент attachedSignature.

Пример подключения к смарт-карте в разделе Подключение к NFC смарт-карте.

Пример создания присоединенной подписи

Swift

// PIN-код пользователя
let userPIN = "1234567890"

// данные для подписи
let dataStr = "Data to sign"
let data = (dataStr.data(using: .utf8))!

// флаг определяющий прикреплять данные к подписи или нет
let attachedSignature = true

let certificatesLoaded = JCSStorage.shared()?.certificates()

guard let certificates = certificatesLoaded?.value, certificates.count > 0 else
{
    // сообщение об отсутствии сертификатов в хранилище
   return
}

// Формирование подписи
// Возьмем первый сертификат из списка
let certificate = certificates.first!

// Вычисление хэша
let hashRes = JCSUtils.digest(data:data, algorithm: .gost)
if let error = hashRes.error
{
    // Сообщение об ошибке при вычислении хэша
    return
}

let signRes = device.createSignature(
    hash: hashRes.value!,
    userPIN: userPIN,
    signaturePIN: nil,
    certificate: certificate,
    data: attachedSignature ? data : nil)

if let error = signRes.error
{
    // Сообщение об ошибке при выполнении подписи
    return
}

Objective-C

NSString* userPin = @"1234567890";
NSString* dataString = @"Data to sign";
BOOL attachedSignature = true;
NSData* data = [dataString dataUsingEncoding:NSUTF8StringEncoding];

// Вычисление хэша
JCSDataResult* hashRes = [JCSUtils digestData:data algorithm:JCSHashAlgorithmGost];
if(hashRes.error) {
    [self showError:hashRes.error];
    return;
}
// Чтение сертификатов
[nfcSession changeAlertMessage:@"Чтение сертификатов..."];

JCSCertificateListResult* certsRes = [[JCSStorage shared] certificates];
    if(certsRes.error) {
        // сообщение об ошибке при четнии сертификатов в хранилище
        [nfcSession close];
        return;
    }

    if(certsRes.value.count == 0) {
        // сообщение об отсутсвии сертификатов
        [nfcSession close];
        return;
    }

    // Формирование подписи
    [nfcSession changeAlertMessage:@"Подписание данных..."];
    id<JCSCertificate> certificate = certsRes.value.firstObject;
    JCSDataResult* signRes = [device createSignatureFromHash:hashRes.value
        userPIN:userPIN
        signaturePIN:nil
        certificate:certificate
        data:attachedSignature ? data : nil];

    if(signRes.error) {
        // сообщение об ошибке при создании подписи
        [nfcSession close];
        return;
    }

    // 6. Закрытие NFC сессии
    [nfcSession close];

Проверка электронной подписи

Для проверки электронной подписи используется метод JCSUtils.verifySignature. При помощи этого метода можно осуществлять проверку:

  • присоединенной подписи (подписываемые данные включены в подпись);
  • отсоединенной подписи (подписываемые данные не включены в подпись).
Если используется отсоединенная подпись, необходимо передать проверяемые данные в аргументе data.
Если используется присоединенная подпись:
  • если в аргументе data передаются данные - они будут использоваться для проверки;
  • если в аргументе data передается null - для проверки будут использоваться данные из подписи.

Пример проверки присоединенной подписи

Swift

// данные для подписи
let dataStr = "Data to sign"

// Перевод подписи из Base64 в набор байт
let signature = Data(base64Encoded: signatureBase64, options: [])

// флаг определяющий прикреплены данные к подписи или нет
let attachedSignature = true

// Если сформирована присоединенная подпись, то исходные данные можно не передавать
let data = attachedSignature ? nil : (dataStr.data(using: .utf8))!

// 1. Программная проверка подписи
let result = JCSUtils.verify(signature: signature!, data: data)

// 2. Обработка результата
if let err = result.error {
    // Сообщение об ошибке
    return
}

if result.value
{
// подпись верна
}
else
{
// подпись не верна
}

Objective-C

// данные для подписи
NSString* dataString = @"Data to sign";

BOOL attachedSignature = true;
// Перевод подписи из Base64 в набор байт
NSData* signature = [[NSData alloc] initWithBase64EncodedString:signatureBase64 options:0];

// Если сформирована присоединенная подпись, то исходные данные можно не передавать
NSData* data = attachedSignature? nil : [dataString dataUsingEncoding:NSUTF8StringEncoding];

// 1. Программная проверка подписи
JCSBoolResult* result = [JCSUtils verifySignature:signature data:data];

// 2. Обработка результата
if(result.error) {
    // сообщение об ошибке
    return;
}

NSString* message = result.value ? @"The signature is correct" : @"The signature is incorrect";
if (result.value)
{
// подпись верна
}
else
{
// подпись не верна
}