Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход. Новые регистрации запрещены.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline KSerega  
#1 Оставлено : 30 марта 2009 г. 23:45:51(UTC)
KSerega

Статус: Новичок

Группы: Участники
Зарегистрирован: 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. Ткните, плз, в соотв ф-цию.
Offline KSerega  
#2 Оставлено : 30 марта 2009 г. 23:47:31(UTC)
KSerega

Статус: Новичок

Группы: Участники
Зарегистрирован: 27.03.2009(UTC)
Сообщений: 2
Откуда: Kiev

сейчас читаю MSDN: Example C Program: Making a Certificate Request
завтра отпишусь что у меня вышло...
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.