Консультация № 173121
10.10.2009, 03:05
0.00 руб.
0 1 0
Доброго времени суток! Друзья,есть такая вот программа(в приложении).Проблема в том что никак не получается вывести на экран PrivateKeyBlob.
pbKeyBlob получилось вывести на экран - можете проверить и загрузить программу.А вот Private ни в какую.Подскажите пожалуйста в чём ошибка?

Приложение:
/ Создание цифровой подписи
// Необходимо подключить библиотеку crypt32.lib
// Компиляция с использованием Visual Studio 7.0

#include <conio.h>
#include "stdio.h"
#include "windows.h"
#include "wincrypt.h"

// Объявление функции CryptAcquireContextEx
BOOL
CryptAcquireContextEx(HCRYPTPROV *phProv, //out
LPTSTR pszContainer, //in
LPTSTR pszpRovider, //in
DWORD dwProvType, //in
DWORD dwFlags, //in
DWORD dwKeySpec, //in
DWORD KeyFlags //in
);
void main(int argc, char *argv[])
{
// Объявление и инициализация переменных.
HCRYPTPROV hProv=0;// Дескриптор провайдера
HCRYPTKEY hKey=0, hPubKey=0; // Дескприптор ключа
HCRYPTHASH hHash=0;
// Буфер данных для подписи
LPBYTE pbBuffer=(BYTE *)"The data that is to be hashed and signed.";
// Типа из командной строки
// LPBYTE pbBuffer;
LPTSTR szDescription="Test Data Description";
LPBYTE pbKeyBlob=NULL, pbSignature=NULL; PrivateBlob = NULL;
DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
DWORD dwSigLen=0, dwBlobLen=0;dwBlobLen1 = 0;
// ********************************************************************
// Первая фраза. Подпись сообщения.
// ********************************************************************
// Получение дискриптора криптопровайдера.
if (!CryptAcquireContextEx(&hProv, NULL, NULL, PROV_RSA_FULL, 0, AT_SIGNATURE, 0))
goto ReleaseResource;
printf("CSP context acquired\n");

// Получение дискриптора ключа подписи.
// AT_SIGNATURE - алгоритма открытых ключей
// являются основой для "Цифровых Подписей" (NIST Digital Signature Algorithm - DSA)
if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey))
{
printf("Error: CryptGetUserKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The signature key has been acquired\n");

// Для получения необходимого размера памяти параметр pbData равен NULL.
// Размер ключевого блока возвращается в параметре dwBlodLen
// PUBLICKEYBLOB - используется для сохранения открытых ключей.
// Поскольку открытые ключи не являются секретными, они сохраняются в незашифрованном виде;
if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen))
{
printf("Error: CryptExportKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("Size of the blob for the public key determined\n");

// Выделение памяти для pbKeyBlob.
pbKeyBlob = (LPBYTE)malloc (dwBlobLen);

if (!pbKeyBlob)
{
printf("Error: Out of memory\n");
goto ReleaseResource;
}
printf("Memory has been allocated for the blob\n");

// Экспорт открытого ключа пары подписи.
if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen))
{
printf("Error: CryptExportKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("Context have been written to the blob\n");

//выведем ключевой блоб открытого ключа
for (DWORD i = 0; i < dwBlobLen; i++)
printf("%02x",pbKeyBlob[i]);


//получим ключевой блоб ключевой пары
// Для получения необходимого размера памяти параметр pbData равен NULL.
// Размер ключевого блоба возвращается в параметре dwBlodLen1
if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwBlobLen1))
{
printf("Error: CryptExportKey=0x%X.\n", GetLastError());
goto ReleaseResource;
}
printf("Size of the blob for the private key pair determined\n");

// Выделение памяти для PrivateBlob
PrivateBlob = (LPBYTE)malloc (dwBlobLen1);

if (!PrivateBlob)
{
printf("Error: Out of memory\n");
goto ReleaseResource;
}
printf("Memory has been allocated for the blob\n");

// Экспорт секретного ключа пары подписи.
if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, PrivateBlob, &dwBlobLen1))
{
printf("Error: CryptExportKey=0x%X.\n", GetLastError());
goto ReleaseResource;
}
printf("Context have been written to the blob\n");

//выведем ключевой блоб пары
for (DWORD i = 0; i < dwBlobLen1; i++)
printf("%02x", PrivateBlob[i]);



// Создание объекта хеширования.
// CALG_MD5 - идентификатор алгоритма MD5
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
printf("Error: CryptCreateHash=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("Hash object created. Using MD5\n");

// Хеширование буфера данных
if (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0))
{
printf("Error: CryptHashData=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The data buffer has been hashed\n");

// Определение необходимого размера памяти для буфера цифровой подписи.
if (!CryptSignHash(hHash, AT_SIGNATURE, szDescription, 0, NULL, &dwSigLen))
{
printf("Error: CryptSignHash=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("Signature length %d found.\n", dwSigLen);

// Выделение памяти под буфер цифровой подписи.
pbSignature = (LPBYTE)malloc(dwSigLen);
if (!pbSignature)
{
printf("Error: Out of memory\n");
goto ReleaseResource;
}
printf("Memory allocated for the signature\n");

// Вычисление цифровой подписи
if (!CryptSignHash(hHash, AT_SIGNATURE, szDescription, 0, pbSignature, &dwSigLen))
{
printf("Error: CryptSignHash=0x%X.\n", GetLastError());
goto ReleaseResource;
}
printf("pbSignature is the hash signature\n");


// Уничтожение объекта хеширования
if (hHash)
CryptDestroyHash(hHash);
hHash = 0;
printf("The hash object has been destroyed\n");
printf("The signing phase of this program is completed\n\n");


//************************************************** *********
// Вторая фаза. Проверка цифровой подписи сообщения
//************************************************** *********

// Импортируем открытый ключ в криптопровайдер
if (!CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey))
{
printf("Error: CryptImportKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The key has been inported\n");

// Создание нового объекта хеширования.
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
printf("Error: CryptCreateHash=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The hash object has been recreated. Using MD5\n");

// Хеширование буфера данных
if (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0))
{
printf("Error: CryptHashData=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The new has been created.\n");


// Проверка цифровой подписи
if (!CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, szDescription, 0))
{
if (GetLastError() == NTE_BAD_SIGNATURE)
printf("SIGNATURE FAILED TO VALIDATED");
else
printf("Error: CryptVerifySignature=0x%X.\n",GetLastError());
}
else
printf("SIGNATURE VALIDATED OK!\n");


ReleaseResource:


// Освобождаем память блоба открытого ключа
if (pbKeyBlob)
free(pbKeyBlob);
// Освобождаем память подписи
if (pbSignature)
free(pbSignature);
// Уничтожаем объект хеширования
if (hHash)
CryptDestroyHash(hHash);
// Освобождаем дескриптор криптопровайдера
if (hProv)
CryptReleaseContext(hProv, 0);

}



BOOL CryptAcquireContextEx(HCRYPTPROV *phProv, //out
LPTSTR pszContainer, //in
LPTSTR pszProvider, //in
DWORD dwProvType, //in
DWORD dwFlags, //in
DWORD dwKeySpec, //in
DWORD KeyFlags //in
)
{
DWORD dwError;
HCRYPTKEY hKey;
// Пытаемся открыть контейнер криптопровайдера
if(!CryptAcquireContext(phProv, pszContainer, pszProvider, dwProvType, dwFlags))
{
dwError = GetLastError();
if (dwError != NTE_BAD_KEYSET)
{
printf("Error: CryptAcquireContext=0x%X.\n", dwError);
return FALSE;
}
else
{
// Если контекст не существует, создаем новый
if (!CryptAcquireContext(phProv, pszContainer, pszProvider, dwProvType, dwFlags|CRYPT_NEWKEYSET))
{
printf("Error: CryptAcquireContext=0x%X.\n", GetLastError());
return FALSE;
}
}
}


// Если ключевая пара в контейнере отсутствует, создаем новую
if (!CryptGetUserKey(*phProv, dwKeySpec, &hKey))
{
if (!CryptGenKey(*phProv, dwKeySpec, CRYPT_EXPORTABLE, &hKey))
{
CryptReleaseContext(*phProv, 0);
printf("Error: CryptGetUserKey=0x%X.\n", GetLastError());
return FALSE;
}
}
// Освобождаем дескриптор ключа
CryptDestroyKey(hKey);

return TRUE;
}

Обсуждение

Неизвестный
12.10.2009, 03:16
общий
Roma2010:
Код:
CSP context acquired
The signature key has been acquired
Size of the blob for the public key determined
Memory has been allocated for the blob
Context have been written to the blob
0602000000240000525341310004000001000100af8c3778ccc27cc31ff600bc4f5ee5059ecaea6a
0ae713922eb4ce74f7d6f16dfcff74256bddcff9d285689129247c8973ffd3b84b518b9775185a4d
3a0c83c2a630884745dd8a8c8b8a3cf6e952322a6b7ad50b3d4a52b2d7baa227d244bad83566064e
198967d74596d2f21c3e4208a65b66cb89efb761156e18023f8276aa
Size of the blob for the private key pair determined
Memory has been allocated for the blob
Context have been written to the blob
0702000000240000525341320004000001000100af8c3778ccc27cc31ff600bc4f5ee5059ecaea6a
0ae713922eb4ce74f7d6f16dfcff74256bddcff9d285689129247c8973ffd3b84b518b9775185a4d
3a0c83c2a630884745dd8a8c8b8a3cf6e952322a6b7ad50b3d4a52b2d7baa227d244bad83566064e
198967d74596d2f21c3e4208a65b66cb89efb761156e18023f8276aaededbacb617d4f324bb1a5b5
1dd4ee7b769d628b940e8b14bb6634270025177a4cc14356b15002d6409a6a5480af9d25afd52ef3
29b6d9c319349f2db1bd69ec8b3126a5a728aa07cdc2d075788a6d57ed1cba96067f91fee401fa3e
c05e34397c9fdedf21ba2877aca5fbec1c6e19694cdcac1990e4b7c3aeb2ac8e9cfb95b84d61a17c
424d340c9ec32c7ae1c0d498fdc893111b4ffaa4f6c6b53db52afa4e14f67572176369c181001981
7065d12ea4cb6a80183ceee0eaf71bf4049a55a5fbc27dcd6ffce0576e2ee8976e0431cea92d27f3
b93c5ad540b8ab26698a2a8d3e61c651e08502106a35b829433b0268f77afd1e35e79ddbe7f1d454
27c1f8006399f076a6acf5e1f5bf70e0a828a828201c2efe09f45c8e5f0b1b315f10a6e6b926cdea
2a1365f11833db511c3790ca565c50b264ce638d7b572c54b1ed7b78b9a2c3cfc29b1068763295e6
5df94749c0043555421a4f4dc75bb06bd44d184605157b0282b73d5707b35643087b8da19e511484
1fceadb127ed54c1a0e682189ef0b8e087d5bd41c0b2cb1428afd82123419dadc60b0e01e868f88b
3e828f0905521101fa35a0770eb076bca5e451b8321699f0e2326280b0d2ce8a2553ba7b

Hash object created. Using MD5
The data buffer has been hashed
Signature length 128 found.
Memory allocated for the signature
pbSignature is the hash signature
The hash object has been destroyed
The signing phase of this program is completed

The key has been inported
The hash object has been recreated. Using MD5
The new has been created.
SIGNATURE VALIDATED OK!

Код:
// Необходимо подключить библиотеку crypt32.lib
// Компиляция с использованием Visual Studio 7.0

#include <conio.h>
#include "stdio.h"
#include "windows.h"
#include "wincrypt.h"

// Объявление функции CryptAcquireContextEx
BOOL
CryptAcquireContextEx(HCRYPTPROV *phProv, //out
LPTSTR pszContainer, //in
LPTSTR pszpRovider, //in
DWORD dwProvType, //in
DWORD dwFlags, //in
DWORD dwKeySpec, //in
DWORD KeyFlags //in
);
int main(int argc, char *argv[])
{
// Объявление и инициализация переменных.
HCRYPTPROV hProv=0;// Дескриптор провайдера
HCRYPTKEY hKey=0, hPubKey=0; // Дескприптор ключа
HCRYPTHASH hHash=0;
// Буфер данных для подписи
LPBYTE pbBuffer=(BYTE *)"The data that is to be hashed and signed.";
// Типа из командной строки
// LPBYTE pbBuffer;
LPTSTR szDescription=L"Test Data Description";
LPBYTE pbKeyBlob=NULL, pbSignature=NULL, PrivateBlob = NULL;
DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
DWORD dwSigLen=0, dwBlobLen=0,dwBlobLen1 = 0;
// ********************************************************************
// Первая фраза. Подпись сообщения.
// ********************************************************************
// Получение дискриптора криптопровайдера.
if (!CryptAcquireContextEx(&hProv, NULL, NULL, PROV_RSA_FULL, 0, AT_SIGNATURE, 0))
goto ReleaseResource;
printf("CSP context acquired\n");

// Получение дискриптора ключа подписи.
// AT_SIGNATURE - алгоритма открытых ключей
// являются основой для "Цифровых Подписей" (NIST Digital Signature Algorithm - DSA)
if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey))
{
printf("Error: CryptGetUserKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The signature key has been acquired\n");

// Для получения необходимого размера памяти параметр pbData равен NULL.
// Размер ключевого блока возвращается в параметре dwBlodLen
// PUBLICKEYBLOB - используется для сохранения открытых ключей.
// Поскольку открытые ключи не являются секретными, они сохраняются в незашифрованном виде;
if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen))
{
printf("Error: CryptExportKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("Size of the blob for the public key determined\n");

// Выделение памяти для pbKeyBlob.
pbKeyBlob = (LPBYTE)malloc (dwBlobLen);

if (!pbKeyBlob)
{
printf("Error: Out of memory\n");
goto ReleaseResource;
}
printf("Memory has been allocated for the blob\n");

// Экспорт открытого ключа пары подписи.
if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen))
{
printf("Error: CryptExportKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("Context have been written to the blob\n");

//выведем ключевой блоб открытого ключа
for (DWORD i = 0; i < dwBlobLen; i++)
printf("%02x",pbKeyBlob[i]);


//получим ключевой блоб ключевой пары
// Для получения необходимого размера памяти параметр pbData равен NULL.
// Размер ключевого блоба возвращается в параметре dwBlodLen1
if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwBlobLen1))
{
printf("Error: CryptExportKey=0x%X.\n", GetLastError());
goto ReleaseResource;
}
printf("\nSize of the blob for the private key pair determined\n");

// Выделение памяти для PrivateBlob
PrivateBlob = (LPBYTE)malloc (dwBlobLen1);

if (!PrivateBlob)
{
printf("Error: Out of memory\n");
goto ReleaseResource;
}
printf("Memory has been allocated for the blob\n");

// Экспорт секретного ключа пары подписи.
if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, PrivateBlob, &dwBlobLen1))
{
printf("Error: CryptExportKey=0x%X.\n", GetLastError());
goto ReleaseResource;
}
printf("Context have been written to the blob\n");

//выведем ключевой блоб пары
for (DWORD i = 0; i < dwBlobLen1; i++)
printf("%02x", PrivateBlob[i]);



// Создание объекта хеширования.
// CALG_MD5 - идентификатор алгоритма MD5
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
printf("Error: CryptCreateHash=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("\nHash object created. Using MD5\n");

// Хеширование буфера данных
if (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0))
{
printf("Error: CryptHashData=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The data buffer has been hashed\n");

// Определение необходимого размера памяти для буфера цифровой подписи.
if (!CryptSignHash(hHash, AT_SIGNATURE, szDescription, 0, NULL, &dwSigLen))
{
printf("Error: CryptSignHash=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("Signature length %d found.\n", dwSigLen);

// Выделение памяти под буфер цифровой подписи.
pbSignature = (LPBYTE)malloc(dwSigLen);
if (!pbSignature)
{
printf("Error: Out of memory\n");
goto ReleaseResource;
}
printf("Memory allocated for the signature\n");

// Вычисление цифровой подписи
if (!CryptSignHash(hHash, AT_SIGNATURE, szDescription, 0, pbSignature, &dwSigLen))
{
printf("Error: CryptSignHash=0x%X.\n", GetLastError());
goto ReleaseResource;
}
printf("pbSignature is the hash signature\n");


// Уничтожение объекта хеширования
if (hHash)
CryptDestroyHash(hHash);
hHash = 0;
printf("The hash object has been destroyed\n");
printf("The signing phase of this program is completed\n\n");


//************************************************** *********
// Вторая фаза. Проверка цифровой подписи сообщения
//************************************************** *********

// Импортируем открытый ключ в криптопровайдер
if (!CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey))
{
printf("Error: CryptImportKey=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The key has been inported\n");

// Создание нового объекта хеширования.
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
printf("Error: CryptCreateHash=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The hash object has been recreated. Using MD5\n");

// Хеширование буфера данных
if (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0))
{
printf("Error: CryptHashData=0x%X.\n",GetLastError());
goto ReleaseResource;
}
printf("The new has been created.\n");


// Проверка цифровой подписи
if (!CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, szDescription, 0))
{
if (GetLastError() == NTE_BAD_SIGNATURE)
printf("SIGNATURE FAILED TO VALIDATED");
else
printf("Error: CryptVerifySignature=0x%X.\n",GetLastError());
}
else
printf("SIGNATURE VALIDATED OK!\n");


ReleaseResource:


// Освобождаем память блоба открытого ключа
if (pbKeyBlob)
free(pbKeyBlob);
// Освобождаем память подписи
if (pbSignature)
free(pbSignature);
// Уничтожаем объект хеширования
if (hHash)
CryptDestroyHash(hHash);
// Освобождаем дескриптор криптопровайдера
if (hProv)
CryptReleaseContext(hProv, 0);

}



BOOL CryptAcquireContextEx(HCRYPTPROV *phProv, //out
LPTSTR pszContainer, //in
LPTSTR pszProvider, //in
DWORD dwProvType, //in
DWORD dwFlags, //in
DWORD dwKeySpec, //in
DWORD KeyFlags //in
)
{
DWORD dwError;
HCRYPTKEY hKey;
// Пытаемся открыть контейнер криптопровайдера
if(!CryptAcquireContext(phProv, pszContainer, pszProvider, dwProvType, dwFlags))
{
dwError = GetLastError();
if (dwError != NTE_BAD_KEYSET)
{
printf("Error: CryptAcquireContext=0x%X.\n", dwError);
return FALSE;
}
else
{
// Если контекст не существует, создаем новый
if (!CryptAcquireContext(phProv, pszContainer, pszProvider, dwProvType, dwFlags|CRYPT_NEWKEYSET))
{
printf("Error: CryptAcquireContext=0x%X.\n", GetLastError());
return FALSE;
}
}
}


// Если ключевая пара в контейнере отсутствует, создаем новую
if (!CryptGetUserKey(*phProv, dwKeySpec, &hKey))
{
if (!CryptGenKey(*phProv, dwKeySpec, CRYPT_EXPORTABLE, &hKey))
{
CryptReleaseContext(*phProv, 0);
printf("Error: CryptGetUserKey=0x%X.\n", GetLastError());
return FALSE;
}
}
// Освобождаем дескриптор ключа
CryptDestroyKey(hKey);

return TRUE;
}
Форма ответа