Статус: Активный участник
Группы: Участники
Зарегистрирован: 26.08.2010(UTC) Сообщений: 38 Откуда: Санкт-Петербург
Сказал(а) «Спасибо»: 21 раз
|
Здравствуйте, криптоАРМ не принимает запрос на сертификат. Вот функция в которой создаю запрос на сертификат. Код:
char* createRequest() {
size_t i;
char *UserName_C = new char[100];
wcstombs_s(&i, UserName_C, (size_t)100, CommonName, (size_t)100);
/*
CERT_RDN_ATTR rgNameAttr[] = {
"2.5.4.3", // pszObjId
CERT_RDN_PRINTABLE_STRING, // dwValueType
strlen(UserName_C), // value.cbData
(BYTE*)UserName_C };
*/
CERT_RDN_ATTR *rgNameAttr = new CERT_RDN_ATTR[6];//DN_count];
rgNameAttr[0].pszObjId = "2.5.4.3";
rgNameAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
rgNameAttr[0].Value.cbData = strlen(UserName_C);
rgNameAttr[0].Value.pbData = (BYTE*)UserName_C;
rgNameAttr[1].pszObjId = "2.5.4.6";
rgNameAttr[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
rgNameAttr[1].Value.cbData = strlen("RU");
rgNameAttr[1].Value.pbData = (BYTE*)"RU";
rgNameAttr[2].pszObjId = "2.5.4.7";
rgNameAttr[2].dwValueType = CERT_RDN_PRINTABLE_STRING;
rgNameAttr[2].Value.cbData = strlen("Moscow");
rgNameAttr[2].Value.pbData = (BYTE*)"Moscow";
rgNameAttr[3].pszObjId = "2.5.4.8";
rgNameAttr[3].dwValueType = CERT_RDN_PRINTABLE_STRING;
rgNameAttr[3].Value.cbData = strlen("Russia");
rgNameAttr[3].Value.pbData = (BYTE*)"Russia";
rgNameAttr[4].pszObjId = "2.5.4.10";
rgNameAttr[4].dwValueType = CERT_RDN_PRINTABLE_STRING;
rgNameAttr[4].Value.cbData = strlen("Roga i Kopita");
rgNameAttr[4].Value.pbData = (BYTE*)"Roga i Kopita";
rgNameAttr[5].pszObjId = "1.2.840.113549.1.9.1";
rgNameAttr[5].dwValueType = CERT_RDN_PRINTABLE_STRING;
rgNameAttr[5].Value.cbData = strlen("email@test.com");
rgNameAttr[5].Value.pbData = (BYTE*)"email@test.com";
CERT_RDN rgRDN[] = {6, &rgNameAttr[0]};
CERT_NAME_INFO Name = {1, rgRDN};
CERT_REQUEST_INFO CertReqInfo;
CERT_NAME_BLOB SubjNameBlob;
DWORD cbNameEncoded;
BYTE* pbNameEncoded;
DWORD cbPublicKeyInfo;
CERT_PUBLIC_KEY_INFO* pbPublicKeyInfo;
DWORD cbEncodedCertReqSize;
CRYPT_OBJID_BLOB Parameters;
CRYPT_ALGORITHM_IDENTIFIER SigAlg;
BYTE* pbSignedEncodedCertReq;
char* pSignedEncodedCertReqBlob;
if (CryptEncodeObject(
MY_ENCODING_TYPE, // 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
{
HandleError("The first call to CryptEncodeObject failed. \nA public/private key pair may not exit in the container. \n");
}
if (!(pbNameEncoded = (BYTE*)malloc(cbNameEncoded)))
HandleError("The pbNamencoded malloc operation failed. \n");
if (CryptEncodeObject(
MY_ENCODING_TYPE, // 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);
HandleError("The second call to CryptEncodeObject failed. \n");
}
SubjNameBlob.cbData = cbNameEncoded;
SubjNameBlob.pbData = pbNameEncoded;
CertReqInfo.Subject = SubjNameBlob;
CertReqInfo.cAttribute = 0;
CertReqInfo.rgAttribute = NULL;
CertReqInfo.dwVersion = CERT_REQUEST_V1;
//!!!!!!!!!!!!!!!!!!!!!!
if (CryptAcquireContext(
&hCryptProv, // Address for handle to be returned.
CommonName, // Use the current user's logon name.
ProviderName, // Use the default provider.
75, // Need to both encrypt and sign.
NULL)) // No flags needed.
{
printf("A cryptographic provider has been acquired. \n");
}
else
{
free(pbNameEncoded);
HandleError("CryptAcquireContext failed. \n");
}
if (CryptExportPublicKeyInfo(
hCryptProv, // Provider handle
AT_KEYEXCHANGE, // Key spec
MY_ENCODING_TYPE, // Encoding type
NULL, // pbPublicKeyInfo
&cbPublicKeyInfo)) // Size of PublicKeyInfo
{
printf("The keyinfo structure is %d bytes. \n", cbPublicKeyInfo);
}
else
{
free(pbNameEncoded);
HandleError("The first call to CryptExportPublickKeyInfo failed. \nThe probable cause is that \nthere is no key pair in the key container. \n");
}
if (pbPublicKeyInfo = (CERT_PUBLIC_KEY_INFO*)malloc(cbPublicKeyInfo))
{
printf("Memory is allocated for the public key structure. \n");
}
else
{
free(pbNameEncoded);
HandleError("Memory allocation failed. \n");
}
if (CryptExportPublicKeyInfo(
hCryptProv, // Provider handle
AT_KEYEXCHANGE, // Key spec
MY_ENCODING_TYPE, // Encoding type
pbPublicKeyInfo, // pbPublicKeyInfo
&cbPublicKeyInfo)) // Size of PublicKeyInfo
{
printf("The key has been exported. \n");
}
else
{
free(pbNameEncoded);
free(pbPublicKeyInfo);
HandleError("The second call to CryptExportPublicKeyInfo failed. \n");
}
CertReqInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo;
memset(&Parameters, 0, sizeof(Parameters));
SigAlg.pszObjId = szOID_CP_GOST_R3411;
SigAlg.Parameters = Parameters;
if (CryptSignAndEncodeCertificate(
hCryptProv, // Crypto provider
AT_KEYEXCHANGE, // Key spec
MY_ENCODING_TYPE, // Encoding type
X509_CERT_REQUEST_TO_BE_SIGNED, // Structure type
&CertReqInfo, // Structure information
&SigAlg, // Signature algorithm
NULL, // Not used
NULL, // pbSignedEncodedCertReq
&cbEncodedCertReqSize)) // Size of certificate
{
printf("The size of the encoded certificate is set. \n");
}
else
{
free(pbNameEncoded);
free(pbPublicKeyInfo);
HandleError("First call to CryptSignandEncode failed. \n");
}
if (pbSignedEncodedCertReq = (BYTE*)malloc(cbEncodedCertReqSize))
{
printf("Memory has been allocated.\n");
}
else
{
free(pbNameEncoded);
free(pbPublicKeyInfo);
HandleError("The malloc operation failed. \n");
}
if (CryptSignAndEncodeCertificate(
hCryptProv, // Crypto provider
AT_KEYEXCHANGE, // Key spec
MY_ENCODING_TYPE, // Encoding type
X509_CERT_REQUEST_TO_BE_SIGNED, // Struct type
&CertReqInfo, // Struct info
&SigAlg, // Signature algorithm
NULL, // Not used
pbSignedEncodedCertReq, // Pointer
&cbEncodedCertReqSize)) // Length of the message
{
printf("The message is encoded and signed. \n");
}
else
{
free(pbNameEncoded);
free(pbPublicKeyInfo);
free(pbSignedEncodedCertReq);
HandleError("The second call to CryptSignAndEncode failed. \n");
}
pSignedEncodedCertReqBlob = new char[(cbEncodedCertReqSize * 2) + 1];
ByteToStr(cbEncodedCertReqSize, pbSignedEncodedCertReq, pSignedEncodedCertReqBlob);
printf("The string created is: \n");
printf("%s\n", pSignedEncodedCertReqBlob);
free(pbNameEncoded);
free(pbPublicKeyInfo);
free(pbSignedEncodedCertReq);
CryptReleaseContext(hCryptProv, 0);
printf("\nMemory freed. Program ran without error. \n");
return pSignedEncodedCertReqBlob;
}
На выходе получаю. Код:
308201053081D3020100306731653007060355040313003009060355040613025255300D060355040713064D6F73636F77300D060355040813065275737369613014060355040A130D526F67612069204B6F70697461301B06092A864886F70D010901130E656D61696C40746573742E636F6D3063301C06062A8503020213301206072A85030202240006072A850302021E0103430004403CCE610E308F0C13DA22271A834CA7389972A5771F79068325D6D4709921966E2D52ADC9BF0B4228519A12824D26C805AA391444E41DF9EE6607B0BBAA6C8537A000300A06062A850302020905000321009B32F4F950E910CB8FA5C48D4E935F64DDA89FEE0E3EAA59B0D5BA3BFFE50F51
Далее перевожу в base64. Код:
static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(char* bytes_to_encode, unsigned int in_len) {
std::string ret;
int block = 0;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++) {
ret += base64_chars[char_array_4[i]];
block++;
if (block == 64) {
ret += '\n';
block = 0;
}
}
i = 0;
}
}
if (i) {
for (j = i; j < 3; j++) {
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++) {
ret += base64_chars[char_array_4[j]];
}
}
return ret += "=\n";
}
И получаю вот такой запрос, который не принимается АРМ. Код:
MzA4MjAxMDUzMDgxRDMwMjAxMDAzMDY3MzE2NTMwMDcwNjAzNTUwNDAzMTMwMDMw
MDkwNjAzNTUwNDA2MTMwMjUyNTUzMDBEMDYwMzU1MDQwNzEzMDY0RDZGNzM2MzZG
NzczMDBEMDYwMzU1MDQwODEzMDY1Mjc1NzM3MzY5NjEzMDE0MDYwMzU1MDQwQTEz
MEQ1MjZGNjc2MTIwNjkyMDRCNkY3MDY5NzQ2MTMwMUIwNjA5MkE4NjQ4ODZGNzBE
MDEwOTAxMTMwRTY1NkQ2MTY5NkM0MDc0NjU3Mzc0MkU2MzZGNkQzMDYzMzAxQzA2
MDYyQTg1MDMwMjAyMTMzMDEyMDYwNzJBODUwMzAyMDIyNDAwMDYwNzJBODUwMzAy
MDIxRTAxMDM0MzAwMDQ0MDNDQ0U2MTBFMzA4RjBDMTNEQTIyMjcxQTgzNENBNzM4
OTk3MkE1NzcxRjc5MDY4MzI1RDZENDcwOTkyMTk2NkUyRDUyQURDOUJGMEI0MjI4
NTE5QTEyODI0RDI2QzgwNUFBMzkxNDQ0RTQxREY5RUU2NjA3QjBCQkFBNkM4NTM3
QTAwMDMwMEEwNjA2MkE4NTAzMDIwMjA5MDUwMDAzMjEwMDlCMzJGNEY5NTBFOTEw
Q0I4RkE1QzQ4RDRFOTM1RjY0RERBODlGRUUwRTNFQUE1OUIwRDVCQTNCRkZFNTBG
NTE=
АРМ выдаёт следующую ошибку. Код:
Номер: -2147220992
Источник: GetRequestPKCS
Описание: Неправильный формат запроса
Может я где-то что-то упустил или сделал не так, подскажите пожалуйста.
|