首先,说一个标准的实现方法。(实现兼容Weak KEY的方向稍后再说)
此方法受.NET自身的限制,具有一定的局限性,无法使用DES弱密钥(Weak Key),如FFFFFFFFFFFFFFFF(十六进制),一旦使用程序就会报错(错误提示大意为:检测到弱密钥)。
因此,该代码无法用于设计智能卡应用(许多智能卡的初始DES密钥都属于.NET限制的“弱密钥”)。
'注:此处输入输出的字节数组内,均为二进制数据。如果需要使用文本(明文),请自行转换。
Dim inputByteArray As Byte() '明文,以字节数组形式表达
Dim KeyAsBytes() As Byte '密钥,以字节数组形式表达,8字节
Dim IVAsBytes() As Byte '初始向量IV,以字节数组形式表达,8字节Dim DES As New System.Security.Cryptography.DESCryptoServiceProvider()
DES.Key = KeyAsBytes
DES.IV = IVAsBytes
DES.Mode = Security.Cryptography.CipherMode.ECB 'DES-ECB模式
DES.Padding = Security.Cryptography.PaddingMode.NoneDim result() As Byte
result = DES.CreateEncryptor().TransformFinalBlock(inputByteArray, 0, inputByteArray.Length) '运算结果为字节数组
下面讲实现兼容Weak KEY的方法。
网路上早已有大师们写出了功能相同的C#代码,主要原理是利用反射(reflection),绕过.Net对Weak KEY的侦测。
参考链接1:解决DESCryptoServiceProvider加解密时弱密钥异常_努力的犀牛的博客-CSDN博客_如何检测是否为弱密钥
参考链接2:C# 3DES加密及弱密钥处理_MHSMIE的专栏-CSDN博客
参考链接3:c# - Weak Key for DES in .NET - Stack Overflow
我们将C#的代码稍作修改,变成VB .Net代码。
Private Function CreateWeakDESDecryptor(ByVal uKey() As Byte) As Security.Cryptography.ICryptoTransformDim uIV() As Byte = New Byte() {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0} 'IVDim DES As New System.Security.Cryptography.DESCryptoServiceProvider()DES.Mode = Security.Cryptography.CipherMode.ECB 'DES-ECB模式(该模式不需要IV)DES.Padding = Security.Cryptography.PaddingMode.None '禁止自动填充Dim mi As System.Reflection.MethodInfo = DES.GetType().GetMethod("_NewEncryptor", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)Dim Par() As Object = {uKey, DES.Mode, uIV, DES.FeedbackSize, 1} '最后的1为解密,0为加密Dim trans As Security.Cryptography.ICryptoTransform = mi.Invoke(DES, Par)Return transEnd FunctionPrivate Function CreateWeakDESEncryptor(ByVal uKey() As Byte) As Security.Cryptography.ICryptoTransformDim uIV() As Byte = New Byte() {&H0, &H0, &H0, &H0, &H0, &H0, &H0, &H0}Dim DES As New System.Security.Cryptography.DESCryptoServiceProvider()DES.Mode = Security.Cryptography.CipherMode.ECB 'DES-ECB模式(该模式不需要IV)DES.Padding = Security.Cryptography.PaddingMode.None '禁止自动填充Dim mi As System.Reflection.MethodInfo = DES.GetType().GetMethod("_NewEncryptor", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)Dim Par() As Object = {uKey, DES.Mode, uIV, DES.FeedbackSize, 0} '最后的1为解密,0为加密Dim trans As Security.Cryptography.ICryptoTransform = mi.Invoke(DES, Par)Return transEnd Function'使用如下方法调用
Dim uTmpEncText as Byte = New Byte() {&H6A, &HCC ,&H20 ,&H4F ,&H8E &HFB ,&HCC ,&HC7}
Dim uKey() as Byte = New Byte() {&H00 ,&H01 ,&H02 ,&H03 ,&H04 ,&H05 ,&H06 ,&H07}
Dim uTmpClearText() as ByteuTmpClearText = CreateWeakDESDecryptor(uKey).TransformFinalBlock(uTmpEncText, 0, 8)