技术标签: 算法 其他 api windows microsoft 加密 algorithm
Microsoft Windows Vista中的下一代加密API
CNG是Windows Vista中最新的加密体系,其支持新的API、一体式用户及内核模式、灵活的加密方法及新的密码套件。
简介
CNG是Windows Vista中一种新的、灵活的框架结构,其实现了可扩展的提供者模式,可允许你通过指定所需的加密算法来加载某个提供者,而不用针对某个特殊的提供者进行硬编码。
其好处在于算法提供者可被替换或升级,而无需修改相关程序代码就可使用新的提供者;同时,如果确定某些算法在将来会变得不安全,也可以安装更安全的版本,且对原程序代码无任何影响。这样一来,就可通过识别所需的加密算法,而不是特定的提供者来加载一个CNG提供者。大多数CNG API都需要一个提供者或由提供者创建的一个对象。
在本文中,将会讲解CNG新的安全特性,并与RSA及AES进行比较,并在托管及非托管模式下使用“Crypto API”(Vista之前的加密API),及它们如何在Windows Vista下通过CNG来实现。
背景知识
关于RSA
RSA是公匙加密中已确定的标准,RSA本身的名称派生自算法发明的名字,他们是:Ron Rivest、Adi Shamir、Leonard Adleman。RSA的原理及安全性基于现今的认识——即不可能在适当的时间内找到一个大数的质数因子(如n=qp,在这p及q为质数)。细则如下:
公匙:n=qp(p及q为大质数)
E相关质数(p-1)(q-1)
私匙:d e-1 mod ((p-1)(q-1))
加密:c = me mod n
解密:m = cd mod n
关于AES
Advanced Encryption Standard (AES),也称为Rijndael,是一种128位块的对称加密,已被采用为美国政府的一种加密标准。细则如下:
AES操作一个4×4的字节数组。
加密时,每轮AES(除了最后一轮)由四阶段组成:AddRoundKey、Subbytes、Shift rows、Mix columns。
在每一阶段,字节为下一级进行了相关操纵及处理。
下一代加密API:CNG
CNG提供一个API集,用于执行基本的加密操作,如创建哈希、加密及解密数据。CNG中的每个算法类都有一个原语路由,使用这些原语API的程序则会链接到路由库(用户模式中是Bcrypt.dll,核心模式中是Dsecdd.sys),并调用不同的CNG原语函数。所有这些算法原语都由各个不同的路由组件管理,这些路由跟踪安装在系统中每个算法的实现,并把对各个函数的调用,路由到适当的原语提供者模块中。
下图演示了CNG加密原语的设计与函数模式。
CNG为下列算法提供了原语:
随机数生成:表示可插入的随机数生成(RNG)。
哈希:表示用于哈希的算法,如SHA1及SHA2。
对称加密:表示对称加密的算法,如AES、3DES、RC4。
非对称加密:表示非对称加密算法,如RSA。
签名:表示如DSA及ECDSA之类的签名算法,也可与RSA一同使用。
秘密协定:表示私密协定算法,如Diffie-Hellman及椭圆曲线Diffie-Hellman。
使用RSA CryptoService Provider(CAPI)
就CAPI而言,所有的加密算法都预定义在wincrypt.h中,这样就非常难以扩展加密功能以适应各自程序的需要,比如说添加一个自定义的对称加密算法就不是一件简单的事;其次,CAPI需要微软来签名其实现,所以它可作为安全命名空间的一部分。
以下是传统方式的加密及解密,使用了RSACryptoServiceProvider。
RSACryptoServiceProvider MyAsymmetricAlgorithm = new RSACryptoServiceProvider();
byte[] PlainTextBytes;
byte[] CipherTextBytes;
private void Encrypt()
{
PlainTextBytes = System.Text.Encoding.UTF8.GetBytes(TextBoxOriginal.Text);
CipherTextBytes = MyAsymmetricAlgorithm.Encrypt(PlainTextBytes, true);
TextBoxEncrypted.Text = TextBoxEncrypted.Text +
+ Convert.ToBase64String(CipherTextBytes);
ShowPublicPrivate();
//剩余代码已省略
}
private void Decrypt()
{
PlainTextBytes = MyAsymmetricAlgorithm.Decrypt(CipherTextBytes, true);
TextBoxOriginal.Text = System.Text.Encoding.UTF8.GetString
(PlainTextBytes);
}
private void ShowPublicPrivate()
{
RSAParameters MyParameters = new RSAParameters();
MyParameters = MyAsymmetricAlgorithm.ExportParameters(true);
TextBoxPrivateKey.Text = Convert.ToBase64String(MyParameters.D);
TextBoxPublicKey.Text = Convert.ToBase64String(MyParameters.Modulus);
//剩余代码已省略
}
与CNG一同使用CryptoService Provider
在CNG中,所有加密常量均为“字符串”而不是数值,因为可使用任何字符串常量来定义算法,所以当程序试图使用算法时,CNG会加载注册了此名字的加密算法提供者。我们也可为SSL及TLS插入自定义的加密算法,添加一个新插件的核心函数是:BCryptAddContextFunctionProvider。
使用CNG API用于加密原语操作的一般步骤如下:
1、 打开算法提供者(Provider)。
2、 Get或Set算法属性。
3、 创建或导入一个密钥。
4、 执行加密操作。
5、 关闭算法提供者。
用作RSA加密的字符串是:BCRYPT_RSA_ALGORITHM,以下是此算法的伪代码:
BCryptOpenAlgorithmProvider(&hAlg...)
BCryptGetProperty(hAlg,BCRYPT_BLOCK_LENGTH,&dwBlockSize...)
//分配缓冲区,取整到下一块大小
BCryptGetProperty(hAlg,BCRYPT_OBJECT_LENGTH,&cbKeyObjectLen...)
//为密钥对象分配缓冲区
BCryptGenerateSymmetricKey(hAlg,&hKey...)
BCryptEncrypt(hKey,...)
//数据现在已被加密
BCryptDestroyKey(hKey)
BCryptCloseAlgorithmProvider(hAlg,0)
//释放缓冲区
BCRYPT_AES_ALGORITHM是字符串变量,其把句柄交给了真正的算法,所以在此之后,如果算法需要修改,我们只需修改AES的实现部分即可,以下代码还包括了密钥的生成。
#include "stdafx.h"
using namespace std;
#pragma comment(lib, "bcrypt")
wchar_t *GetEncryptionAlg()
{
return BCRYPT_AES_ALGORITHM;
}
LPBYTE GetPwd()
{
static const BYTE key[] = {1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,0};
return (LPBYTE)key;
}
LPBYTE GetIV()
{
static const BYTE iv[] = {1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};
return (LPBYTE)iv;
}
int _tmain(int argc, _TCHAR* argv[])
{
BCRYPT_ALG_HANDLE hAlg = NULL;
if (BCryptOpenAlgorithmProvider(
&hAlg,
GetEncryptionAlg(),
NULL,
0) == STATUS_SUCCESS)
{
BCRYPT_KEY_HANDLE hKey = NULL;
DWORD cbKey = 0;
DWORD cbData = 0;
if (BCryptGetProperty(
hAlg,
BCRYPT_OBJECT_LENGTH,
reinterpret_cast(&cbKey),
sizeof cbKey,
&cbData,
0) == STATUS_SUCCESS)
{
LPBYTE pbKey = new (nothrow)BYTE[cbKey];
if (pbKey)
{
BCRYPT_KEY_HANDLE hKey = NULL;
LPCSTR szPwd = (LPCSTR)GetPwd();
if (BCryptGenerateSymmetricKey(
hAlg,
&hKey,
pbKey,
cbKey,
(PUCHAR)szPwd,
(ULONG)strlen(szPwd),
0) == STATUS_SUCCESS)
{
printf("!!!");
}
}
}
}
return 0;
}
解密数据与上面类似,除了BCryptDecrypt。
BCryptOpenAlgorithmProvider(&hAlg...)
BCryptGetProperty(hAlg,BCRYPT_BLOCK_LENGTH,&dwBlockSize...)
//分配缓冲区,取整到下一块大小
BCryptGetProperty(hAlg,BCRYPT_OBJECT_LENGTH,&cbKeyObjectLen...)
//为密钥对象分配缓冲区
BCryptGenerateSymmetricKey(hAlg,&hKey...)
BCryptDecrypt(hKey,...)
//数据现在已被加密
BCryptDestroyKey(hKey)
BCryptCloseAlgorithmProvider(hAlg,0)
//释放缓冲区
以下代码是对数据进行哈希处理。
BCryptOpenAlgorithmProvider(&hAlg...)
BCryptGetProperty(hAlg,BCRYPT_OBJECT_LENGTH,&cbHash...)
//为哈希分配缓冲区
BCryptCreateHash(hAlg,&hHash,...)
BCryptHashData(hHash,...)
//使用哈希数据
//其他程序代码
BCryptDestroyHash(hHash)
BCryptCloseAlgorithmProvider(hAlg,0)
//释放缓冲区
一个加密程序可通过CNG,创建其自己的加密提供者,在CNG框架中,已自带了所有相关所需的接口及功能插件,此核心函数为:BCryptAddContextFunctionProvider。
以下是添加一个BCRYPT_MYTEST_ALGORITHM测试算法所需的基本结构,详细步骤请查阅CNG SDK3中的Install and register “CNG add-ins”。
#define BCRYPT_MYTEST_ALGORITHM
status = BCryptAddContextFunctionProvider(
CRYPT_LOCAL,
NULL, //default
BCRYPT_CIPHER_INTERFACE,
BCRYPT_MYTEST_ALGORITHM,
L"MyTest Provider",
CRYPT_PRIORITY_TOP);
也可使用CNG中的函数BCryptResolveProviders来查询所有支持的算法。
#include "stdafx.h"
#pragma comment(lib, "bcrypt")
#ifndef NT_SUCCESS
# define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
int __cdecl main(int argc, __in_ecount(argc) LPWSTR *wargv)
{
argc;
wargv;
BOOLEAN bFipsEnabled = FALSE;
if (NT_SUCCESS(BCryptGetFipsAlgorithmMode(&bFipsEnabled)))
printf("FIPS is %Senabled./n",bFipsEnabled ? L"" : L"not ");
PCRYPT_PROVIDER_REFS pProviders = NULL;
DWORD dwBufSize = 0;
const DWORD dwFlags = CRYPT_ALL_FUNCTIONS | CRYPT_ALL_PROVIDERS;
for (DWORD i = BCRYPT_CIPHER_INTERFACE; i <= BCRYPT_RNG_INTERFACE; i++)
{
NTSTATUS ret = BCryptResolveProviders(
NULL,
i,
NULL,
NULL,
CRYPT_UM,
dwFlags,
&dwBufSize,
&pProviders);
if (NT_SUCCESS(ret) && pProviders)
{
printf("dwInterface = %d/n", i);
for (DWORD k=0; k < pProviders->cProviders; k++)
{
PCRYPT_PROVIDER_REF pProv = pProviders->rgpProviders[k];
printf("/tFunction = %S/n", pProv->pszFunction);
printf("/tProvider = %S/n", pProv->pszProvider);
// print property names
for ( DWORD j = 0; j < pProv->cProperties; j++)
printf("/tProperty %d = %S/n", j,
pProv->rgpProperties[j]->pszProperty);
printf("/n");
}
BCryptFreeBuffer(pProviders);
pProviders = NULL;
dwBufSize = 0;
}
}
return 0;
}
CNG的托管库已随Visual Studio 2008提供,如果使用Visual Studio 2005,可使用CNG SDK3的非托管版本在Windows Vista上进行开发。同时,CNG也可访问Microsoft Cryptographic Service providers中所使用的所有CAPI密钥。
CNG加密原语函数列表
以下是CNG API中定义的用于加密的函数列表:
• BCryptCloseAlgorithmProvider
• BCryptCreateHash
• BCryptDecrypt
• BCryptDeriveKey
• BCryptDestroyHash
• BCryptDestroyKey
• BCryptDestroySecret
• BCryptDuplicateHash
• BCryptDuplicateKey
• BCryptEncrypt
• BCryptExportKey
• BCryptFinalizeKeyPair
• BCryptFinishHash
• BCryptFreeBuffer
• BCryptGenerateKeyPair
• BCryptGenerateSymmetricKey
• BCryptGenRandom
• BCryptGetProperty
• BCryptHashData
• BCryptImportKey
• BCryptImportKeyPair
• BCryptOpenAlgorithmProvider
• BCryptSecretAgreement
• BCryptSetProperty
• BCryptSignHash
• BCryptVerifySignature
Visual Studio 2008中新的加密算法
在Visual Studio 2008中,已自带了Windows Vista中新的CNG API托管包装函数,其在实现类中以Cng后缀表明。
哈希算法
算法 |
类 |
所支持的操作系统 |
MD5 |
MD5Cng |
Windows Vista |
SHA-1 |
SHA1Cng |
Windows Vista |
SHA-256 |
SHA256CryptoServiceProvider |
Windows 2003 |
SHA-384 |
SHA384CryptoServiceProvider |
Windows 2003 |
SHA-512 |
SHA512CryptoServiceProvider |
Windows 2003 |
算法 |
类 |
所支持的操作系统 |
Elliptic Curve DSA |
ECDSACng |
Windows Vista |
Elliptic Curve Diffie-Hellman |
ECDiffieHellmanCng |
Windows Vista |
平台:mt6582 + android 4.41. 定义sensor id和sensor name(mediatek/custom/common/kernel/imgsensor/inc/kd_imgsensor.h)#define GC2155MIPI_SENSOR_ID 0x2155#define SENSOR_DRVNAME_GC2155_MIPI_YUV "gc2155mipiyu
前言原来,一瞬间,一句话,真的可以改变一个人的命运。说一个前几年一个热门话题:“是否应该跳出舒适圈。”一时间,这个话题便引发众人议论:支持方:愿意挑战不擅长领域的人,勇气可嘉,值得学习。反对派:做自己擅长的事情不好吗?为何非要跳出舒适圈呢?其实,每个人的决定都取决于当下自己的状态以及那一瞬间的冲动,也可能你成了雷军,也可能你和下图一样,大家懂我意思吧一念之间的决定,你敢尝试吗?今天想说的是对于想转行做程序员的一些建议和小小的帮助。每年想转行做程序员的人都不少,现在一些大热门的区块链,人
linux下write操作原理、错误原因及处理方法2012-08-10 14:07:27 我来说两句 收藏 我要投稿linux下write操作原理、错误原因及处理方法 1. write函数介绍(1)文件I/O与标准I/O之争: 根据《UNIX环境高级编程》中介绍,文件I/O与准备I/O之间的差别主要有以下几点:其一,
思科、华为、H3C常用命令对比大全cisco常用命令解释视图模式介绍:普通视图 router>特权视图 router# /在普通模式下输入enable全局视图 router(config)# /在特权模式下输入config t接口视图 router(config-if)# /在全局模式下输入int 接口名称 例如int s0或int e0路由协议视图 router(config-route)# /在全局模式下输入router 动态路由协议名称1、基
运行命令(项目所在路径):npm run dev 会报错出现这个原因是项目里的package.json 文件的问题,找到这一行可以看到这里是serve,一种解决办法是把运行命令改为npm run serve,另一种是把"serve": “vue-cli-service serve”,改成"dev": “vue-cli-service serve”,再运行npm run dev 即可解决...
参考了中文网的搭建方式,安装了nodejs及相关组件npm作为配套; 从官网下载了比较新的cesium版本Cesium-1.93;然后解压后放到D盘下面了。cmd进入D:\Cesium-1.93目录下,输入 启动cesium服务,然后 打开链接http://localhost:8085/ 即可进入页面。自己做代码测试的话可以选择修改"Hello word"那个页面,然后在里面自己随便写一写修改一下。比如我写了CesiumApp。1、切换底图资源2、折叠菜单项3、修改默认视点为北京天安门4、开启关闭
一、work进程的创建在master进程的ngx_start_worker_processes函数中,会调用ngx_spawn_process函数开始创建work进程。创建完成后master进程、work进程同时工作,分别执行不同的业务逻辑。ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, voi
Excel表格中如何批量删除工作表目录Excel表格中如何批量删除工作表1、工作表这么多,一个一个删除太费劲,如何让快速删除?2、按住“ctrl”键选中工作表,工作表颜色变白,鼠标右键点击“删除”即可1、工作表这么多,一个一个删除太费劲,如何让快速删除?2、按住“ctrl”键选中工作表,工作表颜色变白,鼠标右键点击“删除”即可安利一个R语言的优秀博主及其CSDN专栏:博主博客地址:Data+Science+Insight的博客_程序员秘密-R语言从..
MT6737是什么呢? MT6737是联发科技极具成本效益的R.9 Cat-4 LTE解决方案,不但能将模块及内存成本降至最低,符合中低端市场需求,同时具备超越同级产品的性能与电源效能表现。此外,MT6737能在全球范围内支持各式IP多媒体子系统(IMS),支持VoLTE、ViLTE、VoWi...
webpackChain (chain) { chain.plugin('analyzer') .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []) }cnpm install -D webpack-bundle-analyzerhttp://12...
第五章 语句练习5.1什么是空语句?什么时候会用到空语句?解:只含义一个单独的分号的语句是空语句。如:;。如果在程序的某个地方,语法上需要一条语句但是逻辑上不需要,此时应该使用空语句。while (cin >> s && s != sought) ;练习5.2什么是块?什么时候会用到块?解:用花括号括起来的语句和声明的序列就是块。{ // ....
swarm主网查钱包余额概述网址新矿机版本概述Swarm 主网发布已经在今天6月13日正式开始了,将于 6 月 21 日全部部署完成。截至 6 月 10 日,代币合约已部署到主网。BZZ的合约地址是:0x19062190b1925b5b6689d7073fdfc8c2976ef8cb网址https://etherscan.io/新矿机版本最新的 Swarm 客户端,名为“Bee 1.0 候选版本”,将发布。它将被标记为版本 1.0-rc。对于节点运行者来说,重要的是要知道不建议在分发代