如何在.net中使用CNG(或启用AES-NI的指令集)
本文关键字:启用 AES-NI 指令集 CNG net | 更新日期: 2023-09-27 18:14:36
目前在c#中使用AES对文本进行大量的加密/解密。
对于纯软件系统,需要解密的大量数据集可能需要相当长的处理器时间。我知道英特尔推出了他们的AES-NI指令集,AMD也推出了类似的指令集。
我使用的是。net 4.0,我知道windows CNG框架使用了这些指令集,但是。net世界中的AesManaged
似乎没有使用这些指令集。
有一个很棒的项目"CLR安全",它是。net 3.5到windows CNG的一个网关,但是它已经一年没有维护了,我宁愿(如果可能的话)不要跳上一个垂死的项目。
. net 4中有一个CNGProvider类,但似乎没有足够的文档来拼凑出一个用于AES的工作解密。
有没有人有这个主题的经验,他们可以指出我在正确的方向上如何在纯。net环境中实现AES-NI,使用预制类,而不必直接从c#做p/调用?(如果有一个包装器类来做这件事就好了,只要它被维护)。
AesCryptoServiceProvider
呢?它说使用CAPI,等等如果有的话,希望有CNG。——Rup
这个评论有很大的帮助,在做了一些挖掘之后,看起来AesCryptoServiceProvider
将使用AES-NI。然而,我找不到微软关于这方面的任何"官方"文档。当运行简单的计时基准测试时,差异大约是15倍,所以要么API本身被大量优化(对于15倍的增加来说是相当不错的优化),要么它使用AES-NI指令集。
不幸的是,我没有一个非AES-NI盒子来测试,但如果我得到一个,我会更新这个线程的结果。
所以我很有信心这是用于AES-NI的API,但不能保证没有进一步的测试。
如何在。net中使用CNG(或启用AES-NI的指令集)?
我将集中讨论AES-NI指令集问题。我发现它很有趣,因为我自己也想知道它(在C和c++中使用)。
Microsoft在Visual Studio 2008 SP1 (_MSC_FULL_VER >= 150030729
)中添加了AES-NI支持。您最早可以在Microsoft产品中看到AES-NI是在2008年左右,因为早期的编译器不支持它。这意味着Server 2008有它,Windows Vista也可能通过Service Pack或更高版本安装。
根据MS Crypto API是否支持AES和AES- ni处理器指令?, rsaenh.dll
和bcryptprimitives.dll
都有。IvanP在Windows 7和Windows 10上进行了测试。
然而,在Windows 8.1上的测试显示…
# Using a Developer Command prompt so dumpbin is on-path:
> dumpbin /disasm c:'Windows'System32'rsaenh.dll > rsaenh.dll.txt
> dumpbin /disasm c:'Windows'System32'bcryptprimitives.dll > bcryptprimitives.dll.txt
:
# Using a GitBash terminal for grep
$ grep -i aes rsaenh.dll.txt
$
:
$ grep -i aes bcryptprimitives.dll.txt
000000018000234A: 66 0F 3A DF C0 00 aeskeygenassist xmm0,xmm0,0
0000000180002363: 66 0F 38 DB C0 aesimc xmm0,xmm0
000000018000237E: 66 0F 38 DC 41 10 aesenc xmm0,xmmword ptr [rcx+10h]
0000000180002384: 66 0F 38 DC 41 20 aesenc xmm0,xmmword ptr [rcx+20h]
000000018000238A: 66 0F 38 DC 41 30 aesenc xmm0,xmmword ptr [rcx+30h]
0000000180002390: 66 0F 38 DC 41 40 aesenc xmm0,xmmword ptr [rcx+40h]
0000000180002396: 66 0F 38 DC 41 50 aesenc xmm0,xmmword ptr [rcx+50h]
000000018000239C: 66 0F 38 DC 41 60 aesenc xmm0,xmmword ptr [rcx+60h]
00000001800023A2: 66 0F 38 DC 41 70 aesenc xmm0,xmmword ptr [rcx+70h]
00000001800023AF: 66 0F 38 DC 01 aesenc xmm0,xmmword ptr [rcx]
00000001800023B4: 66 0F 38 DC 41 10 aesenc xmm0,xmmword ptr [rcx+10h]
00000001800023C3: 66 41 0F 38 DD 02 aesenclast xmm0,xmmword ptr [r10]
000000018001936E: 66 0F 38 DC 41 10 aesenc xmm0,xmmword ptr [rcx+10h]
0000000180019374: 66 0F 38 DC 41 20 aesenc xmm0,xmmword ptr [rcx+20h]
000000018001937A: 66 0F 38 DC 41 30 aesenc xmm0,xmmword ptr [rcx+30h]
0000000180019380: 66 0F 38 DC 41 40 aesenc xmm0,xmmword ptr [rcx+40h]
0000000180019386: 66 0F 38 DC 41 50 aesenc xmm0,xmmword ptr [rcx+50h]
000000018001938C: 66 0F 38 DC 41 60 aesenc xmm0,xmmword ptr [rcx+60h]
0000000180019392: 66 0F 38 DC 41 70 aesenc xmm0,xmmword ptr [rcx+70h]
000000018001939F: 66 0F 38 DC 01 aesenc xmm0,xmmword ptr [rcx]
00000001800193A4: 66 0F 38 DC 41 10 aesenc xmm0,xmmword ptr [rcx+10h]
00000001800193B3: 66 41 0F 38 DD 02 aesenclast xmm0,xmmword ptr [r10]
000000018001952E: 66 0F 38 DE C4 aesdec xmm0,xmm4
0000000180019533: 66 0F 38 DE CC aesdec xmm1,xmm4
0000000180019538: 66 0F 38 DE D4 aesdec xmm2,xmm4
000000018001953D: 66 0F 38 DE DC aesdec xmm3,xmm4
000000018001954B: 66 0F 38 DF C4 aesdeclast xmm0,xmm4
0000000180019550: 66 0F 38 DF CC aesdeclast xmm1,xmm4
0000000180019555: 66 0F 38 DF D4 aesdeclast xmm2,xmm4
000000018001955A: 66 0F 38 DF DC aesdeclast xmm3,xmm4
000000018002E8B5: 66 0F 38 DE 41 10 aesdec xmm0,xmmword ptr [rcx+10h]
000000018002E8BB: 66 0F 38 DE 41 20 aesdec xmm0,xmmword ptr [rcx+20h]
000000018002E8C1: 66 0F 38 DE 41 30 aesdec xmm0,xmmword ptr [rcx+30h]
000000018002E8C7: 66 0F 38 DE 41 40 aesdec xmm0,xmmword ptr [rcx+40h]
000000018002E8CD: 66 0F 38 DE 41 50 aesdec xmm0,xmmword ptr [rcx+50h]
000000018002E8D3: 66 0F 38 DE 41 60 aesdec xmm0,xmmword ptr [rcx+60h]
000000018002E8D9: 66 0F 38 DE 41 70 aesdec xmm0,xmmword ptr [rcx+70h]
000000018002E8E6: 66 0F 38 DE 01 aesdec xmm0,xmmword ptr [rcx]
000000018002E8EB: 66 0F 38 DE 41 10 aesdec xmm0,xmmword ptr [rcx+10h]
000000018002E8FA: 66 41 0F 38 DF 02 aesdeclast xmm0,xmmword ptr [r10]
000000018003F458: 66 0F 38 DC E8 aesenc xmm5,xmm0
000000018003F45D: 66 0F 38 DC D8 aesenc xmm3,xmm0
000000018003F462: 66 0F 38 DC E0 aesenc xmm4,xmm0
000000018003F467: 66 0F 38 DC F0 aesenc xmm6,xmm0
000000018003F475: 66 0F 38 DD EF aesenclast xmm5,xmm7
000000018003F47A: 66 0F 38 DD DF aesenclast xmm3,xmm7
000000018003F47F: 66 0F 38 DD E7 aesenclast xmm4,xmm7
000000018003F492: 66 0F 38 DD F7 aesenclast xmm6,xmm7
所以,在现代Windows上,你需要使用一些依赖于bcryptprimitives.dll
的东西。我不知道什么。net原语使用bcryptprimitives.dll
.
我还检查了Windows 8.1上的以下dll,没有AES-NI指令:
- advapi32.dll
- bcrypt.dll
- crypt32.dll
- cryptbase.dll
- cryptcatsvc.dll
- cryptdlg.dll
- cryptdll.dll
- cryptext.dll
- cryptnet.dll
- cryptowinrt.dll
- cryptsp.dll
- cryptsvc.dll
在微软网站上没有太多关于这个主题的信息。我从csp"aes-ni"站点:microsoft.com获得了两个点击,而csp"aesni"站点:microsoft.com获得了0个点击。不管发生了什么,微软都是保密的。
我曾使用过最早的具有这些特性的芯片组。那时Windows 7还不能使用AES。我求助于当时可用的Ubuntu,并使用英特尔文档和一些内联汇编做了一个cpuid。这达到了我训练的目的。不过,我学到的一件事是"英特尔安全密钥"。几乎与"aes - ni"同时面世。因此,如果我在芯片组中发现RDRAND指令,这意味着我"可能"AES-NI。这样一来,我能做的最简单的(但没有详细说明)就是
//在撰写本文时,PF_RDRAND_INSTRUCTION_AVAILABLE尚未作为MSDN API的一部分记录IsProcessorFeaturePresent (PF_RDRAND_INSTRUCTION_AVAILABLE);
我们也可以这样使用CPU的内在特性https://learn.microsoft.com/en - us/cpp/intrinsics/cpuid cpuidex?view=vs - 2019
请参阅下面的文档以获得更多"校对"。https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp1894.pdf