| ||||
| ||||
Сейчас я создаю сертификат и в строчке "Открытый ключ" виндузного просмотрщика сертификата показывается OID алгоритма и "(0 Bits)", например Открытый ключ 1.2.643.2.2.22(0 Bits) Где нужно указать длину ключа, чтобы было не (0 Bits), а например (1024 Bits)? Спасибо | ||||
Ответы: | ||||
| ||||
Нужно установить КриптоПро CSP, т.к. длину ключа просмотрщик получает через функции провайдера. | ||||
| ||||
А как этот просмотрщик узнает: 1. к какому криптопровайдеру обратиться за информацией о ключе? 2. к какому алгоритму относится данный ключ сертификата? Ведь ключ в сертификате характеризуется OID’ом а в криптопровадере для идентификации алгоритма используется AlgID если не ошибаюсь... | ||||
| ||||
По OID ключа конечно же. А как blob декодировать определяется с помощью чего-нибудь типа CryptGetOIDFunctionAddress | ||||
| ||||
Еще вопрос по составу сертификата. Как выводить кириллицу в полях сертификата? | ||||
| ||||
Ну для начала установить шрифты, содержашие кириллицу... В остальном же вывод не отличается от вывода обычного текста. | ||||
| ||||
Сорри за торможениее... Естественно, на машине есть русские шрифты, но тем не менее кириллица выводится козяброй в стандартном вьювере сертификата. | ||||
| ||||
Какая ОС, какие языковые настройки? Как создаете сертификат? | ||||
| ||||
ОС Win XP Professional SP1 кодовые страницы 855, 28595, 20880, 1251,10007 Сертификат создаю следующим образом: #define ASN_E (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) #pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define SIGN94_KEY 1 #define ENCRYPT_KEY 2 #define SIGN01_KEY 3 #define SIGN94_KEY_FNAME "my_sign_94.cer" #define ENCRYPT_KEY_FNAME "my_encrypt.cer" #define SIGN01_KEY_FNAME "my_sign_01.cer" #define ALG_ID_SIGN01 "1.2.643.2.2.19" #define ALG_ID_SIGN94 "1.2.643.2.2.20" #define ALG_ID_ENCODE "1.2.643.2.2.22" CERT_RDN_ATTR nameAttr; PChar nameString; CERT_RDN rdn; CERT_NAME_INFO nameInfo; CERT_REQUEST_INFO certReqInfo; CERT_NAME_BLOB subjNameBlob; DWORD encNameLen; PBYTE encName; HCRYPTPROV prov; DWORD pubKeyInfoLen; CERT_PUBLIC_KEY_INFO pubKeyInfo; DWORD encCertReqLen; CRYPT_OBJID_BLOB params; CRYPT_ALGORITHM_IDENTIFIER sigAlg; PBYTE signedEncCertReq; PChar cont; String err ; DWORD encType; CRYPT_BIT_BLOB PubKey; CRYPT_ALGORITHM_IDENTIFIER PubKeyAlg; HCRYPTPROV hCryptProv; HCRYPTKEY phKey; CERT_INFO certInfo,certInfo2,certInfo3; LONGLONG serNum; CERT_NAME_INFO nameInfoIss; CERT_RDN_ATTR nameAttrIss; CERT_RDN rdnIss; CERT_NAME_BLOB issNameBlob; DWORD encNameLenIss; PBYTE encNameIss; DWORD encCertLenIss; PBYTE encCert; // заполняю поля сруктуры запроса на серификат nameAttr.pszObjId = "2.5.4.3"; nameAttr.dwValueType = CERT_RDN_PRINTABLE_STRING; //здесь задаю имя владельца сертификата, которое потом выводится казябрами nameAttr.Value.cbData = strlen(Form1->SubjectEdit->Text.c_str()); nameAttr.Value.pbData = Form1->SubjectEdit->Text.c_str(); rdn.cRDNAttr = 1; rdn.rgRDNAttr = &nameAttr; nameInfo.cRDN = 1; nameInfo.rgRDN = &rdn; // получаем размер закодированного имени пользователя CryptEncodeObject (ASN_E, X509_NAME, &nameInfo, NULL, &encNameLen); encName = (PBYTE) malloc(encNameLen); //GetMem (encName, encNameLen); CryptEncodeObject (ASN_E, X509_NAME, &nameInfo, encName, &encNameLen); subjNameBlob.cbData = encNameLen; subjNameBlob.pbData = encName; certReqInfo.Subject = subjNameBlob; certReqInfo.cAttribute = 0; certReqInfo.rgAttribute = NULL; certReqInfo.dwVersion = CERT_REQUEST_V1; ZeroMemory(¶ms, sizeof(params)); sigAlg.pszObjId = szOID_OIWSEC_sha1RSASign; sigAlg.Parameters = params; // в структуре publickeyblobs находятся ключи, для которых я выпускаю сертификат // в данном случае - подписи ’94 KeySign94Length=sizeof(publickeyblobs.Sign94Blob.publickey.pubkey94); PubKeyAlg.pszObjId = ALG_ID_SIGN94; // подпись 94 PubKeyAlg.Parameters = params; PubKey.cbData = KeySign94Length; PubKey.pbData = publickeyblobs.Sign94Blob.publickey.pubkey94; PubKey.cUnusedBits = 0; pubKeyInfo.Algorithm = PubKeyAlg; pubKeyInfo.PublicKey = PubKey; certReqInfo.SubjectPublicKeyInfo = pubKeyInfo; // подписываю структуру запроса if(!CryptAcquireContext(&hCryptProv,"test",NULL,PROV_RSA_FULL,NULL)) CryptAcquireContext(&hCryptProv,"test",NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET); CryptGenKey(hCryptProv,CALG_RSA_SIGN,CRYPT_EXPORTABLE,&phKey); CryptSignAndEncodeCertificate (hCryptProv, AT_SIGNATURE,ASN_E,X509_CERT_REQUEST_TO_BE_SIGNED, &certReqInfo, &sigAlg, NULL, NULL,&encCertReqLen); signedEncCertReq = (PBYTE) malloc(encCertReqLen); CryptSignAndEncodeCertificate (hCryptProv, AT_SIGNATURE,ASN_E, X509_CERT_REQUEST_TO_BE_SIGNED,&certReqInfo, &sigAlg, NULL, signedEncCertReq,&encCertReqLen); // далее изготовляю сам сертификат certInfo.dwVersion = 0; //// серийный номер if (!Form1->CheckBox1->Checked) serNum = StrToInt64(Form1->serNumEdit->Text); else serNum = 1; certInfo.SerialNumber.cbData = sizeof(serNum); certInfo.SerialNumber.pbData = (BYTE *)&serNum; certInfo.SignatureAlgorithm.pszObjId = szOID_OIWSEC_sha1RSASign; certInfo.SignatureAlgorithm.Parameters = params; nameAttrIss.pszObjId = "2.5.4.3"; nameAttrIss.dwValueType = CERT_RDN_PRINTABLE_STRING; //здесь задаю имя того, кто выпускает сертификат, которое потом тоже выводится казябрами nameAttrIss.Value.cbData = strlen(Form1->IssuerEdit->Text.c_str()); nameAttrIss.Value.pbData = Form1->IssuerEdit->Text.c_str(); rdnIss.cRDNAttr = 1; rdnIss.rgRDNAttr = &nameAttrIss; nameInfoIss.cRDN = 1; nameInfoIss.rgRDN = &rdnIss; CryptEncodeObject (ASN_E, X509_NAME, &nameInfoIss, NULL, &encNameLenIss); encNameIss = (PBYTE) malloc(encNameLen); CryptEncodeObject (ASN_E, X509_NAME, &nameInfoIss, encNameIss, &encNameLenIss); issNameBlob.cbData = encNameLenIss; issNameBlob.pbData = encNameIss; certInfo.Issuer = issNameBlob; // заполняю поля срока действия SYSTEMTIME sysTime; sysTime.wYear=0; sysTime.wYear=0; sysTime.wDay=0; sysTime.wHour=0; sysTime.wMinute=0; sysTime.wSecond=0; sysTime.wMilliseconds=0; Form1->NotBeforeDTP1->DateTime.DecodeDate(&sysTime.wYear,&sysTime.wMonth,&sysTime.wDay); sysTime.wDayOfWeek=Form1->NotBeforeDTP1->DateTime.DayOfWeek(); SystemTimeToFileTime (&sysTime,&(certInfo.NotBefore)); Form1->NotAfterDTP2->DateTime.DecodeDate(&sysTime.wYear,&sysTime.wMonth,&sysTime.wDay); sysTime.wDayOfWeek=Form1->NotAfterDTP2->DateTime.DayOfWeek(); SystemTimeToFileTime (&sysTime, &(certInfo.NotAfter)); certInfo.Subject = certReqInfo.Subject; certInfo.SubjectPublicKeyInfo = certReqInfo.SubjectPublicKeyInfo; certInfo.IssuerUniqueId.cbData = 0; certInfo.IssuerUniqueId.pbData = NULL; certInfo.IssuerUniqueId.cUnusedBits = 0; certInfo.SubjectUniqueId.cbData = 0; certInfo.SubjectUniqueId.pbData = NULL; certInfo.SubjectUniqueId.cUnusedBits = 0; certInfo.cExtension = 0; certInfo.rgExtension = NULL; // генерирую сертификат CryptSignAndEncodeCertificate (hCryptProv, AT_SIGNATURE, ASN_E,X509_CERT_TO_BE_SIGNED, &certInfo, &(certInfo.SignatureAlgorithm),NULL, NULL, &encCertLenIss); encCert = (PBYTE) malloc(encCertLenIss); CryptSignAndEncodeCertificate (hCryptProv, AT_SIGNATURE,ASN_E,X509_CERT_TO_BE_SIGNED, &certInfo, &(certInfo.SignatureAlgorithm), NULL, encCert, &encCertLenIss); CryptReleaseContext (hCryptProv, 0); | ||||
| ||||
CERT_RDN_PRINTABLE_STRING - это ANSI, конечно там русских символов нет. надо использовать юникод | ||||
| ||||
Спасибо, помогло! | ||||
| ||||
Спасибо! | ||||