Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программное создание сертификата 
:(
    Опции темы
xTr1m
Дата 16.10.2008, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



Доброго времени суток. Пытаюсь осуществить САБЖ. Пример кода взял в инете + кое-что от себя
Код

int CreateCert()
{
    DWORD dwSize;;
    LPCSTR sFileName = "Тестовый сертификат";    

    CERT_RDN_ATTR rgNameAttr[1] = {
        szOID_COMMON_NAME, // pszObjId
        CERT_RDN_PRINTABLE_STRING, // dwValueType
        strlen(sFileName), // value.cbData
        (BYTE*)sFileName}; // value.pbData

        CERT_RDN rgRDN[] = {
            1, // rgRDN[0].cRDNAttr
            &rgNameAttr[0]}; // rgRDN[0].rgRDNAttr

            CERT_NAME_INFO Name = {
                1, // Name.cRDN
                rgRDN}; // Name.rgRDN

                //-------------------------------------------------------------------
                // Declare and initialize all other variables and structures.

                CERT_REQUEST_INFO CertReqInfo;
                CERT_NAME_BLOB SubjNameBlob;
                DWORD cbNameEncoded;
                BYTE* pbNameEncoded;
                HCRYPTPROV hCryptProv;
                DWORD cbPublicKeyInfo;
                CERT_PUBLIC_KEY_INFO* pbPublicKeyInfo;
                CRYPT_OBJID_BLOB Parameters;
                CRYPT_ALGORITHM_IDENTIFIER SigAlg;
                BYTE* pbSignedEncodedCertReq;
                char* pSignedEncodedCertReqBlob;
                BOOL bResult = FALSE;
                LPSTR szContainer = NULL;
                //CHAR* szProvider = CP_DEF_PROV;
                CHAR* szProvider = MS_ENHANCED_PROV;
                DWORD dwProviderType = PROV_RSA_FULL; //PROV_GOST_DH; //PROV_RSA_FULL;
                RPC_STATUS Status;

                if(CryptEncodeObject(
                    (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
                    X509_NAME, // Structure type
                    &Name, // Address of CERT_NAME_INFO structure
                    NULL, // pbEncoded
                    &cbNameEncoded)) // pbEncoded size
                {
                    printf("The first call to CryptEncodeObject succeeded. \n");
                }
                else
                {
                    printf("First call to CryptEncodeObject failed.\
                           \nA public/private key pair may not exit in the container. \n");
                }
                //-------------------------------------------------------------------
                // Allocate memory for the encoded name.

                if(!(pbNameEncoded = (BYTE*)malloc(cbNameEncoded)))
                    printf("pbNamencoded malloc operation failed.\n");

                //-------------------------------------------------------------------
                // Call CryptEncodeObject to do the actual encoding of the name.

                if(CryptEncodeObject(
                    (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
                    X509_NAME, // Structure type
                    &Name, // Address of CERT_NAME_INFO structure
                    pbNameEncoded, // pbEncoded
                    &cbNameEncoded)) // pbEncoded size
                {
                    printf("The object is encoded. \n");
                }
                else
                {
                    free(pbNameEncoded);
                    printf("Second call to CryptEncodeObject failed.\n");
                }
                //--------------------------------------------------------------------
                // Set the subject member of CertReqInfo to point to
                // a CERT_NAME_INFO structure that
                // has been initialized with the data from cbNameEncoded
                // and pbNameEncoded.

                SubjNameBlob.cbData = cbNameEncoded;
                SubjNameBlob.pbData = pbNameEncoded;
                CertReqInfo.Subject = SubjNameBlob;

                //--------------------------------------------------------------------
                // Generate custom information. This step is not
                // implemented in this code.

                CertReqInfo.cAttribute = 0;
                CertReqInfo.rgAttribute = NULL;
                CertReqInfo.dwVersion = CERT_V1;                            

                /* Create new crypto context*/
                CString sss = "lolilol" ;
                bResult = CryptAcquireContext(&hCryptProv, sss, szProvider, dwProviderType, CRYPT_MACHINE_KEYSET);
                if (!bResult)
                {
                    printf("CryptAcquireContext failed with %x\n", GetLastError());
                }
                bResult = CryptSetProvParam(hCryptProv, PP_KEYEXCHANGE_PIN, (BYTE*)"pass", 0);
                if (!bResult)
                {
                    printf("CryptSetProvParam failed with %x\n", GetLastError());
                }
                DWORD dwKeyType = AT_KEYEXCHANGE;
                HCRYPTKEY hPubKey = 0;
                /* Generate Private/Public key pair*/
                bResult = CryptGenKey(hCryptProv, dwKeyType, CRYPT_EXPORTABLE, &hPubKey);
                if (!bResult)
                {
                    printf("CryptGenKey failed with %x\n", GetLastError());
                }

                if(CryptExportPublicKeyInfo(
                    hCryptProv, // Provider handle
                    dwKeyType, // Key spec
                    (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
                    NULL, // pbPublicKeyInfo
                    &cbPublicKeyInfo)) // Size of PublicKeyInfo
                {
                    printf("The keyinfo structure is %d bytes.\n",cbPublicKeyInfo);
                }
                else
                {
                    free(pbNameEncoded);
                    printf("First call to CryptExportPublickKeyInfo failed.\
                           \nProbable cause: No key pair in the key container. Error = %d\n", GetLastError());
                }

                if(pbPublicKeyInfo =
                    (CERT_PUBLIC_KEY_INFO*)malloc(cbPublicKeyInfo))
                {
                    printf("Memory is allocated for the public key structure. \n");
                }
                else
                {
                    free(pbNameEncoded);
                    printf("Memory allocation failed.");
                }

                if(CryptExportPublicKeyInfo(
                    hCryptProv, // Provider handle
                    dwKeyType, // Key spec
                    (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
                    pbPublicKeyInfo, // pbPublicKeyInfo
                    &cbPublicKeyInfo)) // Size of PublicKeyInfo
                {
                    printf("The key has been exported. \n");
                }
                else
                {
                    free(pbNameEncoded);
                    free(pbPublicKeyInfo);
                    printf("Second call to CryptExportPublicKeyInfo failed.");
                }
                //--------------------------------------------------------------------
                // Set the SubjectPublicKeyInfo member of the
                // CERT_REQUEST_INFO structure to point to the CERT_PUBLIC_KEY_INFO
                // structure created.

                CertReqInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo;

                memset(&Parameters, 0, sizeof(Parameters));
                SigAlg.pszObjId = szOID_OIWSEC_sha1RSASign;
                SigAlg.Parameters = Parameters;

                //--------------------------------------------------------------------
                // Call CryptSignAndEncodeCertificate to get the size of the
                // returned BLOB.

                if(CryptSignAndEncodeCertificate(
                    hCryptProv, // Crypto provider
                    AT_KEYEXCHANGE, // Key spec
                    (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
                    X509_CERT_REQUEST_TO_BE_SIGNED, // Structure type
                    &CertReqInfo, // Structure information
                    &SigAlg, // Signature algorithm
                    NULL, // Not used
                    NULL, // pbSignedEncodedCertReq
                    &dwSize)) // Size of certificate
                    // required
                {
                    printf("The size of the encoded certificate is set. \n");
                }
                else
                {
                    free(pbNameEncoded);
                    free(pbPublicKeyInfo);
                    printf("First call to CryptSignandEncode failed.");
                }

                ShowError(GetLastError());

                
                //--------------------------------------------------------------------
                // Allocate memory for the encoded certificate request.

                if(pbSignedEncodedCertReq = (BYTE*)malloc(dwSize))
                {
                    printf("Memory has been allocated.\n");
                }
                else
                {
                    free(pbNameEncoded);
                    free(pbPublicKeyInfo);
                    printf("Malloc operation failed.");
                }
                //--------------------------------------------------------------------
                // Call CryptSignAndEncodeCertificate to get the
                // returned BLOB.

                if(CryptSignAndEncodeCertificate(
                    hCryptProv, // Crypto provider
                    AT_KEYEXCHANGE, // Key spec
                    (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type
                    X509_CERT_REQUEST_TO_BE_SIGNED, // Struct type
                    &CertReqInfo, // Struct info
                    &SigAlg, // Signature algorithm
                    NULL, // Not used
                    pbSignedEncodedCertReq, // Pointer
                    &dwSize)) // Length of the message
                {
                    printf("The message is encoded and signed. \n");
                }
                else
                {
                    free(pbNameEncoded);
                    free(pbPublicKeyInfo);
                    printf("Second call to CryptSignAndEncode failed.");
                }                

                //серийный номер сертификата    
                char* pData= new char[39];
                GUID certID;
                CoCreateGuid(&certID);    
                CLSIDtochar(certID, pData, 39);
                long lCRC= GetCRC32(pData, 39);

                PBYTE pDataCRC= NULL; pDataCRC= new BYTE [4];
                PBYTE b= (BYTE*)&lCRC;
                int i, num= dwSize;                

                for(i= 0; i<sizeof(long); ++i)    pDataCRC[i]=b[i];                

                //имя файла - серийный номер сертификата
                int sz= 9;
                CString flName;
                
                LPTSTR flBuf= flName.GetBuffer(sz);
                ByteToStr(4, pDataCRC, flBuf);

                for(int n= 0; n<sz/2; n++)//реверс байтов
                {
                    char chr= flBuf[n];
                    flBuf[n]= flBuf[sz-n-2-1];
                    flBuf[sz-n-2-1]= chr;
                    n++;
                    chr= flBuf[n];
                    flBuf[n]= flBuf[sz-n-1];
                    flBuf[sz-n-1]= chr;
                } 
                flName.ReleaseBuffer();

                int iBlobLen= 2*dwSize + 1;
                LPTSTR szSignedEncodedCertBlob= certEncodBLOB.GetBuffer(iBlobLen);
                ByteToStr(dwSize, pbSignedEncodedCertReq, szSignedEncodedCertBlob);    
#ifdef _DEBUG
                WriteToFile(_CertStorePath+flName+".cer", pbSignedEncodedCertReq, num);                    
#endif
                certEncodBLOB.ReleaseBuffer();
                if(hCryptProv) CryptReleaseContext(hCryptProv,0);


                return 1;
}
.

 Сертификат создается, но при попытке его открыть получаю сообщение о том, что "Этот файл не может использоваться как: Сертификат безопасности". Вроде все обязательные поля записал, может кто сталкивался? Буду благодарен  smile 
PM MAIL WWW ICQ   Вверх
eyeofhell
Дата 16.10.2008, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Адепт
*


Профиль
Группа: Участник
Сообщений: 87
Регистрация: 16.10.2008
Где: Россия, Москва

Репутация: нет
Всего: 1



Есть OpenSSL в исходниках. Там есть функция создания сертификата. Проще посмотреть как она работает и переписать ее.
PM MAIL ICQ   Вверх
xTr1m
Дата 17.10.2008, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



Спс, исходники скачал. Но в этой тонне информации утонул, пока не могу найти нужной функции  smile 
PM MAIL WWW ICQ   Вверх
xTr1m
Дата 17.10.2008, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва

Репутация: 1
Всего: 1



Кстати, а может я просто не совсем понимаю, что делаю. Мой код, вроде, создает запрос на создание сертификата, а можно ли вообче сразу открыть такой сертификат или его нужно сначала подписать?
PM MAIL WWW ICQ   Вверх
modernx
Дата 10.6.2009, 17:59 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 17.5.2009

Репутация: нет
Всего: нет



Цитата(xTr1m @  17.10.2008,  09:10 Найти цитируемый пост)
Кстати, а может я просто не совсем понимаю, что делаю. Мой код, вроде, создает запрос на создание сертификата, а можно ли вообче сразу открыть такой сертификат или его нужно сначала подписать? 


Да, запросы так открывать нельзя.
PM MAIL   Вверх
zim22
Дата 10.6.2009, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(modernx @  10.6.2009,  17:59 Найти цитируемый пост)
Да, запросы так открывать нельзя.

дата сообщения, на которые вы ответили: 17.10.2008, 09:10
вас это не смущает?



--------------------
PM MAIL   Вверх
jonie
Дата 10.6.2009, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



.. уже и CryptoAPI "допилили" до CAPICOM, работает начиная с Vista.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
andrew_121
Дата 10.6.2009, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(zim22 @  10.6.2009,  18:05 Найти цитируемый пост)
дата сообщения, на которые вы ответили: 17.10.2008, 09:10

ГЫ)))
Как такое возможно? Форум же штампует дату не из локального времени машины пользователя...

Добавлено через 1 минуту и 29 секунд
Ааа...
Так это тема была создана той даты smile 
А то я уже начал глупости подумывать smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0836 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.