| ||||
| ||||
подскажите пожалуйста пример использования компоненты xenroll для запроса , получения сертификатов открытых ключей для работы с функциями КриптоПро CPEncrypt CPDecrypt. Насколько я понял, данная компонента при генерации запроса сертификата автоматически генерит ключевые пары в обход CPGetUserKey. Откуда их можно извлечь после работы этой компоненты? И вообще корректный алгоритм использования рез-тов работы xenroll в функция CPEncrypt и CPDecrypt и в функциях подписи? | ||||
Ответы: | ||||
| ||||
Совсем не так. Xenroll является COM интерфейсом над некоторыми функциями CryptoAPI, которые используются для генерации ключей, создания запроса (PKCS#10) и обработки сертификатов (помещения их в Store). Он не может использовать никаких других функций для генерации ключей, кроме CPGenKey от выбранного (указанного) криптопровайдера. Примеры использования функций CryptEncrypt (CryptDecrypt) находятся в тестовом ПО http://www.cryptopro.ru/test/sample.zip Пример использования Xenroll для генерации ключей и установки сертификатов - центр сертификации Microsoft (ASP страницы \\winnt\system32\certsrv), страницы VeriSign (https://digitalid.verisign.com/client/class1MS.htm) Простенький пример для создания запроса и сохранения в файл: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <meta http-equiv="Content-Language" content="ru"> <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> <meta name="ProgId" content="FrontPage.Editor.Document"> <title>Генерация ключей</title> </head> <body> <table class="PageHeader" width="100%" height="32"> <tr> <td class="PageHeaderText" bgcolor="#000080" height="28"> <p align="right"><font color="#FFFFFF" face="Tahoma" size="4">Генерация ключей и запроса на сертификат</font></p> </td> </tr> </table> <hr> <p><font face="Tahoma" size="2"><font color="#000080">Пожалуйста, внимательно заполните поля для формирования запроса на сертификат. Обязательные для заполнения поля помечены </font><font color="#FF0000">красным</font><font color="#000080"> цветом. После генерации ключей запрос на сертификат будет сохранен в файл с именем, указанным в поле </font></font><font color="red" face="Tahoma" size="2">Имя файла для сохранения запроса.</font></p> <p><font color="#000080" face="Tahoma" size="2">Файл с запросом на сертификат должен быть передан в Удостоверяющий центр для формирования сертификата открытого ключа.</font></p> <hr> <form name="UIForm" onsubmit="SubmitRequest(); return false;"> <table cellspacing="0" cellpadding="4" width="662"> <tr> <td valign="center" align="right" class="Form" width="282"><font color="red" face="Tahoma" size="2"><b>Адрес электронной почты:</b></font></td> <td width="360"><input name="EMail" style="WIDTH: 300px" maxlength="128" size="20"></td> </tr> <tr> <td valign="center" align="right" class="Form" width="282"><font color="red" face="Tahoma" size="2"><b>Фамилия, Имя, Отчество (псевдоним):</b></font></td> <td width="360"><input name="Name" style="WIDTH: 300px" onkeyup="Validate()" maxlength="64" size="20"></td> </tr> <tr> <td valign="center" align="right" class="Form" width="282"><font face="Tahoma" size="2" color="#000080"><b>Организация:</b></font></td> <td width="360"><input name="Org" style="WIDTH: 300px" onkeyup="Validate()" maxlength="64" size="20"></td> </tr> <tr> <td valign="center" align="right" class="Form" width="282"><font face="Tahoma" size="2" color="#000080"><b>Подразделение:</b></font></td> <td width="360"><input name="OrgUnit" style="WIDTH: 300px" onkeyup="Validate()" maxlength="64" size="20"></td> </tr> <tr> <td valign="center" align="right" class="Form" width="282"><font color="red" face="Tahoma" size="2"><b>Имя файла для сохранения запроса:</b></font></td> <td width="360"><input name="FileName" style="WIDTH: 300px" onkeyup="Validate()" maxlength="64" size="20"></td> </tr> </table> <input type="hidden" name="PKCS10"> <hr> <p align="right"><input type="submit" value="Продолжить >>" name="Submit" disabled></p> </form> <SCRIPT Language="VBScript"> 'Проверка вводимых значений на лету Sub Validate() UIForm.Submit.disabled = true If (Len(Trim(UIForm.EMail.value))>0) and _ (Len(Trim(UIForm.Name.value))>0) then If (Len(Trim(UIForm.FileName.value))>0) then UIForm.Submit.disabled = false End if Else UIForm.Submit.disabled = true End if End sub Function CheckValues() CheckValues = false 'Формат E-Mail if InStr(UIForm.EMail.value,"@") < 2 or _ InStr(UIForm.EMail.value,"@") = Len(UIForm.EMail.value) then MsgBox "Неверно указан адрес электронной почты (E-Mail). Неправильный формат." UIForm.EMail.focus exit function end if CheckValues = true exit function End Function Function SubmitRequest() ' check values If not CheckValues() then SubmitRequest = false exit function End if ' make DN string Dim strDN strDN = "C=RU" strDN = "CN=" & UIForm.Name.value strDN = strDN & ",OU=" & UIForm.OrgUnit.value strDN = strDN & ",O=" & UIForm.Org.value strDN = strDN & ",E=" & UIForm.EMail.value Dim usage 'Send request XEnroll.ProviderType = 2 XEnroll.ProviderName = "Crypto-Pro Cryptographic Service Provider" XEnroll.KeySpec=1 'AT_KEYEXCHANGE=1; 'AT_SIGNATURE=2; usage = "1.3.6.1.5.5.7.3.2" UIForm.PKCS10.value=XEnroll.createPKCS10(strDN, usage) a= WriteFileData (UIForm.FileName.value, UIForm.PKCS10.value) If a<>0 Then MsgBox Err.Description End If 'RequestForm.submit End Function Function WriteFileData(sFileName, sData) Dim filesystem, file 'On Error Resume Next ' First, create the FileSystem object Set filesystem = CreateObject("Scripting.FileSystemObject") ' Security may not allow this If Err.number<>0 Then WriteFileData=Err.number Exit Function End If ' check for existing file Dim bExists bExists=filesystem.FileExists(sFileName) If 0<>Err.Number Then WriteFileData=Err.number Exit Function End If If True=bExists Then 'file exists. Overwrite? If False=myConfirm("The file '" & sFileName & "' already exists. Overwrite?") Then WriteFileData=58 'File Already Exists Exit Function End If End If ' open the specified file Set file=filesystem.OpenTextFile(sFileName, 2, true) '2->ForWriting, true->create If Err.Number<>0 Then WriteFileData=Err.number Exit Function End If ' read the data and stash it into the form file.Write sData ' catch any read errors If Err.Number<>0 Then WriteFileData=Err.number Exit Function End If ' clean up file.Close Set file=Nothing Set filesystem=Nothing WriteFileData=0 MsgBox "Запрос на сертификат сохранен в файл " & sFileName End Function </SCRIPT> <SCRIPT Language="JavaScript"> function myConfirm(sPrompt) { return confirm(sPrompt); } </SCRIPT> <object classid="clsid:43F8F289-7A20-11D0-8F06-00C04FC295E1" id="XEnroll" / width="14" height="14"> </body> </html> </object> </body> Простенький пример установки сертификата на VBS: Option Explicit Const ForReading = 1, ForWriting = 2 Dim xenroll Dim PKCS7, ret Set xenroll = CreateObject("CEnroll.CEnroll.1") LoadFile Wscript.Arguments(0), PKCS7 xenroll.DeleteRequestCert = FALSE xenroll.WriteCertToCSP = TRUE Wscript.Echo xenroll.MyStoreName Wscript.Echo xenroll.MyStoreFlags 'Wscript.Echo xenroll.MyStoreType Wscript.Echo PKCS7 xenroll.CAStoreName = "My" xenroll.InstallPKCS7 (PKCS7) If 0=Err.Number Then Wscript.Echo "Сертификат OK" Else Wscript.Echo "Сертификат не мог быть инсталлирован" End If Sub LoadFile (FileName, Buffer) Dim fso Set fso = CreateObject("Scripting.FileSystemObject") If Not fso.FileExists(FileName) Then MsgBox "Error: " & FileName & " file not found." Exit Sub End If Dim ts Set ts = fso.OpenTextFile(FileName, ForReading) Buffer = ts.ReadAll End Sub | ||||
| ||||
Перевел Ваш пример на С++ При createPKCS10 получаю ошибку 80090019 - ключевой набор не установлен BSTR bstrreq=NULL; ICEnroll * pEnroll = NULL; // variable for return value HRESULT hr; // Initialize COM. hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); // Check status. if ( FAILED( hr ) ) { sprintf(str1,"Failed CoInitializeEx - [%x]", hr); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); goto error; } // Create an instance of the object. hr = CoCreateInstance( CLSID_CEnroll, NULL, CLSCTX_INPROC_SERVER, IID_ICEnroll, (void **)&pEnroll); // Check status. if ( FAILED( hr ) ) { sprintf(str1,"Failed CoCreateInstance - pEnroll [%x]", hr); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); goto error; } else { // Successfully instantiated object. sprintf(str1,"Obtained pointer to Enrollment interface"); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); // Use object as needed. // ... } hr = pEnroll->put_ProviderName((wchar_t*)"Crypto-Pro Cryptographic Service Provider"); if (FAILED( hr )) { sprintf(str1,"Failed put_ProviderName - %x", hr ); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); goto error; } else { sprintf(str1,"ProviderName set"); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); } hr = pEnroll->put_KeySpec( AT_KEYEXCHANGE ); if (FAILED( hr )) { sprintf(str1,"Failed put_KeySpec - %x", hr ); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); goto error; } else { sprintf(str1,"KeySpec set to %d", AT_KEYEXCHANGE ); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); } hr = pEnroll->put_ProviderType(2); if (FAILED(hr)) { sprintf(str1,"Failed put_ProviderType - %x", hr); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); goto error; } else { sprintf(str1,"ProviderType set"); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); } strcpy(str1,"CN=Your Name,OU=Your Unit,O=Your Org,L=Redmond,S=Washington,C=US"); hr=pEnroll->createPKCS10((wchar_t*)str1,(wchar_t*)"1.3.6.1.5.5.7.3.2",&bstrreq); if (FAILED(hr)) { sprintf(str1,"Failed createPKCS10 - %x", hr); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); goto error; } else { // Success. sprintf(str1,"Successfully created file containing PKCS10"); MessageBox(NULL,str1,"qq",MB_OK|MB_TASKMODAL); } error: // Done processing. // Clean up resources. if ( NULL != pEnroll ) pEnroll->Release(); // Free COM resources. CoUninitialize(); //return hr; | ||||