06.07.2006 10:45:09запрос на получение сертификата Ответов: 2
Дмитрий
Привет, всем! Помогите пожалуйста разобраться с созданием запроса на получение сертификата. Формирование запроса сделал, на основе одной из статей, которые рекомндуют здесь. В результате работы получаю файл запроса, но вид у него несколько старнный:очень много непечатных символов, а строка szOID_COMMON_NAME вообще остается не зашифрованной в этом файле. Подскажите, что я делаю не так.

procedure TCreateReqForm.OKBtnClick(Sender: TObject);
var nameAttr: CERT_RDN_ATTR;
nameString: PChar;
rdn: CERT_RDN;
nameInfo: CERT_NAME_INFO;
certReqInfo: CERT_REQUEST_INFO;
subjNameBlob: CERT_NAME_BLOB;
encNameLen: DWORD;
encName: PBYTE;
prov: HCRYPTPROV;
pubKeyInfoLen: DWORD;
pubKeyInfo: PCERT_PUBLIC_KEY_INFO;
encCertReqLen: DWORD;
params: CRYPT_OBJID_BLOB;
sigAlg: CRYPT_ALGORITHM_IDENTIFIER;
signedEncCertReq: PBYTE;
cont: PChar;
err: string;
encType: DWORD;
f: file;
hKey :HCRYPTKEY;

begin
encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
nameString := StrAlloc(length(SubjectEdit.text)+1);
StrPCopy(nameString, SubjectEdit.Text);
nameAttr.pszObjId := szOID_COMMON_NAME;//'2.5.4.3';
nameAttr.dwValueType := CERT_RDN_PRINTABLE_STRING;
nameAttr.Value.cbData := length(SubjectEdit.text);
nameAttr.Value.pbData := PBYTE(nameString);
rdn.cRDNAttr := 1;
rdn.rgRDNAttr := @nameAttr;
nameInfo.cRDN := 1;
nameInfo.rgRDN := @rdn;

if length(ContainerEdit.Text) = 0
then cont := nil
else
begin
err := ContainerEdit.Text;
cont := StrAlloc(length(err) + 1);
StrPCopy(cont, err);
end;

CryptAcquireContext(@prov, cont, 'Crypto-Pro Cryptographic Service Provider', 2, 0);
CryptGenKey(Prov, (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or 36), CRYPT_EXPORTABLE, @hKey);
CryptEncodeObject(encType, X509_NAME,@nameInfo, nil, @encNameLen);
GetMem(encName, encNameLen);
CryptEncodeObject(encType, X509_NAME,@nameInfo, encName, @encNameLen);

subjNameBlob.cbData := encNameLen;
subjNameBlob.pbData := encName;
certReqInfo.Subject := subjNameBlob;
certReqInfo.cAttribute := 0;
certReqInfo.rgAttribute := nil;
certReqInfo.dwVersion := CERT_REQUEST_V1;

CryptExportPublicKeyInfo (prov, AT_KEYEXCHANGE, encType, nil, @pubKeyInfoLen);
GetMem(pubKeyInfo, pubKeyInfoLen);
CryptExportPublicKeyInfo (prov, AT_KEYEXCHANGE, encType, pubKeyInfo, @pubKeyInfoLen);

certReqInfo.SubjectPublicKeyInfo := pubKeyInfo^;
FillChar(params, sizeof(params), 0);
sigAlg.pszObjId :='1.2.643.2.2.4';//szOID_OIWSEC_sha1RSASign;
sigAlg.Parameters := params;

CryptSignAndEncodeCertificate (prov, AT_KEYEXCHANGE, encType,
X509_CERT_REQUEST_TO_BE_SIGNED, @certReqInfo, @sigAlg, nil, nil,
@encCertReqLen);

GetMem(signedEncCertReq, encCertReqLen);

CryptSignAndEncodeCertificate (prov, AT_KEYEXCHANGE, encType, X509_CERT_REQUEST_TO_BE_SIGNED,
@certReqInfo, @sigAlg, nil, signedEncCertReq, @encCertReqLen);

if SaveDlg.Execute then
begin
AssignFile(f, SaveDlg.FileName);
rewrite(f, 1);
BlockWrite(f, signedEncCertReq^, encCertReqLen);
CloseFile(f);
end;

StrDispose(nameString);
FreeMem(encName, encNameLen);
if cont <> nil then StrDispose(cont);
FreeMem(pubKeyInfo, pubKeyInfoLen);
FreeMem(signedEncCertReq, encCertReqLen);
if not CryptReleaseContext(prov, 0) then
begin
MessageDlg('&#206;&#248;&#232;&#225;&#234;&#224; &#238;&#241;&#226;&#238;&#225;&#238;&#230;&#228;&#229;&#237;&#232;&#255; &#234;&#238;&#237;&#242;&#229;&#234;&#241;&#242;&#224;', mtError, [mbOK], 0);
end;
end;
 
Ответы:
06.07.2006 10:55:35Kirill Sobolev
Наличие непечатных символов и "незашифрованного" имени это вполне нормально. Главная проверка - принимает ли этот запрос ЦС, например служба сертификации MS? Для этого его правда придется преобразовать в base64.
10.04.2007 9:12:56Волков
А как его преобразовать в base64?