---- Encryption is too complex.AlgorithmImplementation is very difficult, so in the past, many applicationsProgramOnly simple encryption technologies can be used. The result is that the encrypted data can be easily decrypted. By using the encryption application interface (cryptography API) or CryptoAPI provided by Microsoft, you can easily add powerful encryption functions to your application without considering basic algorithms. This article will give a brief introduction to CryptoAPI and its data encryption principles, and then give the general steps to write encryption programs using CryptoAPI, finally, the encryption and decryption program of a file is used as an example to demonstrate some functions of CryptoAPI.
---- 1. Introduction to CryptoAPI
---- CryptoAPI is a set of functions. To complete mathematical computation, you must have a cryptographic service provider module (CSP ). Microsoft provides a CSP at the operating system level by bundling the RSA base provider and uses the RSA public key encryption algorithm. More CSPs can be added to applications as needed. In fact, CSPs may encrypt data with special hardware devices (such as smart cards. The CryptoAPI allows simple function calls to encrypt data, exchange public keys, hash a message to create a digest, and generate a digital signature. It also provides advanced management operations, such as using a CSP from a group of possible CSPs. In addition, CryptoAPI provides the foundation for many advanced security services, including set for e-commerce, PCT for encrypting Client/Server messages, pfx is used to transmit confidential data and keys between platforms,CodeSignature. The architecture of CryptoAPI is as follows:
---- Currently, CryptoAPI is supported in Windows 95 osr2, Windows NT SP3, and later versions, Windows 98, and Windows 2000. The configuration information of CryptoAPI is stored in the registry, including the following keys:
HKEY_LOCAL_MACHINE \ SOFTWARE \
Microsoft \ Cryptography \ defaults
HKEY_CURRENT_USER \ Software \ Microsoft
\ Cryptography \ providers
---- 2. Data Encryption principles
---- The data encryption process is as follows:
---- CryptoAPI uses two types of keys: Session Key and public/private key pair. The session key uses the same encryption and decryption key. This algorithm is fast, but must ensure secure transmission of the key. A public/private key pair uses a public key and a private key. A private key can be used only by a dedicated person and can be widely spread. If one of the key pairs is used for encryption, the other must be used for decryption. The public/private key pair algorithm is slow. It is generally used only to encrypt small batches of data, for example, to encrypt session keys.
---- CryptoAPI supports two basic encoding methods: stream encoding and block encoding. Stream encoding creates an encoding bit on each bit of the plain text, which is fast but less secure. Block encoding works on a complete block (usually 64-bit). You need to use the fill method to round the data to be encoded to form multiple complete blocks. This algorithm is slow but safer.
---- 3. Application Example
---- The following uses the C program segment for encryption and decryption of two files as an example to demonstrate the powerful functions of CryptoAPI. Both programs are Win32 console applications, and error handling is omitted. Please add them during actual running.
---- ① File encryption
# Include <windows. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <wincrypt. h>
// Determine whether to use RC2 block encoding or RC4 stream Encoding
# Ifdef use_block_cipher
# Define encrypt_algorithmcalg_rc2
# Define encrypt_block_size8
# Else
# Define encrypt_algorithmcalg_rc4
# Define encrypt_block_size1
# Endif
Void capidecryptfile (pchar szsource,
Pchar szdestination, pchar szpassword );
Void _ cdecl main (INT argc, char * argv [])
{
Pchar szsource = NULL;
Pchar szdestination = NULL;
Pchar szpassword = NULL;
// Number of verification parameters
If (argc! = 3 & argc! = 4 ){
Printf ("Usage: decrypt <Source File>
<DEST File> [<password>] \ n ");
Exit (1 );
}
// Read parameters.
Szsource = argv [1];
Szdestination = argv [2];
If (argc = 4 ){
Szpassword = argv [3];
}
Capidecryptfile (szsource, szdestination, szpassword );
}
/* Szsource is the name of the file to be encrypted, szdestination
Is the name of the encrypted file, and szpassword is the encrypted password */
Void capiencryptfile (pchar szsource, pchar
Szdestination, pchar szpassword)
{
File * hsource = NULL;
File * hdestination = NULL;
Int EOF = 0;
Hcryptprov hprov = 0;
Hcryptkey hkey = 0;
Hcryptkey hxchgkey = 0;
Hcrypthash hhash = 0;
Pbyte pbkeyblob = NULL;
DWORD dwkeybloblen;
Pbyte pbbuffer = NULL;
DWORD dwblocklen;
DWORD dwbufferlen;
DWORD dwcount;
Hsource = fopen (szsource, "rb"); // open the source file.
Hdestination = fopen (szdestination, "WB ");
//. Open the target file
// Connect to the default CSP
Cryptacquirecontext (& hprov, null, null,
Prov_rsa_full, 0 ));
If (szpassword = NULL ){
// The password is empty and is encrypted with a random session key.
// Generate a random session key.
Cryptgenkey (hprov, encrypt_algorithm,
Crypt_exportable, & hkey)
// Obtain the public key of the Key Exchange pair
Cryptgetuserkey (hprov, at_keyexchange, & hxchgkey );
// Calculate the hidden code length and allocate the buffer
Cryptexportkey (hkey, hxchgkey, simpleblob, 0,
Null, & dwkeybloblen );
Pbkeyblob = malloc (dwkeybloblen) = NULL );
// Output the session key to the hidden code
Cryptexportkey (hkey, hxchgkey, simpleblob,
0, pbkeyblob, & dwkeybloblen ));
// Release the handle of the Key Exchange pair
Cryptdestroykey (hxchgkey );
Hxchgkey = 0;
// Write the hidden code length to the target file
Fwrite (& dwkeybloblen, sizeof (DWORD), 1, hdestination );
// Write the hidden code length to the target file
Fwrite (pbkeyblob, 1, dwkeybloblen, hdestination );
} Else {
// The password is not empty. Use the key derived from the password to encrypt the file.
Cryptcreatehash (hprov, calg_md5, 0, 0, & hhash );
// Create a hash
Crypthashdata (hhash, szpassword, strlen (szpassword), 0 );
// Hash Password
// Derive the key from the hash table
Cryptderivekey (hprov, encrypt_algorithm, hhash, 0, & hkey );
// Delete the hash
Cryptdestroyhash (hhash );
Hhash = 0;
}
// Calculate the number of data bytes encrypted at a time, which must be an integer multiple of encrypt_block_size
Dwblocklen = 1000-1000% encrypt_block_size;
// If block encoding is used, additional space is required.
If (encrypt_block_size> 1 ){
Dwbufferlen = dwblocklen + encrypt_block_size;
} Else {
Dwbufferlen = dwblocklen;
}
// Allocate a buffer
Pbbuffer = malloc (dwbufferlen );
// Encrypt the source file and write it to the target file
Do {
// Read dwblocklen bytes from the source file
Dwcount = fread (pbbuffer, 1, dwblocklen, hsource );
EOF = feof (hsource );
// Encrypt data
Cryptencrypt (hkey, 0, eof, 0, pbbuffer,
& Dwcount, dwbufferlen );
// Write encrypted data to the target file
Fwrite (pbbuffer, 1, dwcount, hdestination );
} While (! Feof (hsource ));
Printf ("OK \ n ");
...... // Close the file and release the memory
}
② File decryption
Void capidecryptfile (pchar szsource, pchar
Szdestination, pchar szpassword)
{
...... // Variable declaration, file operations, and file encryption program
Cryptacquirecontext (& hprov, null, null, prov_rsa_full, 0 );
If (szpassword = NULL ){
// The password is empty and is decrypted using the session key stored in the encrypted file.
// Read the length of the hidden code and allocate the memory
Fread (& dwkeybloblen, sizeof (DWORD), 1, hsource );
Pbkeyblob = malloc (dwkeybloblen) = NULL );
// Read the hidden code from the source file.
Fread (pbkeyblob, 1, dwkeybloblen, hsource );
// Input the hidden code into the CSP
Cryptimportkey (hprov, pbkeyblob,
Dwkeybloblen, 0, 0, & hkey );
} Else {
// The password is not empty. Use the key derived from the password to decrypt the file.
Cryptcreatehash (hprov, calg_md5, 0, 0, & hhash );
Crypthashdata (hhash, szpassword, strlen (szpassword), 0 );
Cryptderivekey (hprov, encrypt_algorithm,
Hhash, 0, & hkey );
Cryptdestroyhash (hhash );
Hhash = 0;
}
Dwblocklen = 1000-1000% encrypt_block_size;
If (encrypt_block_size> 1 ){
Dwbufferlen = dwblocklen + encrypt_block_size;
} Else {
Dwbufferlen = dwblocklen;
}
Pbbuffer = malloc (dwbufferlen );
// Decrypt the source file and write it to the target file
Do {
Dwcount = fread (pbbuffer, 1, dwblocklen, hsource );
EOF = feof (hsource );
// Decrypt data
Cryptdecrypt (hkey, 0, eof, 0, pbbuffer, & dwcount );
// Write decrypted data to the target file
Fwrite (pbbuffer, 1, dwcount, hdestination );
} While (! Feof (hsource ));
Printf ("OK \ n ");
...... // Close the file and release the memory
}
---
---- In addition to data encryption, CryptoAPI is also widely used to generate and confirm digital signatures. Here we will not illustrate them one by one. Interested readers can refer to the msdn document.