Because too complex encryption algorithm is very difficult, in the past, many applications can only use very simple encryption technology, which is the result of encryption is easy to be decipherous. The encrypted application interface (ie, Cryptography API) provided by Microsoft, or CryptoAPI can easily add powerful encryption functions in the application without having to consider the basic algorithm. This article will be a simple introduction to the principles of CryptoAPI and its data encryption, and then give the approximate steps to write encrypted programs with CryptoAPI. Finally, in the encryption of a file, the decryption program demonstrates partial features 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 as follows:
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 / Defaultshkey_Current_User / Software / Microsoft / Cryptography / Providers
2. Data encryption principle data encryption process is shown below:
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
Void CapideCryptfile (Pchar Szsource, Pchar Szdestination, Pchar Szpassword);
Void_cdecl main (int Argc, char * argv []) {pchar szsource = null; pchar szdestination = null; pchar szpassword = null;
// Verify the number of parameters (argc! = 3 && argc! = 4) {Printf ("Usage: Decrypt
// Read parameters. Szsource = argv [1]; szdestination = argv [2]; if (argc == 4) {szpassword = argv [3];} CapideCryptFile (szsource, szdestination, szpassword);}
/ * SzSource to be encrypted file name, szDestination for the encrypted file name, szPassword encryption 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 CSPCryptacquiRecontext (& HPROV, NULL, NULL, PROV_RSA_FULL 0); if (szpassword == null) {// password is empty, use randomly generated session key encrypted // Generates the random session key. CryptGey (HPROV, Encrypt_Algorithm, Crypt_Exportable, & HKey) // Get the key exchange of public key CryptGetUserKey (hProv, AT_KEYEXCHANGE, & hXchgKey); // calculate the code length and implicitly allocated buffer CryptExportKey (hKey, hXchgKey, SIMPLEBLOB, 0, NULL, & dwKeyBlobLen); pbKeyBlob = malloc (dwKeyBlobLen)) == NULL ); // Output session key to hidden code CRYPTEXPORTKEY (HKEY, HXCHGKEY, SIMPLEBLOB, 0, PBKEYBLOB, & DWKEYBLOBLEN)); / / Release Key exchange pair CryPTDESTROYKEY (HXCHGKEY = 0; // will hidden Code length Write the target file FWRITE (& DWKEYBLOBLEN, SIZEOF (DWORD), 1, HDestination); // Write the hidden code length FWRITE (PBKEYBLOB, 1, DWKEYBLOBLEN, HDESTINATION);} else {// password is not empty , Use the key encrypted file from the password sent CryptCreatehash (HPROV, CALG_MD5, 0, 0, & Hhash); // Established a hash table CrypthashData (Hhash, Szpassword, Strlen (Szpassword), 0); // Hash Password // Distribute a key CryptderiveKey (HPROV, ENCRYPT_ALGORITHM, HHASH, 0, & HKEY); // delete the hash table cryptDestroyhash; hhash = 0;}
// a calculated number of data bytes encrypted, you must be an integer multiple of ENCRYPT_BLOCK_SIZE dwBlockLen = 1000 - 1000% ENCRYPT_BLOCK_SIZE; // block coding if used, additional space is required if (ENCRYPT_BLOCK_SIZE> 1) {dwBufferLen = dwBlockLen ENCRYPT_BLOCK_SIZE;} Else {dwbufferlen = dwblocklen;} // Assign buffer PBBuffer = malloc (dwbufferlen); // encrypt source file and write target file DO {// read DWBLOCKLEN by DWBLOCKLEN by DWCount = FREAD (PBBuffer, 1) from the source file , dwblocklen, hsource; EOF = feof (hSource); // Encrypted data Cryptencrypt (HKEY, 0, EOF, 0, PBBUFFER, & DWCOUNT, DWBUFFERLEN); // Write the encrypted data into the target file FWRITE (PBBuffer, 1 , dwcount, hdestination;} while (! feof (hSource)); Printf ("ok / n"); ... // Close file, release memory} 2 file decryption
Void Capidecryptfile (Pchar Szsource, Pchar Szdestination, Pchar Szpassword) {... // Variable declaration, file operation with file encryption program
CryptAcquiRecontext (& HPROV, NULL, NULL, PROV_RSA_FULL, 0); if (szpassword == null) {// password is empty, use the session key to decrypt // read the length of the coded code in the encrypted file and allocate memory FREAD ( & dwkeybloblen, Sizeof (DWORD), 1, HSOURCE); PBKEYBLOB = Malloc (dwkeybloblen)) == null); // Read the courier from the source file .fread (pbkeyblob, 1, dwkeybloblen, hsource); // Enter CSPCryptimportKey (HPROV, PBKEYBLOB, DWKEYBLOBLEN, 0, 0, & HKEY); (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 source file and write target file DO {dwcount = FREAD (Pbuffer, 1, dwblocklen, hSource); EOF = Feof (hSource); // Decryption Data CryptDecrypt (HKEY, 0, EOF, 0, Pbuffer, & dwcount) // Write the decrypted data into the target file FWRITE (PBBuffer, 1, dwcount, hdestination);} while (! Feof (hSource)); Printf ("ok / n"); ... // Close 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.