После того, как получен буфер, содержащий цифровую подпись, его (буфер) можно сохранить в файл, отправить по почте и т.п.
Пример:
void signHash(HCRYPTHASH hash)
{
DWORD size;
::CryptSignHash(hash, AT_SIGNATURE, 0, 0, 0, &size);
BYTE * signature = reinterpret_cast<BYTE*>(
::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, size)
);
::CryptSignHash(hash, AT_SIGNATURE, 0, 0, signature, &size);
// ... Используем буфер, сохраняем в файл, отправляем по сети ...
::HeapFree(::GetProcessHeap(), 0, signature);
}
procedure SignHash(hash: HCRYPTHASH);
var
size : integer;
signature : PByte;
begin
CryptSignHash(hash, AT_SIGNATURE, nil, 0, nil, @size);
signature := SysGetMem(size);
CryptSignHash(hash, AT_SIGNATURE, nil, 0, signature, @size);
{ ... Используем буфер, сохраняем в файл, отправляем по сети ... }
SysFreeMem(signature);
end;
Проверить подпись можно при наличии открытого ключа, который соответствует закрытому использовавшемуся при создании подписи. Такой ключ (открытый) экспортируется с параметром PUBLICKEYBLOB. Функция проверки подписи имеет вид:
BOOL WINAPI CryptVerifySignature(
HCRYPTHASH hHash,
BYTE *pbSignature,
DWORD dwSigLen,
HCRYPTKEY hPubKey,
LPCTSTR sDescription,
DWORD dwFlags
);
Всё так же первым параметром (hHash) передаётся идентификатор объекта «хэш», содержащий хэш-значение проверяемого документа (файла). Указатель на буфер, содержащий строку байтов цифровой подписи, передают вторым параметром (pbSignature). Размер буфера — третьим параметром (dwSigLen). Открытый ключ подписавшего документ — четвёртым (hPubKey). Два последних параметра имеют такое же назначение, что и в случае функции CryptSignHash.
Функция возвращает TRUE, если подпись верна, и FALSE — если вызов функции был неудачным. В последнем случае системная функция
DWORD GetLastError(VOID);
вернёт NTE_BAD_SIGNATURE, если подпись неверна (например, документ был изменён, подпись была изменена, открытый ключ не соответствует закрытому, который был использован для подписи и/или использованы разные алгоритмы для подписи и/или нахождения хэш-значения).
Пример:
void verifySignature(HCRYPTHASH hash, HCRYPTKEY publicKey)
{
BYTE * signature;
DWORD size;
// ... Получили строку байтов цифровой подписи и её размер ...
if (::CryptVerifySignature(hash, signature, size, publicKey, 0, 0)) {
// Подпись верна
}
else if (::GetLastError() == NTE_BAD_SIGNATURE) {
// Подпись не верна
}
else {
// Другая ошибка (см. MSDN)
}
}
procedure VerifySignature(hash: HCRYPTHASH; publicKey: HCRYPTKEY);
var
size : integer;
signature : PByte;
begin
{ ... Получили строку байтов цифровой подписи и её размер ... }
if CryptVerifySignature(hash, signature, size, publicKey, nil, 0) then
{ Подпись верна }
else if GetLastError = NTE_BAD_SIGNATURE then
{ Подпись не верна }
else
{ Другая ошибка (см. MSDN) }
end;
Написать программу, которая подписывает документы и проверяет их подпись указанным алгоритмом (название алгоритма подписи и хэш-алгоритма и размер ключа) и сохраняет (берёт) подпись в (из) указанный (указанного) файл (файла).
Предусмотреть создание ключей подписи (закрытый и открытый) указанным алгоритмом и сохранение их в файлы.
Например, передавать в программу следующие параметры из командной строки:
-s my.private document.doc document.signature {for sign}
-v my.public document.doc document.signature {for verify}
-g my.private my.public {for generating keys}
-a RSA_SIGN {for signing algorithm}
-k 1024 {for size of signing key}
-h MD5 {for hash algorithm}
-l {for list of available signing algorithms and hash algorithms}
-? {for help}
Вызов программы может быть такой:
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.