簡介
文中用到了一些Cryptography API Next Generation(CNG)函數
程序可適用於以下情況
? 在安全環境下保存文檔
? 加密文件
? 創建軟件的產品密鑰
需要注意的是
背景
我們最初是想在一個簡單的GUI程序中使用CNG來加密文件
相關程序
此處創建了一個MFC應用程序
另外
相關代碼
在此使用CNG創建了類CMyCNGCryptFile
? EnumProviders
? CryptFile
? GetLastError
相關步驟如下
以下是CNG API
打開算法提供者
BCryptOpenAlgorithmProvider
導入密鑰
BCryptGenerateSymmetricKey
創建密鑰
BCryptCreateHash
BCryptHashData
BCryptFinishHash
BCryptGenerateSymmetricKey
獲取或設置算法屬性
BCryptGetProperty
BCryptSetProperty
執行加解密操作
BCryptEncrypt
BCryptDecrypt
枚舉提供者
BCryptEnumRegisteredProviders
關閉算法提供者
BCryptCloseAlgorithmProvider
銷毀密鑰
BCryptDestroyKey
銷毀哈希
BCryptDestroyHash
bool CryptFile(bool bEncrypt
這是從對話框中調用的主要方法
OpenMSPrimitiveProviderAES方法打開一個到AES提供者的句柄
bool CMyCNGCryptFile::OpenMSPrimitiveProviderAES()
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
ntStatus = BCryptOpenAlgorithmProvider( &m_hAesAlg
BCRYPT_AES_ALGORITHM
switch (ntStatus)
{
case STATUS_SUCCESS:
return true;
case STATUS_INVALID_PARAMETER:
case STATUS_NO_MEMORY:
default:
//
}
return false;
}
CreateSymmetricKey_AES_CBC方法獲取一個密鑰
bool CMyCNGCryptFile::CreateSymmetricKey_AES_CBC(DWORD &cbKeyObject
DWORD &cbIV )
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
DWORD cbData =
cbKeyObject =
cbIV =
ntStatus = BCryptGetProperty(m_hAesAlg
(PBYTE)&cbKeyObject
m_pbKeyObject = (PBYTE)HeapAlloc (GetProcessHeap ()
ntStatus = BCryptGetProperty( m_hAesAlg
(PBYTE)&cbIV
m_pbIV= (PBYTE) HeapAlloc (GetProcessHeap ()
memcpy(m_pbIV
ntStatus = BCryptSetProperty(m_hAesAlg
(PBYTE)BCRYPT_CHAIN_MODE_CBC
ntStatus = BCryptGenerateSymmetricKey(m_hAesAlg
cbKeyObject
return true;
}
CreateSymmetricKey_SHA
bool CMyCNGCryptFile::CreateSymmetricKey_SHA
DWORD cbKeyObject)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
BCRYPT_KEY_HANDLE hKey = NULL;
DWORD cbHashObject
BYTE rgbHash[
DWORD cbData =
ntStatus = BCryptOpenAlgorithmProvider(&m_hHashAlg
BCRYPT_SHA
ntStatus = BCryptGetProperty(m_hAesAlg
(PBYTE)&cbKeyObject
ntStatus = BCryptGetProperty( m_hHashAlg
(PBYTE) &cbHashObject
ntStatus = BCryptCreateHash(m_hHashAlg
cbHashObject
ntStatus = BCryptHashData( m_hHash
pwszText)
ntStatus = BCryptFinishHash( m_hHash
ntStatus = BCryptGenerateSymmetricKey( m_hAesAlg
cbKeyObject
return true;
}
Crypt方法通過BCryptEncrypt與BCryptDecrypt函數執行加解密操作
bool CMyCNGCryptFile::Crypt(bool bEncrypt
ULONG iBytesRead
{
NTSTATUS ntStatus =STATUS_UNSUCCESSFUL;
DWORD cbCipherText =
if ( bEncrypt )
ntStatus = BCryptEncrypt(m_hKey
m_pbIV
else
ntStatus = BCryptDecrypt(m_hKey
m_pbIV
return false;
}
CryptLastByte方法使用了不同長度的密文來加密數據
bool CMyCNGCryptFile::CryptLastByte(bool bEncrypt
ULONG iBytesRead
{
NTSTATUS ntStatus= STATUS_UNSUCCESSFUL;
DWORD cbCipherText =
if (bEncrypt)
{
ntStatus = BCryptEncrypt(m_hKey
m_pbIV
BCRYPT_BLOCK_PADDING);
ntStatus = BCryptEncrypt( m_hKey
m_pbIV
&cbCipherText
iBufToSave = cbCipherText;
}
else
{
ntStatus = BCryptDecrypt( m_hKey
m_pbIV
ntStatus = BCryptDecrypt( m_hKey
m_pbIV
BCRYPT_BLOCK_PADDING);
}
return false;
}
EnumProviders方法返回當前計算機上已安裝的提供者
bool CMyCNGCryptFile::EnumProviders(CStringList *lstRegisteredProviders)
{
ntStatus = BCryptEnumRegisteredProviders(&cbBuffer
for ( DWORD i =
{
sProvider
pProviders
lstRegisteredProviders
}
if (pProviders != NULL)
{
BCryptFreeBuffer(pProviders);
}
return true;
}
~CMyCNGCryptFile析構函數關閉算法提供者
刪除所有的指針以防內存洩漏
CMyCNGCryptFile::~CMyCNGCryptFile()
{
BCryptCloseAlgorithmProvider(m_hAesAlg
BCryptDestroyKey(m_hKey);
HeapFree(GetProcessHeap()
HeapFree(GetProcessHeap()
//Hash
BCryptDestroyHash(m_hHash);
free(m_pbHashObject);
BCryptCloseAlgorithmProvider(m_hHashAlg
}
From:http://tw.wingwit.com/Article/program/net/201311/12871.html