我手头没有MSDN有谁有 Cryptography API 的函数的详细资料呢?贴出来或发给我都可以。E_mail:[email protected]
解决方案 »
- inline钩子 能移植到mobile 平台吗?顺便问下钩子是改函数代码还是地址??
- 创建List Control 时为什么会在编译成功之后,执行的时间出错呢?
- 采用odbc连接SQL数据库,往一个有11万多条记录的数据中增加新记录,居然要花40秒时间!如何提高速度?
- GetQueuedCompletionStatus返回FALSE是什么原因?
- CDialog的显示 送分问题了~~~在线等
- 100分!!!!一个程序,在W2k下能运行,可在W98下不能运行??!!
- 关于文件遍力查找的问题
- Open GL有前途吗?
- 谁知道哪里可以下载win2k server安装程序啊?
- 求助树形控件使用
- 如何在VC中实现对word或excel的调用以完成报表功能?
- 如何分割MDI主窗口?(用MFC实现)
http://down.zy169.net/SoftDown.asp?ID=200
加载示例解决方案
复制所有文件
帮助
Robert Coleridge
Microsoft Developer Network Technology GroupAugust 19, 1996Abstract
This article describes the Microsoft® Cryptography application programming interface (API) that is available with the new Windows NT® version 4.0 release and upcoming versions of Windows® 95. This article examines what is required to set up and use this new API. In order to compile the sample application you will need Microsoft Visual C++® version 4.2 or later and Windows NT 4.0 or later.Note Portions of the Cryptography API fall under U.S. export restrictions.
Introduction
The Cryptography API has a number of significant uses within the Enterprise Computing Model. Computing on an Enterprise scale implies a more global framework for interaction between people, such as international commodity trading, interstate inventory management, and so on. Within that framework it is often necessary to transmit sensitive information over non-secure channels—for example, faxing contracts, e-mailing buy or sell orders, and so on. By using the Cryptography API, you can guarantee the security of such information.This article uses the CRYPTOAPI sample application to demonstrate how to decrypt or encrypt data, sign and verify files, and add and remove users.An Overview of the Cryptography API
Cryptography Service Providers (CSPs)
[Editor's note: Portions of this article are quoted directly from the CryptoAPI documentation in the Platform SDK. Those sections of text are indented (all text is normally flush left) but not preceded by a number, a bullet, or the word "Note:", so that you can easily identify them.]The Cryptography API contains functions that allow applications to encrypt or digitally sign data in a flexible manner, while providing protection for the user's sensitive private key data. All cryptographic operations are performed by independent modules known as cryptographic service providers (CSPs). One CSP, the Microsoft RSA Base Provider, is included with the operating system.
Each CSP provides a different implementation of the Cryptography API layer. Some provide stronger cryptographic algorithms, while others contain hardware components such as smartcards [plastic cards containing microchips that hold security data about the user]. In addition, some CSPs may occasionally communicate with users directly, such as when digital signatures are performed using the user's signature private key.
Applications should not take advantage of attributes particular to a specific CSP. For example, the Microsoft RSA Base Provider currently uses 40-bit session keys and 512-bit public keys. (See "Symmetric Versus Public-Key Encryption," MSDN Library, Platform, SDK, and DDK Documentation) When applications manipulate these, they should be careful not to make assumptions about the amount of memory needed to store them. Otherwise, the application is likely to fail when the user loads a different CSP onto the system. You should take care to write applications that are as well-behaved and flexible as possible.
Key Databases
Each CSP has a key database in which it stores its persistent cryptographic keys. Each key database contains one or more key containers, each of which contains all the key pairs belonging to a specific user (or Cryptography API client). Each key container is given a unique name, which applications provide to the CryptAcquireContext function when acquiring a handle to the key container. Figure 1 is an illustration of the contents of a key database:
Figure 1. Contents of a key database
The CSP stores each key container from session to session, including all the public/private key pairs it contains. However, session keys are not preserved from session to session.
Although it is possible to find these keys on a computer, they are stored in an encrypted and secure format.Generally, a default key container is created for each user. This key container takes the user's logon name as its own name, which is then used by any number of applications. It is also possible for an application to create its own key container (and key pairs), which it usually names after itself.
Keys
Session Keys
Session keys are used when encrypting and decrypting data. They are created by applications using either the CryptGenKey or the CryptDeriveKey function. These keys are kept inside the CSP for safekeeping.
Unlike the key pairs, session keys are volatile. Applications can save these keys for later use or transmission to other users by exporting them from the CSP into application space in the form of an encrypted key binary large object or key blob using the CryptExportKey function.
Public or Private Key Pairs
Each user generally has two public or private key pairs. One key pair is used to encrypt session keys and the other to create digital signatures. These are known as the key exchange key pair and the signature key pair, respectively.
Note that although key containers created by most CSPs will contain two key pairs, this is not required. Some CSPs do not store any key pairs, while others store additional ones.
Encryption
In using data encryption, a plain-text message can be encoded so it appears as completely random binary data that is very difficult (if not impossible) to transform back to the original message without a secret key. In this article, the following definitions apply:
Message is used to refer to any piece of data. A message can consist of ASCII text, a database file, or any data you want to store or transmit securely.
Plain text is used to refer to data that has not been encrypted.
Cipher text refers to data that has been encrypted.
Once a message has been encrypted, it can be stored on nonsecure media or transmitted on a nonsecure network and still remain secret. Later, the message can be decrypted into its original form. This process is shown in Figure 2.
Figure 2. Encrypting and decrypting a message
When a message is encrypted, an encryption key is used. This is analogous to the physical key that is used to lock a padlock. To decrypt the message, the corresponding decryption key must be used. It is very important to properly restrict access to the decryption key, because anyone who possesses it will be able to decrypt all messages that were encrypted with the matching encryption key.
This may come as a surprise, but data encryption/decryption is pretty straightforward. The really difficult part is keeping the keys safe and transmitting them securely to other users. This topic is beyond the scope of this article but I would recommend that the reader read the section titled "Exchanging Cryptographic Keys" in the Win32® Cryptography API documentation (MSDN Library, Platform, SDK, and DDK Documentation).
There are two main classes of encryption algorithms: symmetric algorithms and public-key algorithms (also known as asymmetric algorithms). Systems that use symmetric algorithms are sometimes referred to as conventional.
Algorithms
Symmetric algorithms are the most common type of encryption algorithm. They are known as "symmetric" because the same key is used for both encryption and decryption. Unlike the keys used with public-key algorithms, symmetric keys are frequently changed. For this reason, they are referred to here as session keys. Compared to public-key algorithms, symmetric algorithms are very fast and thus are preferred when encrypting large amounts of data. Some of the more common symmetric algorithms are RC2, RC4, and the Data Encryption Standard (DES).
Public-key (asymmetric) algorithms use a pair of different keys: a public key and a private key. The private key is kept private to the owner of the key pair, and the public key can be distributed to anyone who requests it. If one key is used to encrypt a message, the other key is required to decrypt the message. Public-key algorithms are very slow, on the order of a thousand times slower than symmetric algorithms. Consequently, they are normally used only to encrypt session keys. They are also used to digitally sign messages, as discussed in the next section. One of the most common public-key algorithms is the RSA Public-Key Cipher.
File Signing
Digital signatures can be used when you have a message that you plan to distribute in plain-text form, and you want the recipients to be able to verify that the message comes from you and that it hasn't been tampered with since it left your hands. Signing a message does not alter the message, it simply generates a digital signature string you can bundle with the message or transmit separately.
Digital signatures are generated using public-key signature algorithms. A private key is used to generate the signature, and the corresponding public key is used to validate the signature. This process is shown in Figure 3.
Figure 3. Validating a signature
Some Cryptography API Functions
[Editor's note: Indented portions of the following text are quoted from MSDN Library, Platform, SDK, and DDK Documentation.]Initiating the CSP: CryptAcquireContext, CryptReleaseContext
The CryptAcquireContext function is used to obtain a handle to a particular key container within a particular CSP. This returned handle can then be used to make calls to the selected CSP.
The CryptReleaseContext function is used to release the handle returned from a call to CryptAcquireContext. The CryptReleaseContext function does not delete any Cryptography API objects, but merely releases the handle to an object.The CryptAcquireContext function performs two operations. It first attempts to find a CSP with the characteristics described by various parameters. If the CSP is found, the function attempts to find a key container within the CSP that matches the specified container name. This function can also be used to create and destroy key containers, depending on the value of the parameters.
To obtain a handle to the default key container of the default CSP the code would look like this:
#include <wincrypt.h> // CryptoAPI definitions
/*
For non-C/C++ users the constants used here are:
#define MS_DEF_PROV "Microsoft Base Cryptographic Provider v1.0"
#define PROV_RSA_FULL 1
*/BOOL bResult;
HCRYPTPROC hProv;// Attempt to acquire a handle to the default key container.
bResult = CryptAcquireContext(
&hProv, // Variable to hold returned handle.
NULL, // Use default key container.
MS_DEF_PROV, // Use default CSP.
PROV_RSA_FULL, // Type of provider to acquire.
0); // No special action.
.
.
.
//Do some work.
.
.
.
// Release handle to container.
CryptReleaseContext(hProv);If the call to CryptAcquireContext is successful, the return code will be non-zero and the variable hProv will be a handle to the requested key container.In order to add or create a key container for the default CSP we would write code like the following:#include <wincrypt.h> // CryptoAPI definitions
/*
For non C/C++ users the constants used here are:
#define MS_DEF_PROV "Microsoft Base Cryptographic Provider v1.0"
#define PROV_RSA_FULL 1
#define CRYPT_NEWKEYSET 0x8
*/BOOL bResult;
HCRYPTPROC hProv;// Attempt to add a new key container.
BResult = CryptAcquireContext(
&hProv, // Variable to hold returned handle.
NULL, // Use default key container.
MS_DEF_PROV, // Use default CSP.
PROV_RSA_FULL, // Type of provider to acquire.
CRYPT_NEWKEYSET); // Create new key container.
.
.
.
//Do some work.
.
.
.
// Release handle to container.
CryptReleaseContext(hProv);If the call to CryptAcquireContext is successful, the return code will be non-zero and the variable hProv will be a handle to the new key container.In order to delete an existing key container from the default CSP, we would write code like the following:#include <wincrypt.h> // CryptoAPI definitions
/*
For non C/C++ users the constants used here are:
#define MS_DEF_PROV "Microsoft Base Cryptographic Provider v1.0"
#define PROV_RSA_FULL 1
#define CRYPT_DELETEKEYSET 0x10
*/
BOOL bResult;
HCRYPTPROC hProv;// Attempt to delete key container.
BResult = CryptAcquireContext(
&hProv, // Variable to hold returned handle.
NULL, // Use default key container.
MS_DEF_PROV, // Use default CSP.
PROV_RSA_FULL, // Type of provider to acquire.
CRYPT_DELETEKEYSET); // Delete existing key container.If the call to CryptAcquireContext is successful, the return code will be non-zero, the key container pointed to by hProv will have been deleted, and the key container will no longer be valid.Hashing Data: CryptCreateHash, CryptHashData, CryptGetHashParam, and CryptDestroyHash
When I say "hashing" or "hash," I am referring to the method or algorithm used to derive a numeric value from a piece of data. This could be something as simple as adding up all of the one bits in the data, or as complicated as doing a Fourier transformation of the data.The four functions listed in the heading above are used to create or manipulate hash value from supplied data, and are usually used together: The CryptCreateHash function is used to initiate the hashing of data. It returns a handle to a CSP hash object, which can be used in subsequent calls to CryptHashData in order to hash the data.
The next step is to use the CryptGetHashParam function to retrieve the hash value.
The CryptDestroyHash function is used to release the handle returned from CryptCreateHash. CryptDestroyHash does not delete any Cryptography API objects, but merely releases the handle to a hash object.
The CryptHashData function is used to compute the cryptographic hash of some supplied data. This function can be called multiple times to compute the hash on large data or different pieces of data. As an example, we will hash the data that is contained in a buffer pointed to by pBuffer and that is dwBufferLen bytes long. I have chosen the CALG_MD5 hashing algorithm for the purpose of this example only. There are many other algorithms available and fully explained in the Cryptography API SDK documentation. This example assumes only one piece of data to hash. Once the hash value has been retrieved via CryptGetHashParam, no more data can be hashed with this instance of the hash object.#include <wincrypt.h> // CryptoAPI definitions
/*
For non C/C++ users the constants used here are:
#define ALG_CLASS_HASH (4 << 13)
#define ALG_TYPE_ANY (0)
#define ALG_SID_MD5 3
#define CALG_MD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5)
#define HP_HASHVAL 0x0002 // Hash value
#define HP_HASHSIZE 0x0004 // Hash value size
*/
BOOL bResult;
HCRYPTHASH hHash;
DWORD dwBufferSize;
DWORD dwValue;
PBYTE pBuffer;// Obtain handle to hash object.
bResult = CryptCreateHash(
hProv, // Handle to CSP obtained earlier
CALG_MD5, // Hashing algorithm
0, // Non-keyed hash
0, // Should be zero
&hHash); // Variable to hold hash object handle // Hash data.
bResult = CryptHashData(
hHash, // Handle to hash object
pBuffer, // Pointer to data buffer
dwBufferlen, // Length of data
0); // No special flags// Get size of hash value.
dwBufferSize = sizeof(DWORD);
bResult = CryptGetHashParam(
hHash, // Handle to hash object
HP_HASHSIZE, // Get hash value
&dwValue, // Buffer to hold hash value length
&dwBufferSize, // Length of data buffer
0); // Must be zero// Create buffer to hold hash value.
pBuffer = new char [dwBufferSize];// Get hash value.
bResult = CryptGetHashParam(
hHash, // Handle to hash object
HP_HASHVAL, // Get hash value
pBuffer, // Buffer to hold hash value
&dwBufferSize, // Length of data
0); // Must be zero// Release hash object.
CryptDestroyHash(hHash);The above example generated a hash value for the data pointed to by pBuffer. If there was more data to hash, calling CryptHashData with that data would have hashed the new data with the old value. Be warned—calling CryptGetHashParam with the HP_HASHVALUE parameter prevents any further hashing with that particular object.Generating Keys: CryptDeriveKey, CryptGenKey, CryptDestroyKey
These three functions are the ones used to generate handles to keys: The CryptDeriveKey function is used to generate a key from a specified password.
The CryptGenKey function is used to generate a key from random generated data.
The CryptDestroyKey function is used to release the handle to the key object.
If the CryptGenKey function is used, it is recommended that the CRYPT_EXPORTABLE parameter be used to create an exportable session key. This creates a value that can be moved from one computer to another. Without this parameter the value returned is only valid on that particular computer/session.