VC ++ network security programming example (2)-create a self-signed certificate

Source: Internet
Author: User

The digital certificate uses a public key system, that is, a pair of matching keys are used for encryption and decryption. Each user sets a specific private key (Private Key) that is only known to him and uses it for decryption and signature. At the same time, a Public Key (Public Key) is set and made public by himself, shared by a group of users for encryption and signature verification. When a confidential file is sent, the sender encrypts the data using the public key of the receiver, while the receiver decrypts the data using its own private key, so that the information can be securely reached to the destination. The encryption process is irreversible by digital means, that is, only private keys can be used for decryption. In the public key cryptography system, an RSA System is commonly used. The mathematical principle is to divide a large number into the product of two prime numbers. encryption and decryption use two different keys. Even if the plaintext, ciphertext, and encryption key (Public Key) are known, it is impossible to calculate the decryption key (Private Key. According to the current computer technology level, it takes thousands of years to crack the 1024-bit RSA key currently used. The public key technology solves the issue of key Publishing Management. Merchants can disclose their public keys while retaining their private keys. A shopper can encrypt the information sent by using the public key of a person's bank and transmit it to the merchant securely. Then, the merchant uses its own private key.
Decryption
You can also use your own private key to process the information. Because the key is only owned by yourself, a file cannot be generated by others, and a digital signature is formed. Using a digital signature, you can confirm the following two points:
(1) ensure that the information is sent by the signatory's own signature, and the signatory cannot deny or be hard to deny;
(2) ensure that no modification has been made to the information since it was issued and that the issued document is a real document
The specific method of digital signature is:
(1) Calculate the packets according to the HASH algorithm agreed by both parties to obtain a fixed-digit message digest. Mathematical guarantee: As long as any bit in the message is modified, the Digest value of the re-calculated packet will be inconsistent with the original value. This ensures that the packets cannot be modified.
(2) encrypt the digest value with the private key of the sender, and then send the digest value together with the original message to the receiver. The generated message is called a digital signature.
(3) After receiving the digital signature, the receiver uses the same HASH algorithm to calculate the digest value of the message, and then compares it with the digest value of the packet decrypted by the sender's public key. If they are equal, the message actually comes from the called sender.

The Code is as follows. for analysis, see annotations.

# Ifndef _ WIN32_WINNT <br/> # define _ WIN32_WINNT 0x0400 <br/> # endif </p> <p> # include <stdio. h> <br/> # include <windows. h> <br/> # include <wincrypt. h> </p> <p> # define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) <br/> # define CERT_SUBJECT_NAME "TEST_SIGNER_NAME" <br/> // function declaration <br/> void HandleError (char * s); <br/> HCRYPTPROV GetCryptProv (); <br/> void ByteToStr (<br/> DWORD cb, <br/> void * pv, <br/> LPSTR sz); </p> <p> void main (void) <br/> {<br/> // declare <br/> // variable declaration and initialization </p> <p> HCERTSTORE hCertStore = NULL; <br/> HCRYPTPROV hCertProv = NULL; <br/> HCRYPTKEY hKeySign = NULL; <br/> PCCERT_CONTEXT pCertCtxSign = NULL; </p> <p> BYTE * Encrypted = NULL; <br/> DWORD EncryptedLen = 0; <br/> BYTE * Decrypted = NULL; <br/> DWORD DecryptedLen = 0; <Br/> CERT_NAME_BLOB certName = {0}; <br/> certName. cbData = 0; <br/> certName. pbData = NULL; <br/> DWORD cbNameEncoded; <br/> BYTE * pbNameEncoded; </p> <p> // assign a value to the CERT_NAME_BLOB structure certName </p> <p> CERT_RDN_ATTR rgNameAttr [] = {<br/> "2.5.4.3 ", <br/> CERT_RDN_PRINTABLE_STRING, <br/> strlen (CERT_SUBJECT_NAME), <br/> (BYTE *) CERT_SUBJECT_NAME }; </p> <p> CERT_RDN rgRDN [] ={< br/> 1, <br/> & rgNameAttr [0] }; </p> <P> CERT_NAME_INFO Name ={< br/> 1, <br/> rgRDN };</p> <p> // encode <br/> // encode the CERT_NAME_INFO structure, determine the encoded data length </p> <p> if (CryptEncodeObject (<br/> MY_ENCODING_TYPE, // Encoding type <br/> X509_NAME, // Structure type <br/> & Name, // Address of CERT_NAME_INFO structure <br/> NULL, // pbEncoded <br/> & cbNameEncoded )) // pbEncoded size <br/>{< br/> printf ("CryptEncodeObject is successfully called for the first time. \ n "); <br/>}< br/> else <br/> {<br/> HandleError (" the first call of the function CryptEncodeObject failed. \ <br/> \ n public/private key pairs cannot be exported from the key container. \ n "); <br/>}< br/> // ------------------------------------------------------------------- <br/> // allocate memory </p> <p> if (! (PbNameEncoded = (BYTE *) malloc (cbNameEncoded) <br/> HandleError ("pbNamencoded malloc operation failed. \ n "); </p> <p> // encode <br/> // encoding struct </p> <p> if (CryptEncodeObject (<br/> MY_ENCODING_TYPE, // Encoding type <br/> X509_NAME, // Structure type <br/> & Name, // Address of CERT_NAME_INFO structure <br/> pbNameEncoded, // pbEncoded <br/> & cbNameEnco Ded) // pbEncoded size <br/>{< br/> printf ("This struct has been encoded. \ n "); <br/>}< br/> else <br/>{< br/> free (pbNameEncoded ); <br/> HandleError ("the second call to the function CryptEncodeObject failed. \ n "); <br/>}</p> <p> // assign a value to certName <br/> certName. cbData = cbNameEncoded; <br/> certName. pbData = pbNameEncoded; </p> <p> // obtain the CSP handle <br/> hCertProv = GetCryptProv (); </p> <p> // generate a signature key pair <br/> if (CryptGenKey (hCertProv, AT_SIGNATURE, CRYPT_EXPORTABLE, & hK EySign) <br/>{< br/> printf ("the signature key is successfully created in the service certificate container! \ N "); </p> <p >}< br/> else <br/>{< br/> HandleError (" Protection :: initialise-you cannot create a signature key in the service certificate Container-\ n "); </p> <p >}</p> <p> SYSTEMTIME cs; <br/> GetSystemTime (& cs); <br/> cs. wYear + = 1; </p> <p> // create a self-signed certificate <br/> if (pCertCtxSign = CertCreateSelfSignCertificate (<br/> hCertProv, // CSP handle <br/> & certName, // certificate Object Name Data Structure pointer <br/> 0, // flag. Default behavior: create private key information, create a signature <br/> NULL, // key information structure <br/> NULL, // signature algorithm, null indicates the default algorithm SHA1RSA <br/> NULL, // validity period start time, null indicates the current system time <br/> & cs, // validity period End Time, null indicates the start time plus 1 year <br/> NULL) // No extended attributes are set <br/>{< br/> printf ("A self-signed certificate has been created. \ n "); <br/>}< br/> else <br/> {<br/> HandleError (" CertCreateSelfSignCertificate Error! "); <Br/>}< br/> free (certName. pbData); </p> <p> // open the certificate library <br/> if (hCertStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L "My") <br/>{< br/> printf ("successfully opened the certificate library. \ n "); <br/>}< br/> else <br/> {<br/> HandleError (" An error occurred while calling the CertOpenStore function. \ n "); <br/>}</p> <p> // Add the certificate to the certificate repository <br/> if (CertAddCertificateContextToStore (hCertStore, <br/> pCertCtxSign, CERT_STORE_ADD_NEW, NULL) <br/ >{< Br/> printf ("adding the self-signed certificate to the system certificate library succeeded. \ n "); <br/>}< br/> else <br/> {<br/> printf (" An error occurred while adding the self-signed certificate to the system certificate library. \ n "); <br/>}</p> <p> // release space <br/> if (Encrypted) <br/> free (Encrypted ); <br/> if (Decrypted) <br/> free (Decrypted); <br/> if (pCertCtxSign) <br/> CertFreeCertificateContext (pCertCtxSign ); <br/> if (hKeySign) <br/> CryptDestroyKey (hKeySign); <br/> if (hCertStore) <br/> CertCloseStore (hCertStore, 0); <br/> If (hCertProv) <br/> CryptReleaseContext (hCertProv, 0 ); </p> <p >}// End of main </p> <p> // obtain the encryption provider handle <br/> HCRYPTPROV GetCryptProv () <br/>{< br/> HCRYPTPROV hCryptProv; // encryption service provider handle </p> <p> // obtain the encryption provider handle <br/> if (CryptAcquireContext (<br/> & hCryptProv, // encryption service provider handle <br/> "ruanou", // key container name <br/> MS_ENHANCED_PROV, // encryption service provider <br/> PROV_RSA_FULL, // data encryption service provider type, which can provide encryption and signature functions <br/> 0) // flag <br/>{< br/> printf ("provided by the encryption service The handler is obtained successfully! \ N "); <br/>}< br/> else <br/>{</p> <p> // create a new key set <br/> if (! CryptAcquireContext (& hCryptProv, "ruanou", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) <br/>{< br/> HandleError ("re-establishing a new key set error! "); <Br/>}</p> <p >}< br/> return hCryptProv; <br/>}</p> <p> // bytes <br/> // ByteToStr: converts an array of the BYTE type to a string. <br/> // parameter: cb [in] length of the BYTE array to be converted <br/> // pv [in] BYTE array pointer to be converted <br/> // sz [out] string pointer <br/> void ByteToStr (<br/> DWORD cb, <br/> void * pv, <br/> LPSTR sz) <br/> {<br/> BYTE * pb = (BYTE *) pv; <br/> DWORD I; <br/> int B; </p> <p> for (I = 0; I <cb; I + +) <Br/>{< br/> // convert the first 4 digits of pb to characters <br/> B = (* pb & 0xF0)> 4; <br/> * sz ++ = (B <= 9 )? B + '0': (B-10) + 'a '; <br/> // the last 4 characters of pb are converted to characters. <br/> B = * pb & 0x0F; <br/> * sz ++ = (B <= 9 )? B + '0': (B-10) + 'a'; <br/> pb ++; <br/>}< br/> * sz ++ = 0; <br/>}</p> <p> // HandleError: error handling function. Print the error message and exit the program. <br/> void HandleError (char * s) <br/>{< br/> printf ("An error occurred while executing the program! \ N "); <br/> printf (" % s \ n ", s); <br/> printf (" error code: % x. \ n ", GetLastError (); <br/> printf (" the program is terminated! \ N "); <br/> exit (1); <br/>}</p> <p>

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.