Цифровая подпись в проектах на CryptoAPI (Лабораторная работа № 3), страница 2

Третий параметр dwBlobType — это тип блоба ключа. Для ключей цифровой подписи этот параметр может принимать значение PRIVATEKEYBLOB для экспорта пары ключей (открытый и закрытый) и PUBLICKEYBLOB для экспорта только открытого ключа. Пара ключей остаётся и должна надёжно храниться у владельца ключа, а открытый ключ публикуется и распространяется между участниками криптографической сети.

Флаг ключа pbData обычно принимает нулевое значение. За дополнительной информацией обращайтесь в MSDN.

Указатель на буфер, куда будет помещён блоб ключа, передаётся пятым параметром (pbData). Буфер должен быть достаточно большим, чтобы принять весь блоб ключа, размер буфера передаётся последним параметром (pdwDataLen). Для определения размера буфера применяют уже известную методику, передавая в функцию нулевое значение в пятом параметре (pbData). Тогда после вызова функции в последнем параметре (pdwDataLen) вернётся необходимый размер буфера.

Например, это можно сделать так:

C++

void exportKeys(HCRYPTKEY key)

{

  DWORD size;

  BYTE * keyBlob;

  // Экспортируем private key и public key (то есть ключевую пару)

  ::CryptExportKey(key, 0, PRIVATEKEYBLOB, 0, 0, &size);

  keyBlob = reinterpret_cast<BYTE*>(

    ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, size)

  );

  ::CryptExportKey(key, 0, PRIVATEKEYBLOB, 0, keyBlob, &size);

  // ... Используем буфер, например, сохраняем в файл, ...

  // ... или импортируем в контекст другого провайдера ...

  ::HeapFree(::GetProcessHeap(), 0, keyBlob);

  // Экспортируем public key

  ::CryptExportKey(key, 0, PUBLICKEYBLOB, 0, 0, &size);

  keyBlob = reinterpret_cast<BYTE*>(

    ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, size)

  );

  ::CryptExportKey(key, 0, PUBLICKEYBLOB, 0, keyBlob, &size);

  // ... Используем буфер, например, сохраняем в файл, ...

  // ... или импортируем в контекст другого провайдера ...

  ::HeapFree(::GetProcessHeap(), 0, keyBlob);

}


Delphi

procedure ExportKeys(key: HCRYPTKEY);

var

  size    : integer;

  keyBlob : PByte;

begin

  { Экспортируем private key и public key (то есть ключевую пару) }

  CryptExportKey(key, 0, PRIVATEKEYBLOB, 0, nil, @size);

  keyBlob := SysGetMem(size);

  CryptExportKey(key, 0, PRIVATEKEYBLOB, 0, keyBlob, @size);

  { ... Используем буфер, например, сохраняем в файл, ... }

  { ... или импортируем в контекст другого провайдера ... }

  SysFreeMem(keyBlob);

  { Экспортируем public key }

  CryptExportKey(key, 0, PUBLICKEYBLOB, 0, nil, @size);

  keyBlob := SysGetMem(size);

  CryptExportKey(key, 0, PUBLICKEYBLOB, 0, keyBlob, @size);

  { ... Используем буфер, например, сохраняем в файл, ... }

  { ... или импортируем в контекст другого провайдера ... }

  SysFreeMem(keyBlob);

end;

После того как мы получили блоб ключа, мы можем сохранить его в файл, передать по сети, послать по почте или импортировать в контекст другого провайдера (например, сохранить на смарт-карте) с помощью функции CryptImportKey:

BOOL WINAPI CryptImportKey(

  HCRYPTPROV hProv,

  BYTE *pbData,

  DWORD dwDataLen,

  HCRYPTKEY hPubKey,

  DWORD dwFlags,

  HCRYPTKEY *phKey

);