Опытный
 
Профиль
Группа: Участник
Сообщений: 692
Регистрация: 9.2.2005
Где: Москва
Репутация: 1 Всего: 1
|
Доброго времени суток. Пытаюсь осуществить САБЖ. Пример кода взял в инете + кое-что от себя Код | int CreateCert() { DWORD dwSize;; LPCSTR sFileName = "Тестовый сертификат";
CERT_RDN_ATTR rgNameAttr[1] = { szOID_COMMON_NAME, // pszObjId CERT_RDN_PRINTABLE_STRING, // dwValueType strlen(sFileName), // value.cbData (BYTE*)sFileName}; // value.pbData
CERT_RDN rgRDN[] = { 1, // rgRDN[0].cRDNAttr &rgNameAttr[0]}; // rgRDN[0].rgRDNAttr
CERT_NAME_INFO Name = { 1, // Name.cRDN rgRDN}; // Name.rgRDN
//------------------------------------------------------------------- // Declare and initialize all other variables and structures.
CERT_REQUEST_INFO CertReqInfo; CERT_NAME_BLOB SubjNameBlob; DWORD cbNameEncoded; BYTE* pbNameEncoded; HCRYPTPROV hCryptProv; DWORD cbPublicKeyInfo; CERT_PUBLIC_KEY_INFO* pbPublicKeyInfo; CRYPT_OBJID_BLOB Parameters; CRYPT_ALGORITHM_IDENTIFIER SigAlg; BYTE* pbSignedEncodedCertReq; char* pSignedEncodedCertReqBlob; BOOL bResult = FALSE; LPSTR szContainer = NULL; //CHAR* szProvider = CP_DEF_PROV; CHAR* szProvider = MS_ENHANCED_PROV; DWORD dwProviderType = PROV_RSA_FULL; //PROV_GOST_DH; //PROV_RSA_FULL; RPC_STATUS Status;
if(CryptEncodeObject( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // 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 { printf("First call to CryptEncodeObject failed.\ \nA public/private key pair may not exit in the container. \n"); } //------------------------------------------------------------------- // Allocate memory for the encoded name.
if(!(pbNameEncoded = (BYTE*)malloc(cbNameEncoded))) printf("pbNamencoded malloc operation failed.\n");
//------------------------------------------------------------------- // Call CryptEncodeObject to do the actual encoding of the name.
if(CryptEncodeObject( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // 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); printf("Second call to CryptEncodeObject failed.\n"); } //-------------------------------------------------------------------- // Set the subject member of CertReqInfo to point to // a CERT_NAME_INFO structure that // has been initialized with the data from cbNameEncoded // and pbNameEncoded.
SubjNameBlob.cbData = cbNameEncoded; SubjNameBlob.pbData = pbNameEncoded; CertReqInfo.Subject = SubjNameBlob;
//-------------------------------------------------------------------- // Generate custom information. This step is not // implemented in this code.
CertReqInfo.cAttribute = 0; CertReqInfo.rgAttribute = NULL; CertReqInfo.dwVersion = CERT_V1;
/* Create new crypto context*/ CString sss = "lolilol" ; bResult = CryptAcquireContext(&hCryptProv, sss, szProvider, dwProviderType, CRYPT_MACHINE_KEYSET); if (!bResult) { printf("CryptAcquireContext failed with %x\n", GetLastError()); } bResult = CryptSetProvParam(hCryptProv, PP_KEYEXCHANGE_PIN, (BYTE*)"pass", 0); if (!bResult) { printf("CryptSetProvParam failed with %x\n", GetLastError()); } DWORD dwKeyType = AT_KEYEXCHANGE; HCRYPTKEY hPubKey = 0; /* Generate Private/Public key pair*/ bResult = CryptGenKey(hCryptProv, dwKeyType, CRYPT_EXPORTABLE, &hPubKey); if (!bResult) { printf("CryptGenKey failed with %x\n", GetLastError()); }
if(CryptExportPublicKeyInfo( hCryptProv, // Provider handle dwKeyType, // Key spec (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type NULL, // pbPublicKeyInfo &cbPublicKeyInfo)) // Size of PublicKeyInfo { printf("The keyinfo structure is %d bytes.\n",cbPublicKeyInfo); } else { free(pbNameEncoded); printf("First call to CryptExportPublickKeyInfo failed.\ \nProbable cause: No key pair in the key container. Error = %d\n", GetLastError()); }
if(pbPublicKeyInfo = (CERT_PUBLIC_KEY_INFO*)malloc(cbPublicKeyInfo)) { printf("Memory is allocated for the public key structure. \n"); } else { free(pbNameEncoded); printf("Memory allocation failed."); }
if(CryptExportPublicKeyInfo( hCryptProv, // Provider handle dwKeyType, // Key spec (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type pbPublicKeyInfo, // pbPublicKeyInfo &cbPublicKeyInfo)) // Size of PublicKeyInfo { printf("The key has been exported. \n"); } else { free(pbNameEncoded); free(pbPublicKeyInfo); printf("Second call to CryptExportPublicKeyInfo failed."); } //-------------------------------------------------------------------- // Set the SubjectPublicKeyInfo member of the // CERT_REQUEST_INFO structure to point to the CERT_PUBLIC_KEY_INFO // structure created.
CertReqInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo;
memset(&Parameters, 0, sizeof(Parameters)); SigAlg.pszObjId = szOID_OIWSEC_sha1RSASign; SigAlg.Parameters = Parameters;
//-------------------------------------------------------------------- // Call CryptSignAndEncodeCertificate to get the size of the // returned BLOB.
if(CryptSignAndEncodeCertificate( hCryptProv, // Crypto provider AT_KEYEXCHANGE, // Key spec (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type X509_CERT_REQUEST_TO_BE_SIGNED, // Structure type &CertReqInfo, // Structure information &SigAlg, // Signature algorithm NULL, // Not used NULL, // pbSignedEncodedCertReq &dwSize)) // Size of certificate // required { printf("The size of the encoded certificate is set. \n"); } else { free(pbNameEncoded); free(pbPublicKeyInfo); printf("First call to CryptSignandEncode failed."); }
ShowError(GetLastError());
//-------------------------------------------------------------------- // Allocate memory for the encoded certificate request.
if(pbSignedEncodedCertReq = (BYTE*)malloc(dwSize)) { printf("Memory has been allocated.\n"); } else { free(pbNameEncoded); free(pbPublicKeyInfo); printf("Malloc operation failed."); } //-------------------------------------------------------------------- // Call CryptSignAndEncodeCertificate to get the // returned BLOB.
if(CryptSignAndEncodeCertificate( hCryptProv, // Crypto provider AT_KEYEXCHANGE, // Key spec (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Encoding type X509_CERT_REQUEST_TO_BE_SIGNED, // Struct type &CertReqInfo, // Struct info &SigAlg, // Signature algorithm NULL, // Not used pbSignedEncodedCertReq, // Pointer &dwSize)) // Length of the message { printf("The message is encoded and signed. \n"); } else { free(pbNameEncoded); free(pbPublicKeyInfo); printf("Second call to CryptSignAndEncode failed."); }
//серийный номер сертификата char* pData= new char[39]; GUID certID; CoCreateGuid(&certID); CLSIDtochar(certID, pData, 39); long lCRC= GetCRC32(pData, 39);
PBYTE pDataCRC= NULL; pDataCRC= new BYTE [4]; PBYTE b= (BYTE*)&lCRC; int i, num= dwSize;
for(i= 0; i<sizeof(long); ++i) pDataCRC[i]=b[i];
//имя файла - серийный номер сертификата int sz= 9; CString flName; LPTSTR flBuf= flName.GetBuffer(sz); ByteToStr(4, pDataCRC, flBuf);
for(int n= 0; n<sz/2; n++)//реверс байтов { char chr= flBuf[n]; flBuf[n]= flBuf[sz-n-2-1]; flBuf[sz-n-2-1]= chr; n++; chr= flBuf[n]; flBuf[n]= flBuf[sz-n-1]; flBuf[sz-n-1]= chr; } flName.ReleaseBuffer();
int iBlobLen= 2*dwSize + 1; LPTSTR szSignedEncodedCertBlob= certEncodBLOB.GetBuffer(iBlobLen); ByteToStr(dwSize, pbSignedEncodedCertReq, szSignedEncodedCertBlob); #ifdef _DEBUG WriteToFile(_CertStorePath+flName+".cer", pbSignedEncodedCertReq, num); #endif certEncodBLOB.ReleaseBuffer(); if(hCryptProv) CryptReleaseContext(hCryptProv,0);
return 1; }
|
. Сертификат создается, но при попытке его открыть получаю сообщение о том, что "Этот файл не может использоваться как: Сертификат безопасности". Вроде все обязательные поля записал, может кто сталкивался? Буду благодарен
|