如果你在網絡上傳遞一份數據,但卻存在著種種不安全的因素,使你對數據能否原封不動地到達目的地而心存疑惑,這時,你就可以給數據加上數字簽名,從而使對方可以通過驗證簽名來檢查你所傳過去的數據是否已被他人修改。
一、程序原理
數字簽名的工作原理還是比較簡單的,它是根據你所提供的原始數據,經過復雜的算法,產生特定的數據簽名,對方通過同樣的過程也產生簽名,如果數據已被修改,那麼就不可能得到兩份一模一樣的簽名,從而就可判斷數據已被他人修改。人員利用Windows的CAPI接口,就可以實現數據的加密、解密和數字簽名。
二、程序清單
下面用C++ Builder的語句來看一下它的具體實現過程。
先來創建數字簽名,假定其數據來自於一個文件。
//變量聲明:
HCRYPTPROV hProv;
// CSP的句柄
HCRYPTHASH hHash;
// 散列的句柄
const int BUFFER=4096;
// 緩沖區大小常數
BYTE pBuffer[BUFFER];
// 存放讀文件內容的緩沖區
BYTE pSignature[256];
// 存放簽名的緩沖區
DWORD dSignatureLen=256;
// 簽名的長度
TFileStream *sourceFile;
// 一個文件流
if(!CryptAcquireContext(&hProv,NULL,NULL,PROV—RSA—FULL,0))
// 連接默認的CSP,接受它的句柄放入hProv
{
// 錯誤處理
}
if(!CryptCreateHash(hProv,CALG—MD5,0,0,&hHash))
// 創建一個散列對象,得到它的句柄放入hHash
{
// 錯誤處理
}
do
{
dReadLen=sourceFile-Read(pBuffer,BUFFER);
if(!CryptHashData(hHash,pBuffer,dReadLen,0))
// 根據文件的內容計算散列值
{
// 錯誤處理
}
}while(!(dReadLen
if(!CryptSignHash(hHash,AT—SIGNATURE,NULL,0,pSignature,&dSignatureLen))
//使用私人密鑰對散列值進行數字簽名
//簽名數據放入pSignature,長度放入dSignatureLen
// 錯誤處理
}
對基於文件的數據簽名進行檢驗。
//變量聲明:
HCRYPTPROV hProv;
// CSP的句柄
HCRYPTHASH hHash;
// 散列的句柄
HCRYPTKEY hPublicKey;
// 公共密鑰的句柄
const int BUFFER=4096;
// 緩沖區大小常數
BYTE pBuffer[BUFFER];
// 存放讀文件內容的緩沖區
TFileStream *sourceFile; // 一個文件流
BYTE pSignature[256];
// 上一段得到的簽名的緩沖區
DWORD dSignatureLen;
// 上一段得到的簽名的長度
if(!CryptAcquireContext(&hProv,NULL,NULL,PROV—RSA—FULL,0))
// 連接默認的CSP,接受它的句柄放入hProv
{
// 錯誤處理
}
if(!CryptGetUserKey(hProv,AT_SIGNATURE,&hPublicKey); // 得到公共密鑰的句柄
{
// 錯誤處理
}
if(!CryptCreateHash(hProv,CALG—MD5,0,0,&hHash)) // 創建一個散列對象,得到它的句柄放入hHash
{
// 錯誤處理
}
do
{
dReadLen=sourceFile-Read(pBuffer,BUFFER);
if(!CryptHashData(hHash,pBuffer,dReadLen,0))
// 根據文件的內容計算散列值
{
// 錯誤處理
}
}while(!(dReadLen
if(!CryptVerifySignature(hHash,pSignature,dSignatureLen,hPublicKey,NULL,0))
{
if(GetLastError()==NTE—BAD—SIGNATURE) ShowMessage(″文件已被修改″);
}
else
{
ShowMessage(″文件沒被修改″);
}
以上是一個數字簽名的簡單實現,得到的簽名數據可以單獨保存,也可以分開保存。