VB.NET 中的 DES 和三重 DES 实现






4.38/5 (5投票s)
一个简单的 VB.NET DES/三重 DES 实现,没有实例化开销。
引言
我正在一个慢速 CPU 上执行大量的加密操作,对性能不满意。由于我只处理几十个字节的数据,我怀疑问题在于 .NET 加密服务实例化的开销,事实也确实如此。
与其学习 CryptoAPI 并希望它没有相同的开销,我移植了 Christophe Devine 的 C++ 实现(包含在 zip 文件中),该实现没有开销。
Using the Code
我包含了一个演示,它使用 DES
类和 .NET 加密类。它显示输出是相同的。还有几个基准测试按钮。
使用该类非常简单。首先,创建该类
Dim myDes As New DES()
然后调用子程序
myDes.encrypt_des(key8, input, input.Length, output, outputLength)
模式为 CBC(密码块链接)。
为了演示,在加密后将输出复制回输入以进行解密。输入必须是 8 的倍数(不为您添加填充)。
DES
类不执行任何异常处理。如果没有错误,将不会有异常,并且它会将处理的字节数放入 outputLength
整数中,这将与 input.Length
相同。
对于我的目的,未使用 TransformFinalBlock
。
DES
类在 Compact Framework 上也能正常工作。
演示截图

|
|
关注点
如基准测试所示,在发布配置中,实例化基准测试(大量小操作)比 .NET 快约 14 倍(在某些系统上快 25 倍),但数据基准测试(16 兆字节)慢约 4 倍,因此该类仅适用于大量小操作。
VB.NET 使所有数学运算都显得很笨拙,因为强制执行了空格,并且从十六进制常量中删除了前导 0。(更新:在 Visual Studio 中找到了一个选项来删除自动格式化(工具 > 选项 > 文本编辑器 > Basic > VB 特定)。)
两个主要问题困扰了我
- 为什么 &HFFFFFFFF 不是有效的
UInt32
?因为十六进制常量默认被视为Int32
,除非你在末尾添加 UI:&HFFFFFFFFUI。 - 我需要将字节转换为
UInt32
,然后将它们左移到UInt32
中(GET_UINT32
子程序)。这个CUInt
错误让我花费了大约 4 个小时。
由于 VB.NET 没有 #define
的概念,我修改了这些转换后的子程序,以接受另一个变量作为继承的变量。并且由于处理数组的不同方式,我添加了一个 nSK
枚举器到一些子程序中。
这是 GPL,因为 Christophe 的许可证是 GPL。
移植示例
对移植 C++ 到 VB.NET 感兴趣的人也应该觉得这段代码有用。我不太擅长写 C++,但我可以理解它。
这里有一些移植示例
/* DES round macro */
#define DES_ROUND(X,Y) \
{ \
T = *SK++ ^ X; \
Y ^= SB8[ (T ) & 0x3F ] ^ \
SB6[ (T >> 8) & 0x3F ] ^ \
SB4[ (T >> 16) & 0x3F ] ^ \
SB2[ (T >> 24) & 0x3F ]; \
\
T = *SK++ ^ ((X << 28) | (X >> 4)); \
Y ^= SB7[ (T ) & 0x3F ] ^ \
SB5[ (T >> 8) & 0x3F ] ^ \
SB3[ (T >> 16) & 0x3F ] ^ \
SB1[ (T >> 24) & 0x3F ]; \
}
'DES round macro
'init nSK as -1
Private Sub DES_ROUND(ByRef X As UInt32, ByRef Y As UInt32, _
ByRef T As UInt32, ByRef SK() As UInt32, ByRef nSK As Integer)
nSK += 1
T = SK(nSK) Xor X
Y = Y Xor SB8((T ) And &H3FUI) Xor _
SB6((T >> 8) And &H3FUI) Xor _
SB4((T >> 16) And &H3FUI) Xor _
SB2((T >> 24) And &H3FUI)
nSK += 1
T = SK(nSK) Xor ((X << 28) Or (X >> 4))
Y = Y Xor SB7((T ) And &H3FUI) Xor _
SB5((T >> 8) And &H3FUI) Xor _
SB3((T >> 16) And &H3FUI) Xor _
SB1((T >> 24) And &H3FUI)
End Sub
// DES 64-bit block encryption/decryption
void des_crypt( uint32 SK[32], uint8 input[8], uint8 output[8] )
{
uint32 X, Y, T;
GET_UINT32( X, input, 0 );
GET_UINT32( Y, input, 4 );
DES_IP( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_ROUND( Y, X ); DES_ROUND( X, Y );
DES_FP( Y, X );
PUT_UINT32( Y, output, 0 );
PUT_UINT32( X, output, 4 );
}
'DES 64-bit block encryption/decryption
Private Sub des_crypt(ByRef SK() As UInt32, _
ByRef input() As Byte, ByRef output() As Byte)
Dim X, Y, T As UInt32
GET_UINT32(X, input, 0)
GET_UINT32(Y, input, 4)
DES_IP(X, Y, T)
Dim nSK As Integer = -1
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
DES_FP(Y, X, T)
PUT_UINT32(Y, output, 0)
PUT_UINT32(X, output, 4)
End Sub
历史
- 2010.01.27
- 初次发布
- 2010.01.27
- 通过添加空格和前导 0 来美化代码
- 将移植示例添加到文章中