Http://expert.9cbs.net/expert/topic/1034/1034228.xml?temp =.8807794
Data encryption with CRYPTOAPI
Department of Computer, Nanjing University of Technology, Li Weiqing
Due to too many complex encryption algorithms, it is very difficult, in the past, many applications can only use very simple encryption techniques, the result of doing the encrypted data is easy to be deciphered. Use Microsoft's encrypted application interface (ie, Cryptography API), or CryptoAPI, convenient to add powerful encryption functions in the application without having to consider basic algorithms. This article will be a simple introduction to the CryptoAPI and the data encryption of the data used, and then give the approximate steps to write encrypted programs with CryptoAPI. Finally, in the encryption of a file, the decryption program is a partial function of CryptoAPI.
Introduction to CryptoAPI
CryptoAPI is a set of functions, in order to complete mathematical calculations, must have a password service provider module (CSP). Microsoft provides a CSP by bundling RSA Base Provider at the operating system level, using RSA's public key encryption algorithm, more CSP can be added to the application as needed. In fact, the CSP may be encrypted with special hardware devices (such as smart cards). The CryptoAPI interface allows simple function call to encrypt data, exchange public keys, hash a message to create summary and generate digital signatures. It also provides advanced management, such as using a CSP from a group of possible CSPs. In addition, CryptoAPI provides a basis for many advanced security services, including SETs for e-commerce, PCTs for encrypting client / server messages, and is used to pass back and forth in each platform. PFX, Code signature, etc. The architecture of CryptoAPI is shown in Figure 1. Figure 1 CRYPTOAPI architecture
The Windows systems currently supporting CryptoAPI are: Windows 95 OSR2, Windows NT SP3, and Subsessments, Windows 98, Windows 2000, etc. CryptoAPI configuration information is stored in the registry, including the following key:
HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Cryptography / DEFAULTS
HKEY_CURRENT_USER / SOFTWARE / Microsoft / Cryptography / Providers
2. Data encryption principle
The data encryption process is shown in Figure 2.
Figure 2 Data encryption process
CryptoAPI uses two keys: session keys with public / private key pairs. The session key uses the same encryption and decryption key, which is faster, but must guarantee the secure transmission of the key. Public / private key uses a public key and a private key, the private key is only a special person to use, and the public key 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 is very slow, generally only for encrypted small batch data, such as for encrypted session keys.
CryptoAPI supports two basic coding methods: streaming coding and block encoding. Flow coding creates a coded bit on each bit of the coded text, fast speed, but is low. Block encoding on a complete block (typically 64 bits), you need to use a fill method to round the data to be encoded to form a plurality of complete blocks. This algorithm is slow, but safer.
3. Application example
The following is an example of encrypting the C program encrypted and decrypted as an example to demonstrate the powerful function of CryptoAPI. Both the two programs are Win32 console applications, and the program omits the error handling, please join when actually runtime.
1 file encryption
#include
#include
#include
#include
/ / Determine the use of RC2 block encoding or RC4 streaming coding
#ifdef us_block_cipher
#define encrypt_algorithm calg_rc2
#define encrypt_block_size 8
#ELSE
#define encrypt_algorithm calg_rc4
#define encrypt_block_size 1
#ENDIF
Void Capidecryptfile (Pchar Szsource, Pchar Szdstination, Pchar Szpassword); Void_CDecl Main (int Argc, char * argv [])
{
Pchar szsource = NULL;
Pchar szdestination = NULL;
Pchar Szpassword = NULL;
// Verify the number of parameters
IF (argc! = 3 && argc! = 4) {
Printf ("Usage: Decrypt
Exit (1);
}
// read the 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 encrypted, szdestination is an encrypted file name, Szpassword is an 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 the default CSP
CryptacquiRecontext (& HPROV, NULL, NULL, PROV_RSA_FULL, 0));
IF (szpassword == null) {
// password is empty, encrypt with randomized session key
// Generate an endless session key.
CryptGenkey (HPROV, Encrypt_Algorithm, Crypt_Exportable, & HKey)
// Get the public key of the key exchange pair
CryptgetuserKey (HPROV, AT_KEYEXCHANGE, & HXCHGKEY);
/ / Calculate the length of the coding and allocate the buffer
CryptexportKey (HKEY, HXCHGKEY, SIMPLEBLOB, 0, NULL, & DWKEYBLOBLEN);
PBKEYBLOB = Malloc (dwkeybloblen) == null);
// output the session key to the cod
CryptexportKey (HKEY, HXCHGKEY, SIMPLEBLOB, 0, PBKEYBLOB, & DWKEYBLOBLEN))
// Release the handle of the key exchange pair
CryptDestroyKey (HXCHGKEY);
HxChgKey = 0;
// Write the length of the coding to the target file
FWRITE (& DWKEYBLOBLEN, SIZEOF (DWORD), 1, HDESTINATION; // Write the tidal length to the target file
FWRITE (PBKEYBLOB, 1, DWKEYBLOBLEN, HDESTINATION);
} else {// password is not empty, use the key encrypted file from the password
CryptCreatehash (HPROV, CALG_MD5, 0, 0, & Hhash); // Establish a hash table
Crypthashdata (Hhash, Szpassword,
Strlen (szpassword), 0); // Hatt password
// Send a key from the hash table
CryptderiveKey (HPROV, ENCRYPT_ALGORITHM, HHASH, 0, & HKEY);
// Delete a list of lashes
CryptDestroyhash (Hhash);
Hhash = 0;
}
/ / Calculate the number of data bytes of the encrypted data, must be an integer times dwblocklen = 1000 - 1000% encrypt_block_size for Encrypt_Block_size;
// If you use block encoding, you need additional space.
IF (Encrypt_Block_size> 1) {
Dwbufferlen = dwblocklen encrypt_block_size;
} else {
DWBUFFERLEN = dwblocklen;
}
// Assign buffer
PBBuffer = malloc (dwbufferlen);
// Encrypted source file and write to the target file
Do {
/ / Read DWBLOCKLEN bytes from the source file
DWCount = FREAD (PBBuffer, 1, dwblocklen, hsource);
EOF = Feof (hSource);
// Encrypted data
Cryptencrypt (HKEY, 0, EOF, 0, PBBUFFER, & DWCOUNT, DWBUFFERLEN);
// Write the encrypted data to the target file
FWRITE (PBBuffer, 1, dwcount, hdestination);
} while (! feof (hsource));
Printf ("ok / n");
... // Close the file, release memory
}
2 file decryption
Void Capidecryptfile (Pchar Szsource, Pchar Szdestination, Pchar Szpassword)
{
... // Variable Declaration, File Operation with Document Encryption Program
CryptacquiRecontext (& HPROV, NULL, NULL, PROV_RSA_FULL, 0);
IF (szpassword == null) {
// password is empty, use the session key in the encrypted file to decrypt
// Read the length of the coding and allocate memory
Fread (& DwKeybloblen, Sizeof (DWORD), 1, HSOURCE;
PBKEYBLOB = Malloc (dwkeybloblen) == null);
// Read the courination from the source file.
Fread (pbkeyblob, 1, dwkeybloblen, hsource);
// Enter the hidden code CSP
CryptimportKey (HPROV, PBKEYBLOB, DWKEYBLOBLEN, 0, 0, & HKEY);
} else {
// password is not empty, use the key to decrypt file from the password
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 to the target file
Do {
DWCount = FREAD (PBBuffer, 1, dwblocklen, hsource);
EOF = Feof (hSource);
// Decrypt data
CryptDecrypt (HKEY, 0, EOF, 0, PBBUFFER, & DWCOUNT);
// Write the decrypted data to the target file
FWRITE (PBBuffer, 1, dwcount, hdestination);
} while (! feof (hsource));
Printf ("ok / n");
... // Close the file, release memory}
The above code is compiled in the Windows NT4.0, the Visual C 6.0 environment. In addition to direct use of encrypted data, CryptoAPI is also widely used to generate and confirm the digital signature, here is not a way to say, interested readers can refer to the MSDN documentation.