知识大全 用CNG加密文件的简单方法
Posted 知
篇首语:绝大多数人,在绝大多数时候,都只能靠自己。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 用CNG加密文件的简单方法相关的知识,希望对你有一定的参考价值。
用CNG加密文件的简单方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
简介 文中用到了一些Cryptography API Next Generation(CNG)函数 开发环境为Windows Vista下的Visual C++ SP 标准版 加上Windows SDK及CNG SDK 程序可适用于以下情况 ? 在安全环境下保存文档 但需要在不安全的媒质(如互联网)中传送 ? 加密文件 如图像 MP 各类文档 ? 创建软件的产品密钥 需要注意的是 CNG目前只支持Windows Vista 且不能使用在Visual Basic及C#中 要在Visual Studio中生成相应的Windows程序 可能还需要Windows Vista SDK及CNG SDK 两者都可以从微软官方网站下载获得 背景 我们最初是想在一个简单的GUI程序中使用CNG来加密文件 需要以下三步 选择加密操作 选择需要加密的文件 选择加密密钥 相关程序 此处创建了一个MFC应用程序 程序使用单文档界面 在其中可选择待加解密的文件 加密还是解密 密码 此外 还有一个列表框 用于显示其他信息 另外 要在Visual C++ 中使用CNG SDK 还需要进行如下的项目设置 在 C/C++——General 项右方的 Additional Include Directories 中 添加以下目录 C:\\Program Files\\Microsoft CNG Development Kit\\Include 在 Link——General 项右方的 Additional Library Directories 中 添加以下目录 C:\\Program Files\\Microsoft CNG Development Kit\\Lib\\X 在 Linker——Input 项右方的 Additional Dependencies 中
添加 bcrypt lib 相关代码 在此使用CNG创建了类CMyCNGCryptFile 它有三个公有方法 ? EnumProviders 枚举出注册的提供者 ? CryptFile 加密或解密一个文件 ? GetLastError 返回发生在CryptFile或EnumProviders中的最后一个错误 相关步骤如下 打开算法提供者 创建或导入一个密钥 获取或设置算法属性 执行操作 关闭算法提供者 以下是CNG API 打开算法提供者 BCryptOpenAlgorithmProvider导入密钥 BCryptGenerateSymmetricKey创建密钥 BCryptCreateHashBCryptHashDataBCryptFinishHashBCryptGenerateSymmetricKey获取或设置算法属性 BCryptGetPropertyBCryptSetProperty执行加解密操作 BCryptEncryptBCryptDecrypt枚举提供者 BCryptEnumRegisteredProviders关闭算法提供者 BCryptCloseAlgorithmProvider销毁密钥 BCryptDestroyKey销毁哈希 BCryptDestroyHashbool CryptFile(bool bEncrypt CString sFileToOpen CString sFileToCrypt CString sKey) 这是从对话框中调用的主要方法 它接受要执行的操作 输入的文件 输出的文件 密钥作为参数 步骤如下 用OpenMSPrimitiveProviderAES打开算法提供者 用CreateSymmetricKey_AES_CBC创建一个密钥 或用CreateSymmetricKey_SHA _Hash导入一个密钥 获取相关文件的缓冲区 通过Crypt执行加解密操作 输出中间文件 并通过CryptLastByte获得最终的文件 保存加密数据到输出文件 OpenMSPrimitiveProviderAES方法打开一个到AES提供者的句柄 bool CMyCNGCryptFile::OpenMSPrimitiveProviderAES() NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; ntStatus = BCryptOpenAlgorithmProvider( &m_hAesAlg BCRYPT_AES_ALGORITHM NULL ); switch (ntStatus) case STATUS_SUCCESS: return true; case STATUS_INVALID_PARAMETER: case STATUS_NO_MEMORY: default: // return false; CreateSymmetricKey_AES_CBC方法获取一个密钥 并把它作为一个静态常数BYTE变量rgbAES Key存储在程序中 第一步 通过BCryptGetProperty取得算法属性 接着用算法提供者句柄得到算法的实现细节 如密钥大小及IV大小 第二步 把它分配在堆中 并通过BCryptSetProperty修改算法的属性 此处假定要使用BCRYPT_CHAIN_MODE_CBC 我们将AES算法的BCRYPT_CHAINING_MODE属性设为BCRYPT_CHAIN_MODE_CBC 现在 我们就可通过BCryptGenerateSymmetricKey来创建一个短暂的密钥了
bool CMyCNGCryptFile::CreateSymmetricKey_AES_CBC(DWORD &cbKeyObject DWORD &cbIV ) NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; DWORD cbData = ; cbKeyObject = ; cbIV = ; ntStatus = BCryptGetProperty(m_hAesAlg BCRYPT_OBJECT_LENGTH (PBYTE)&cbKeyObject sizeof(DWORD) &cbData ); m_pbKeyObject = (PBYTE)HeapAlloc (GetProcessHeap () cbKeyObject); ntStatus = BCryptGetProperty( m_hAesAlg BCRYPT_BLOCK_LENGTH (PBYTE)&cbIV sizeof(DWORD) &cbData ); m_pbIV= (PBYTE) HeapAlloc (GetProcessHeap () cbIV); memcpy(m_pbIV rgbIV cbIV); ntStatus = BCryptSetProperty(m_hAesAlg BCRYPT_CHAINING_MODE (PBYTE)BCRYPT_CHAIN_MODE_CBC sizeof(BCRYPT_CHAIN_MODE_CBC) ); ntStatus = BCryptGenerateSymmetricKey(m_hAesAlg &m_hKey m_pbKeyObject cbKeyObject (PBYTE)rgbAES Key sizeof(rgbAES Key) ); return true; CreateSymmetricKey_SHA _Hash方法从用户处获取一个密钥 第一步 通过BCryptOpenAlgorithmProvider打开一个新算法SHA 使用SHA 是因为提供者支持我们后面要用到的哈希接口 接下来通过BCryptGetProperty得到算法属性 再使用算法提供者句柄得到算法的实现细节 如密钥大小及哈希大小 之后再把它分配在堆中 通过BCryptCreateHash为密钥创建哈希对象 第二步 使用BCryptHashData函数对数据缓冲区执行单向哈希 并得到要用于BCryptHashData的哈希值 为此 使用了BCryptFinishHash 现在 就可通过BCryptSetProperty修改算法属性 像上面一样 把AES算法的BCRYPT_CHAINING_MODE属性设为BCRYPT_CHAIN_MODE_CBC 最终将通过BCryptGenerateSymmetricKey创建一个短暂的密钥 bool CMyCNGCryptFile::CreateSymmetricKey_SHA _Hash(PCWSTR pwszText DWORD cbKeyObject) NTSTATUS ntStatus = STATUS_SUCCESS; BCRYPT_KEY_HANDLE hKey = NULL; DWORD cbHashObject cbResult; BYTE rgbHash[ ]; DWORD cbData = ; ntStatus = BCryptOpenAlgorithmProvider(&m_hHashAlg BCRYPT_SHA _ALGORITHM NULL ); ntStatus = BCryptGetProperty(m_hAesAlg BCRYPT_OBJECT_LENGTH (PBYTE)&cbKeyObject sizeof(DWORD) &cbData ); ntStatus = BCryptGetProperty( m_hHashAlg BCRYPT_OBJECT_LENGTH (PBYTE) &cbHashObject sizeof(DWORD) &cbResult ); ntStatus = BCryptCreateHash(m_hHashAlg &m_hHash m_pbHashObject cbHashObject NULL ); ntStatus = BCryptHashData( m_hHash (PBYTE)pwszText (ULONG)wcslen( pwszText) ); ntStatus = BCryptFinishHash( m_hHash rgbHash sizeof(rgbHash) ); ntStatus = BCryptGenerateSymmetricKey( m_hAesAlg &hKey m_pbKeyObject cbKeyObject rgbHash SYMM_KEY_SIZE_SECRET ); return true; Crypt方法通过BCryptEncrypt与BCryptDecrypt函数执行加解密操作 另外 使用了相同长度的密文来加密数据 bool CMyCNGCryptFile::Crypt(bool bEncrypt PUCHAR pbufFileToOpen ULONG iBytesRead ULONG cbIV PBYTE pbufFileToSave DWORD& iBufToSave)NTSTATUS ntStatus =STATUS_UNSUCCESSFUL; DWORD cbCipherText = ; if ( bEncrypt ) ntStatus = BCryptEncrypt(m_hKey pbufFileToOpen iBytesRead NULL m_pbIV cbIV pbufFileToSave iBytesRead &iBufToSave ); else ntStatus = BCryptDecrypt(m_hKey pbufFileToOpen iBytesRead NULL m_pbIV cbIV pbufFileToSave iBytesRead &iBufToSave ); return false; CryptLastByte方法使用了不同长度的密文来加密数据 此处调用了BCryptEncrypt或BCryptDecrypt两次 第一次是为了得到加密数据的大小 第二次是得到密文 bool CMyCNGCryptFile::CryptLastByte(bool bEncrypt PUCHAR pbufFileToOpen ULONG iBytesRead ULONG cbIV PBYTE pbufFileToSave DWORD& iBufToSave) NTSTATUS ntStatus= STATUS_UNSUCCESSFUL; DWORD cbCipherText = ; if (bEncrypt) ntStatus = BCryptEncrypt(m_hKey pbufFileToOpen iBytesRead NULL m_pbIV cbIV NULL &cbCipherText BCRYPT_BLOCK_PADDING); ntStatus = BCryptEncrypt( m_hKey pbufFileToOpen iBytesRead NULL m_pbIV cbIV pbufFileToSave cbCipherText &cbCipherText BCRYPT_BLOCK_PADDING); iBufToSave = cbCipherText; else ntStatus = BCryptDecrypt( m_hKey pbufFileToOpen iBytesRead NULL m_pbIV cbIV NULL &cbCipherText BCRYPT_BLOCK_PADDING); ntStatus = BCryptDecrypt( m_hKey pbufFileToOpen iBytesRead NULL m_pbIV cbIV pbufFileToSave cbCipherText &cbCipherText BCRYPT_BLOCK_PADDING); return false; EnumProviders方法返回当前计算机上已安装的提供者 调用BCryptEnumRegisteredProviders以获取有关已注册提供者的信息 从pProviders中枚举提供者 其为一个PCRYPT_PROVIDERS结构 bool CMyCNGCryptFile::EnumProviders(CStringList *lstRegisteredProviders) ntStatus = BCryptEnumRegisteredProviders(&cbBuffer &pProviders); for ( DWORD i = ; i < pProviders >cProviders; i++) sProvider Format(_T( %s\\n ) pProviders >rgpszProviders[i]); lstRegisteredProviders >AddHead(sProvider); if (pProviders != NULL) BCryptFreeBuffer(pProviders); return true; ~CMyCNGCryptFile析构函数关闭算法提供者
删除所有的指针以防内存泄漏 并销毁密钥哈希 此处调用了BCryptCloseAlgorithmProvider来关闭算法提供者 函数BCryptDestroyKey用于销毁密钥 函数BCryptDestroyHash用于销毁哈希 最后 从PCRYPT_PROVIDERS结构的pProviders中枚举提供者
cha138/Article/program/net/201311/12871相关参考
甲方和乙方采用公钥密码体制对数据文件进行加密传送,甲方用乙方的公钥加密数据文件,乙方要对数据文件进行解密应该使用__
甲方和乙方采用公钥密码体制对数据文件进行加密传送,甲方用乙方的公钥加密数据文件,乙方要对数据文件进行解密应该使用_____。A、乙的公钥B、乙的私钥C、甲的公钥D、甲的私钥答案:B解析:公开密钥密码体
用Delphi实现文件加密压缩技巧 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!引 言 在日常中
用ASP写个简单的加密和解密的类实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 用asp写个
Java文件加密-spring属性文件加密 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! pac
知识大全 如何将pbb转化为普通文件,例如一个加密的视频“xxx.mp4.pbb”文件,我想将它转化为我们普
如何将pbb转化为普通文件,例如一个加密的视频“xxx.mp4.pbb”文件,我想将它转化为我们普用屏幕录像软件录一下就行了。如何将MP4文件转化为AMV文件?AMV文件是特定的文件,常用在彩屏MP3
个人隐私保护软件哪个最好用?,电脑个人隐私保护软件哪个好?电脑中有文件、数据、照片、视频等隐私需要进行保护的话,建议使用透明加密软件,落地即加密,办公或者私人使用电脑不用多余操作,保存文件即加密,使用
Oracle数据库中文件加密详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在Oracle数
知识大全 加密和解密ASP.NET配置文件(Web.config)
加密和解密ASP.NET配置文件(Web.config) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下
知识大全 电脑桌面上有一个资料夹需要加密。就是设定成访问时输密码,怎么弄
电脑桌面上有一个资料夹需要加密。就是设定成访问时输密码,怎么弄?这个很简单,百度一下就知道了!注明什么系统怎么设定加密资料夹到电脑桌面用第三方软体可以实现。请问大家在电脑桌面上的资料夹怎么设定加密呀!
CNG(英文CompressedNaturalGas的缩写),—常温下,将天然气压缩到20MPa,可使存储容器的储气能力为常态的200倍。 LNG(英文liquefiednaturalgas的缩写)