Статус: Новичок
Группы: Участники
Зарегистрирован: 27.03.2009(UTC) Сообщений: 2 Откуда: Kiev
|
Генерю SUBJ на Open SSL: 1. Создаю ключи (приватный и на подпись): openssl req -new -newkey rsa:1024 -nodes -keyout vasyapupkin.key -out vasyapupkin.csr -subj /CN=VASYAPUPKIN/OU=ExternOrgUnit 2. Открытый ключ запроса vasyapupkin.csr отдаётся в иную организацию которая на его основе возвращает клиентский сертификат (vasyapupkin.crt) и свой корневой сертификат ca.crt. 3. Экспортирую cертификат vasyapupkin.crt в PKCS #12 файл с паролем под своим приватным ключём vasyapupkin.key: openssl pkcs12 -export -in vasyapupkin.crt -inkey vasyapupkin.key -certfile ca.crt -out vasyapupkin.p12 -passout pass:PupkinPass 4. Устанавливаю под Виндой в хранилище сертификатов: - ca.crt - в Доверенный корневой центр сертификации - vasyapupkin.p12 - в Личное хранилище. Это всё делается вручную и отлично работает, но нужно теперь это (пункты 1, 3 и 4) реализовать без OpenSSL (т.е. автоматизировать) - на win CryptoAPI. Вот здесь у меня и траблы... Для начала пытался выполнить п.1: Код:
#include "Wincrypt.h"
#pragma comment(lib, "Advapi32.lib")
#define CERT_OUT_DIR CString(_T("c:\\OutCert"))
#define PUPKIN ВашеИмя // see GetUserName
BOOL SaveCert(IN LPCTSTR szFileCertName, IN HCRYPTKEY hKey, IN DWORD dwBlobType);
BOOL GenClientKeys(IN LPCTSTR szUserName);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
CString strUser = PUPKIN;
BOOL bRes = GenClientKeys(strUser);
return 0;
}
BOOL GenClientKeys(IN LPCTSTR szUserName) {
DWORD dwErrCode = NO_ERROR;
BOOL bRes = TRUE;
// open provider
HCRYPTPROV hProv = NULL;
{
CString strContainer = szUserName;
bRes = ::CryptAcquireContext(&hProv, strContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, 0);
if (!bRes) {
dwErrCode = ::GetLastError();
// err
}
}
// create key
HCRYPTKEY hKey = NULL;
if (bRes) {
bRes = ::CryptGenKey(hProv, CALG_RSA_KEYX, CRYPT_EXPORTABLE | (1024<<16), &hKey);
if (!bRes) {
dwErrCode = ::GetLastError();
// err
}
}
// export pub to file
if (bRes) {
bRes = SaveCert(CString(szUserName)+_T("_public_request.csr"), hKey, PUBLICKEYBLOB);
if (!bRes) {
dwErrCode = ::GetLastError();
// err
}
}
// export private to file
if (bRes) {
bRes = SaveCert(CString(szUserName)+_T("_private.key"), hKey, PRIVATEKEYBLOB);
if (!bRes) {
dwErrCode = ::GetLastError();
// err
}
}
// clean
if (hKey)
::CryptDestroyKey(hKey);
if (hProv)
::CryptReleaseContext(hProv, 0);
::SetLastError(dwErrCode);
return 0;
}
BOOL SaveCert(IN LPCTSTR szFileCertName, IN HCRYPTKEY hKey, IN DWORD dwBlobType) {
DWORD dwErrCode = NO_ERROR;
// get size blob
DWORD dwDataLen = 0;
BOOL bRes= ::CryptExportKey(hKey, NULL, dwBlobType, 0, NULL, &dwDataLen) && !!dwDataLen;
if (!bRes) {
dwErrCode = ::GetLastError();
// err
}
// get blob
BYTE *pbData = NULL;
if (bRes) {
pbData = new BYTE [dwDataLen];
bRes = !!pbData;
if (!bRes) {
dwErrCode = ERROR_OUTOFMEMORY;
} else {
bRes= ::CryptExportKey(hKey, NULL, dwBlobType, 0, pbData, &dwDataLen);
if (!bRes) {
dwErrCode = ::GetLastError();
// err
}
}
}
// save file
HANDLE hFile = INVALID_HANDLE_VALUE;
if (bRes) {
bRes = ::CreateDirectory(CERT_OUT_DIR, NULL);
CString strFile = CERT_OUT_DIR +_T('\\')+szFileCertName;
hFile = ::CreateFile(strFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
bRes = (hFile != INVALID_HANDLE_VALUE);
if (!bRes) {
dwErrCode = ::GetLastError();
// err
} else {
DWORD dwNBW = 0;
bRes = ::WriteFile(hFile, pbData, dwDataLen, &dwNBW, NULL) && (dwDataLen == dwNBW);
if (!bRes) {
dwErrCode = ::GetLastError();
// err
} else {
// Ok
}
}
}
// clean
if (hFile != INVALID_HANDLE_VALUE)
::CloseHandle(hFile);
if (pbData)
delete [] pbData;
::SetLastError(dwErrCode);
return bRes;
}
Я получил на выход файлы ключей, но они в другом формате чем при работе с openssl. Как их сконвертить? И я так и не понял, как можно внести инфу об CN и OU. Ткните, плз, в соотв ф-цию.
|