| ||||
| ||||
Если при создании запроса использовать поля Subject на русском языке, то в результате получаю нечитаемый текст. Подскажите, как это исправить. В проекте установлено Use Multi-Byte Character Set. Вот код (CryptoAPI): #include <stdio.h> #include <windows.h> #include <wincrypt.h> #include <wincryptex.h> #include <atlstr.h> #include <strsafe.h> #include "atlenc.h" void main(void) { HCRYPTPROV hCryptProv; HCRYPTKEY hKey; CERT_RDN_ATTR rgNameAttr[1]; DWORD cbNameEncoded; BYTE* pbNameEncoded; HANDLE hf = NULL; CERT_REQUEST_INFO CertReqInfo; CRYPT_ALGORITHM_IDENTIFIER SigAlg; DWORD dwSize; BYTE* pbSignedEncodedCertReq; DWORD cbPublicKeyInfo; CERT_PUBLIC_KEY_INFO* pbPublicKeyInfo; CString CSPName = "Crypto-Pro Cryptographic Service Provider"; LPCSTR UserName = "User"; CString CN = "абвгдеёжзийклмнопрстуфхцчшщьъэюя"; // Запрос контекста провайдера и генерация ключей CryptAcquireContext(&hCryptProv,UserName,CSPName,2,CRYPT_NEWKEYSET); CryptGenKey(hCryptProv,CALG_DH_EL_SF,CRYPT_EXPORTABLE,&hKey); // Заполнение поля CN rgNameAttr[0].pszObjId = szOID_COMMON_NAME; rgNameAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; rgNameAttr[0].Value.cbData = CN.GetLength(); rgNameAttr[0].Value.pbData = (BYTE*)malloc(CN.GetLength()); CopyMemory(rgNameAttr[0].Value.pbData,CN,CN.GetLength()); CERT_RDN rgRDN[1] = {1,&rgNameAttr[0]}; CERT_NAME_INFO Name = {1,&rgRDN[0]}; CERT_NAME_BLOB SubjNameBlob; // Кодирование структуры CERT_NAME_INFO CryptEncodeObject(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,X509_NAME,&Name,NULL,&cbNameEncoded); pbNameEncoded = (BYTE*)malloc(cbNameEncoded); CryptEncodeObject(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,X509_NAME,&Name,pbNameEncoded,&cbNameEncoded); SubjNameBlob.cbData = cbNameEncoded; SubjNameBlob.pbData = pbNameEncoded; CertReqInfo.Subject = SubjNameBlob; // Заполнение остальных параметров CERT_REQUEST_INFO CertReqInfo.dwVersion = CERT_V1; CertReqInfo.cAttribute = 0; CertReqInfo.rgAttribute = NULL; CryptExportPublicKeyInfo(hCryptProv,AT_KEYEXCHANGE,X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,NULL,&cbPublicKeyInfo); pbPublicKeyInfo = (CERT_PUBLIC_KEY_INFO*)malloc(cbPublicKeyInfo); CryptExportPublicKeyInfo(hCryptProv,AT_KEYEXCHANGE,X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,pbPublicKeyInfo,&cbPublicKeyInfo); CertReqInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo; // Генерация запроса SigAlg.pszObjId = "1.2.643.2.2.4"; SigAlg.Parameters.cbData = 0; SigAlg.Parameters.pbData = NULL; CryptSignAndEncodeCertificate(hCryptProv,AT_KEYEXCHANGE,X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,X509_CERT_REQUEST_TO_BE_SIGNED,&CertReqInfo,&SigAlg,NULL,NULL,&dwSize); pbSignedEncodedCertReq = (BYTE*)malloc(dwSize); CryptSignAndEncodeCertificate(hCryptProv,AT_KEYEXCHANGE,X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,X509_CERT_REQUEST_TO_BE_SIGNED,&CertReqInfo,&SigAlg,NULL,pbSignedEncodedCertReq,&dwSize); // Кодирование запроса в Base64 int dwSize64 = dwSize*2; LPSTR pBase64Req = (LPSTR)malloc(dwSize64); Base64Encode(pbSignedEncodedCertReq,dwSize,pBase64Req,&dwSize64); // Запись в файл c:\req.req hf = CreateFile("c:\\req.req",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hf != INVALID_HANDLE_VALUE) { DWORD cbWrite; WriteFile(hf,pBase64Req,dwSize64,&cbWrite,NULL); } if(hf) CloseHandle(hf); // Очистка памяти free(pBase64Req); free(pbSignedEncodedCertReq); free(pbPublicKeyInfo); free(pbNameEncoded); free(rgNameAttr[0].Value.pbData); CryptReleaseContext(hCryptProv,0); } | ||||
Ответы: | ||||
| ||||
Printable string - это строка, состоящая из символов A, B, …, Z a, b, …, z 0, 1, …, 9 (space) ’ ( ) +, - . / : = ? для русского языка нужно использовать юникод. | ||||
| ||||
Пробовал и CERT_RDN_ATTR dwValueType CERT_RDN_UNICODE_STRING и CryptEncodeObject(X509_UNICODE_NAME) в разных сочетаниях, но русский текст не проходит. | ||||
| ||||
А вот так пробовали? USES_CONVERSION; // Заполнение поля CN LPWSTR s = T2W(CN); rgNameAttr[0].pszObjId = szOID_COMMON_NAME; rgNameAttr[0].dwValueType = CERT_RDN_UNICODE_STRING; rgNameAttr[0].Value.cbData = wcslen(s)*sizeof(WCHAR); rgNameAttr[0].Value.pbData = (BYTE*)s; | ||||
| ||||
Большое спасибо, так сработало. | ||||