A digital envelope contains the encrypted content and the Encrypted Key used to encrypt the content. Although the receiver's public key is often used to encrypt the "encryption key", this is not necessary. You can also use the symmetric key pre-shared by the sender and receiver for encryption. When receiving a digital envelope, the receiver decrypts the envelope with the private key or pre-shared key to obtain the "encryption key", and then decrypts the ciphertext with the key to obtain the original text. The digital envelope technology uses a two-layer encryption system.
The digital envelope is an application of the public key cryptography system in practice. It uses encryption technology to ensure that only specified recipients can read the communication content. In a digital envelope, the sender uses a symmetric key to encrypt the information content, and then encrypts the symmetric key with the public key of the receiver (this part is called a digital envelope, send it together with the encrypted information to the receiver. The Receiver opens the digital envelope with the corresponding private key to obtain the symmetric key, and then uses the symmetric key to unbind the encrypted information. This technology is highly secure. A digital Envelope consists of the packaging of a digital envelope and the dismantling of a digital envelope. A digital envelope is a process of encrypting the encryption key using the public key of the other party, only the private key of the other party can restore the encrypted data (Communication Key). The digital envelope disassembly uses the private key to decrypt the encrypted data.
Key replacement
The function of a digital envelope is similar to that of an ordinary envelope. Under legal restrictions, a normal envelope ensures that only the recipient can read the content of the letter; the password technology is used to ensure that only the specified recipient can read the information. Symmetric cryptography and public key cryptography are used in the digital envelope. The information sender first encrypts the information using a random symmetric password, and then uses the receiver's public key to encrypt the symmetric password. The symmetric password encrypted by the Public Key is called a digital envelope. When transmitting information, to decrypt the information, the information receiver must first use its own private key to decrypt the digital envelope and obtain a symmetric password to decrypt the obtained information. This ensures the authenticity and integrity of data transmission. In some important e-commerce transactions, keys must be frequently replaced. In order to solve the problem of each key replacement, combined with the advantages of symmetric encryption and public key technology, it overcomes the difficulty of distributing secret keys in secret key encryption and the long encryption time in public key encryption. It uses two levels of encryption to obtain the flexibility of Public Key Technology and the efficiency of secret key technology. The information sender uses a password to encrypt the information, so that only the specified recipient can read the content of the message. After the use of the digital envelope technology, even if the encrypted file is illegally intercepted by others, because the attacker cannot obtain the sender's communication key, it is impossible to decrypt the file.
The VC ++ implementation code is as follows. For detailed analysis, see the code comment.
# Include <stdio. h> <br/> # include <windows. h> </p> <p> # include <wincrypt. h> </p> <p> # define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) <br/> void HandleError (char * s ); </p> <p> PCCERT_CONTEXT GetRecipientCert (HCERTSTORE hCertStore); </p> <p> void ByteToStr (<br/> DWORD cb, <br/> void * pv, <br/> LPSTR sz); </p> <p> BOOL DecryptMessage (<br/> BYTE * pbEncryptedBlob, <br/> DWORD cbEncryptedBlob, <br/> HCRYPTPROV hCryptProv, <br/> HCERTSTORE hStoreHandle); </p> <p> HCRYPTPROV GetCryptProv (); </p> <p> void main () <br/> {<br/> // declare <br/> // variable declaration and initialization </p> <p> BYTE * pbContent = (BYTE *) "Security is our business. "; // message to be encrypted <br/> DWORD cbContent = strlen (char *) pbContent) + 1; // message length <br/> HCRYPTPROV hCryptProv; // CSP handle <br/> HCERTSTORE hStoreHandl E; // certificate store handle <br/> PCCERT_CONTEXT pRecipientCert; // receive certificate <br/> PCCERT_CONTEXT RecipientCertArray [1]; // receive certificate list <br/> DWORD EncryptAlgSize; <br/> encryption EncryptAlgorithm; <br/> encryption EncryptParams; <br/> DWORD EncryptParamsSize; <br/> BYTE * pbEncryptedBlob; <br/> DWORD cbEncryptedBlob; </p> <p> printf ("starting from message % s. \ n ", pbContent); <br/> printf (" The message length is % d bytes. \ n ", cbConten T); </p> <p> // obtain the encryption service provider handle <br/> hCryptProv = GetCryptProv (); </p> <p> // -------------------------------------------------------------------- <br/> // open the system certificate library. </p> <p> if (hStoreHandle = CertOpenSystemStore (<br/> hCryptProv, <br/> "MY ")) <br/> {<br/> printf ("MY certificate library has been opened. \ n "); <br/>}< br/> else <br/> {<br/> HandleError (" An error occurred while obtaining the certificate store handle. "); <br/>}< br/> //--------------------------------------------------------------- ----- <Br/> // call the GetRecipientCert function to obtain the receiver certificate </p> <p> if (pRecipientCert = GetRecipientCert (<br/> hStoreHandle )) <br/> {<br/> printf ("the recipient's certificate has been obtained. \ n "); <br/>}< br/> else <br/> {<br/> printf (" No certificate with a CERT_KEY_CONTEXT_PROP_ID \ n "); <br/> printf ("property and an AT_KEYEXCHANGE private key available. \ n "); <br/> printf (" While the message cocould be encrypted, in this case, \ n "); <br/> printf (" it cocould Not be decrypted in this program. \ n "); <br/> printf (" For more information, see the documentation for \ n "); <br/> printf (" CrypteEncryptMessage and CryptDecryptMessage. \ n "); <br/> HandleError (" No Certificate with AT_KEYEXCHANGE key in store. "); <br/>}< br/> // ------------------------------------------------------------------ <br/> // create a list of received certificates. only one receiver certificate is included here <br/> RecipientCertArray [0] = pRecipientCer T; </p> <p> // ---------------------------------------------------------------------- <br/> // initialize the algorithm structure. </p> <p> EncryptAlgSize = sizeof (EncryptAlgorithm); </p> <p> // initialize <br/> // The initialization algorithm structure is 0. </p> <p> memset (& EncryptAlgorithm, 0, EncryptAlgSize ); </p> <p> // -------------------------------------------------------------------- <br/> // set the necessary member variables of the algorithm structure. </p> <p> EncryptAlgorithm. pszObjId = szOID_RSA_RC4; </p> <p> // initialize <br/> // initialize the CRYPT_ENCRYPT_MESSAGE_PARA structure. </p> <p> EncryptParamsSize = sizeof (EncryptParams); <br/> memset (& EncryptParams, 0, EncryptParamsSize); <br/> EncryptParams. cbSize = EncryptParamsSize; <br/> EncryptParams. dwMsgEncodingType = MY_ENCODING_TYPE; <br/> EncryptParams. hCryptProv = HCryptProv; <br/> EncryptParams. contentEncryptionAlgorithm = EncryptAlgorithm; </p> <p> // call CryptEncryptMessage to encrypt the message. </p> <p> // obtain the encrypted data length <br/> if (CryptEncryptMessage (<br/> & EncryptParams, <br/> 1, <br/> RecipientCertArray, // list of received certificates <br/> pbContent, <br/> cbContent, <br/> NULL, <br/> & cbEncryptedBlob )) <br/>{< br/> printf ("the encrypted message is % D bytes. \ n ", cbEncryptedBlob); <br/>}< br/> else <br/>{< br/> HandleError (" failed to get the data block length after encryption. "); <br/>}< br/> // ------------------------------------------------------------------ <br/> // allocate memory space. </p> <p> if (pbEncryptedBlob = (BYTE *) malloc (cbEncryptedBlob )) <br/> {<br/> printf ("memory space has been allocated for the encrypted data block. \ n "); <br/>}< br/> else <br/> {<br/> HandleError (" memory allocation error during encryption. "); <br/>}< br/> //--------------------------------------- --------------------------- <Br/> // encrypt the message </p> <p> if (CryptEncryptMessage (<br/> & EncryptParams, <br/> 1, <br/> RecipientCertArray, <br/> pbContent, <br/> cbContent, <br/> pbEncryptedBlob, <br/> & cbEncryptedBlob )) <br/>{< br/> printf ("encrypted successfully. \ n "); <br/>}< br/> else <br/> {<br/> HandleError (" encryption failed. "); <br/>}</p> <p> // ------------------------------------------------------------------ <br/> // call DecryptMes Sage decryption message </p> <p> if (DecryptMessage (<br/> pbEncryptedBlob, <br/> cbEncryptedBlob, <br/> hCryptProv, <br/> hStoreHandle )) <br/>{< br/> printf ("decryption successful. \ n "); <br/>}< br/> else <br/> {<br/> printf (" decryption failed. \ n "); <br/>}< br/> // ------------------------------------------------------------------ <br/> // release the memory space. </p> <p> CertFreeCertificateContext (pRecipientCert); <br/> if (CertCloseStore (<br/> hStoreHandle, <br/> CERT_CLOSE_STORE_CHECK_FLAG) <br/>{< br/> printf ("MY certificate library closed successfully. \ n "); <br/>}< br/> else <br/> {<br/> printf ("Disable the certificate library after encryption -- \ n" <br/> "but not all certificates or the Certificate Revocation List is released. \ n "); <br/>}< br/> if (hCryptProv) <br/>{< br/> CryptReleaseContext (hCryptProv, 0 ); <br/> printf ("the CSP handle has been released. \ n "); <br/>}< br/> else <br/> {<br/> printf (" the CSP handle is empty. \ n "); <br/>}< br/>}// End of main </p> <p> //----------------------------------------------------- --------------- <Br/> // function: decrypt messages encrypted by the CryptDecryptMessage function. <br/> // parameter <br/> // pbEncryptedBlob: the message to be decrypted <br/> // cbEncryptedBlob: the length of the message to be decrypted <br/> // hCryptProv: CSP handle <br/> // hStoreHandle: opened certificate store handle <br/> BOOL DecryptMessage (<br/> BYTE * pbEncryptedBlob, <br/> DWORD cbEncryptedBlob, <br/> HCRYPTPROV hCryptProv, <br/> HCERTSTORE hStoreHandle) <br/>{< br/> //---------------------------------------------------- ---------------- <Br/> // declaration and initialization variable <br/> DWORD cbDecryptedMessage; </p> <p> char * EncryptedString = (char *) malloc (sizeof (char) * (cbEncryptedBlob * 2 + 1); <br/> HCERTSTORE CertStoreArray [] = {hStoreHandle}; <br/> CRYPT_DECRYPT_MESSAGE_PARA DecryptParams; <br/> DWORD DecryptParamsSize = sizeof (DecryptParams); <br/> BYTE * pbDecryptedMessage; <br/> LPSTR DecryptedString; <br/> BOOL fReturn = TRUE; </p> <p> ByteToSt R (<br/> cbEncryptedBlob, <br/> pbEncryptedBlob, <br/> EncryptedString ); </p> <p> // -------------------------------------------------------------------- <br/> // print the converted ciphertext. <br/> printf ("the encrypted string is \ n % s \ n", EncryptedString ); </p> <p> // ---------------------------------------------------------------------- <br/> // initialize the CRYPT_DECRYPT_MESSAGE_PARA structure. </p> <p> memset (& DecryptParams, 0, DecryptParamsSize); <br/> DecryptParam S. cbSize = DecryptParamsSize; <br/> DecryptParams. dwMsgAndCertEncodingType = MY_ENCODING_TYPE; <br/> DecryptParams. cCertStore = 1; <br/> DecryptParams. rghCertStore = CertStoreArray; // Certificate database list </p> <p> // ------------------------------------------------------------------ <br/> // decrypt message data. </p> <p> // call CryptDecryptMessage to determine the data length after decryption. <br/> if (CryptDecryptMessage (<br/> & DecryptParams, <br/> pbEncryptedBlob, <br/> CbEncryptedBlob, <br/> NULL, <br/> & cbDecryptedMessage, <br/> NULL )) <br/>{< br/> printf ("the decrypted data length is % d. \ n ", cbDecryptedMessage); <br/>}< br/> else <br/>{< br/> HandleError (" An error occurred while obtaining the message length after decryption "); <br/>}< br/> // allocate <br/> // allocate space </p> <p> if (pbDecryptedMessage = (BYTE *) malloc (<br/> cbDecryptedMessage) <br/> {<br/> printf ("memory space has been allocated to decrypt messages. \ n "); <br />}< Br/> else <br/> {<br/> HandleError ("memory allocation error during decryption "); <br/>}< br/> // ---------------------------------------------------------------------- <br/> // call CryptDecryptMessage to decrypt data. </p> <p> if (CryptDecryptMessage (<br/> & DecryptParams, <br/> pbEncryptedBlob, <br/> cbEncryptedBlob, <br/> pbDecryptedMessage, <br/> & cbDecryptedMessage, <br/> NULL) <br/>{< br/> DecryptedString = (LPSTR) pbDecryptedMessage; <br/> p Rintf ("The message is successfully decrypted. \ n "); <br/> printf (" decrypted string: % s \ n ", DecryptedString ); <br/>}< br/> else <br/> {<br/> printf ("An error occurred while decrypting the message \ n "); <br/> printf ("error code % x \ n", GetLastError (); <br/> fReturn = FALSE; <br/>}</p> <p> // release <br/> // release the memory </p> <p> free (pbEncryptedBlob ); <br/> free (pbDecryptedMessage); <br/> return fReturn; <br/>}// End of DecryptMessage </p> <p> // ---------------------------------------------------------------------- <Br/> // ByteToStr: converts BYTE arrays to strings. <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 four 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> // ------------------------------------------------------------------ <br/> // function: traverses the certificate in the certificate library. If yes, this certificate is returned. <br/> // parameter: hCertStore certificate store handle </p> <p> PCCERT_CONTEXT GetRecipientCert (<br/> HCERTSTORE hCertStore) <br/>{< br/> // ---------------------------------------------------------------------- <br/> // declare and initialize the variable </p> <p> PCCERT_CONTEXT pCert Context = NULL; <br/> BOOL fMore = TRUE; <br/> DWORD dwSize = 0; <br/> CRYPT_KEY_PROV_INFO * pKeyInfo = NULL; <br/> DWORD PropId = CERT_KEY_PROV_INFO_PROP_ID; </p> <p> // certificate <br/> // search for a certificate containing an exchange key pair </p> <p> while (fMore & (pCertContext = CertFindCertificateInStore (<br/> hCertStore, // certificate store handle. <br/> 0, // encoding type. <br/> 0, // dwFindFlags. describes the query criteria. Use <br/> CERT_FIND_PROPERTY, // query type to determine the type of query. The specific extension attributes of the certificate are used here <br/> & PropId, // pvFindPara. the specific value of the query, which is the identifier of the extended property <br/> pCertContext) // certificate handle, which is NULL when it is called for the first time, then obtain the certificate attributes for the last returned pointer <br/>{< br/> // ------------------------------------------------------- <br/>: key pair Information </p> <p> if (! (CertGetCertificateContextProperty (<br/> pCertContext, <br/> CERT_KEY_PROV_INFO_PROP_ID, <br/> NULL, & dwSize ))) <br/> {<br/> HandleError ("An error occurred while obtaining the key feature. "); <br/>}</p> <p> // ------------------------------------------------------------ <br/> // allocate space </p> <p> if (pKeyInfo) <br/> free (pKeyInfo); <br/> if (! (PKeyInfo = (CRYPT_KEY_PROV_INFO *) malloc (dwSize) <br/>{< br/> HandleError ("An error occurred while allocating memory for the variable pKeyInfo. "); <br/>}</p> <p> // ------------------------------------------------------------ <br/> // obtain the key information block. </p> <p> if (! (CertGetCertificateContextProperty (<br/> pCertContext, <br/> CERT_KEY_PROV_INFO_PROP_ID, <br/> pKeyInfo, <br/> & dwSize ))) <br/> {<br/> HandleError ("the second call to this function failed. "); <br/>}</p> <p> // ------------------------------------------- <br/> // check whether the key information block contains an exchange key pair. </p> <p> if (pKeyInfo-> dwKeySpec = AT_KEYEXCHANGE) <br/>{< br/> fMore = FALSE; <br/>}< br/>}// End of while loop </p> <p> if (pKeyInfo) <br/> free (pKeyInfo ); <Br/> return (pCertContext); <br/>}// End of GetRecipientCert </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. Here, use the login user name <br/> MS_ENHANCED_PROV, // data encryption service provider <br/> PROV_RSA_FULL, // data encryption service provider type, which can provide encryption, signature, and other functions <br/> 0 )) // flag <br/>{< br/> printf ("obtain the encrypted service provider handle Success! \ 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> // HandleError: error handler, print error information, and exit the Program <br/> void HandleError (char * s) <br/>{< br/> printf ("an error occurred during program execution! \ N "); <br/> printf (" % s \ n ", s); <br/> printf (" error code: % x. \ n ", GetLastError (); <br/> printf (" the program is terminated! \ N "); <br/> exit (1); <br/>}