将Philips Fresle将VB6 AES Rijndael Block Cipher转换为C# [英] Converting VB6 AES Rijndael Block Cipher to C# by Phil Fresle
问题描述
功能AESDecrypt(sCypher)
如果sCypher< ;> 然后
Dim bytIn()
Dim bytOut
Dim bytPassword()
Dim lCount
Dim lLength
Dim sTemp
Dim sPassword
sPassword =My_Password
lLength = Len(sCypher)
ReDim bytIn(lLength / 2-1)
对于lCount = 0到lLength / 2-1
bytIn(lCount)= CByte(& H& Mid(sCypher,lCount * 2 + 1,2))
下一个
lLength = Len(sPassword)
ReDim bytPassword(lLength-1)
对于lCount = 1到lLength
bytPassword(lCount-1)= CByte(AscB(Mid(sPassword,lCount,1)))
下一步
bytOut = DecryptData(bytIn,bytPassword)//'这是问题child
lLength = UBound(bytOut)+ 1
sTemp =
对于lCount = 0到lLength - 1
sTemp = sTemp& Chr(bytOut(lCount))
下一个
AESDecrypt = sTemp
如果
结束功能
pre>
public static byte [] DecryptData(byte [] message,byte [] password,
byte [] initialisationVector,BlockSize blockSize,
KeySize keySize,EncryptionMode cryptMode)
{...}
我可以使用什么值来初始化Vector,blockSize,keySize,cryptMode,以便能够解密经典asp代码的方式。
使用Phil Fresle的C#Rijndael实现,可以使用以下代码成功解密了使用Phil的ASP / VBScript版本加密的值。
您可以在这里阅读我关于加密的答案:传统asp和ASP.NET之间的密码加密/解密
public string DecryptData(string encryptedMessage,string password)
{
if(encryptedMessage.Length%2 == 1)
throw new异常(二进制键不能有奇数位);
byte [] byteArr = new byte [encryptedMessage.Length / 2]; (int index = 0; index< byteArr.Length; index ++)
string byteValue = encryptedMessage.Substring(index * 2,2);
byteArr [index] = byte.Parse(byteValue,NumberStyles.HexNumber,CultureInfo.InvariantCulture);
}
byte [] result = Rijndael.DecryptData(
byteArr,
Encoding.ASCII.GetBytes(password),
new byte [] {},//初始化向量
Rijndael.BlockSize.Block256,//在大多数实现中通常为128
Rijndael.KeySize.Key256,
Rijndael.EncryptionMode.ModeECB // Rijndael。 EncryptionMode.ModeCBC
);
返回ASCIIEncoding.ASCII.GetString(result);
}
大多数默认实现将使用密钥大小为 128 , 192 或 256 位。在 128 位的块大小是标准的。虽然一些实现允许128位以外的块大小,但是当尝试在一个实现中获取数据加密以在另一个实现中正确解密时,更改块大小将只会将另一个项目添加到混合中。
更新
原来我在这里有一个错误;应该将 EncryptionMode
设置为 EncryptionMode.ModeECB
,而不是 EncryptionMode.ModeCBC
。 ECB不太安全( https://crypto.stackexchange.com/questions/225/should-i-use-ecb-or-cbc-encryption-mode-for-my-block-cipher ),因为它不会循环CBC确实如此,但是这是如何在VB版本的加密中实现的。有趣的是,使用CBC的ECB加密值将会在第一个字节上运行直到某一点(我想象这与块有关大小),此值的剩余部分被破坏。在VB版本中加密long-ish字符串并使用上面发布的代码进行解密时,您可以特别清楚地看到这一点,模式为 EncryptionMode.ModeECB
I am converting a classic asp application to C#, and would like to be able to decrypt strings in c# that were originally encrypted in classic asp. the classic asp code is here, and the c# code is here. The problem that i am facing is that the signatures of the Encrypt and Decrypt methods in asp vs C# are different. here is my asp code for decrypting, which wraps the decrypt code.
Function AESDecrypt(sCypher)
if sCypher <> "" then
Dim bytIn()
Dim bytOut
Dim bytPassword()
Dim lCount
Dim lLength
Dim sTemp
Dim sPassword
sPassword = "My_Password"
lLength = Len(sCypher)
ReDim bytIn(lLength/2-1)
For lCount = 0 To lLength/2-1
bytIn(lCount) = CByte("&H" & Mid(sCypher,lCount*2+1,2))
Next
lLength = Len(sPassword)
ReDim bytPassword(lLength-1)
For lCount = 1 To lLength
bytPassword(lCount-1) = CByte(AscB(Mid(sPassword,lCount,1)))
Next
bytOut = DecryptData(bytIn, bytPassword) //' this is the problem child
lLength = UBound(bytOut) + 1
sTemp = ""
For lCount = 0 To lLength - 1
sTemp = sTemp & Chr(bytOut(lCount))
Next
AESDecrypt = sTemp
End if
End Function
However, in c# i am struggling to convert this function because the c# equivalent of DecryptData has more params
public static byte[] DecryptData(byte[] message, byte[] password,
byte[] initialisationVector, BlockSize blockSize,
KeySize keySize, EncryptionMode cryptMode)
{...}
what values can i use for initialisationVector, blockSize, keySize, cryptMode so as to be able to decrypt the same way the classic asp code does.
Using Phil Fresle's C# Rijndael implementation, you can use the following code to have successfully decrypt a value that was encrypted with Phil's ASP/VBScript version.
You can read my answer about encrypting here: Password encryption/decryption between classic asp and ASP.NET
public string DecryptData(string encryptedMessage, string password)
{
if (encryptedMessage.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] byteArr = new byte[encryptedMessage.Length / 2];
for (int index = 0; index < byteArr.Length; index++)
{
string byteValue = encryptedMessage.Substring(index * 2, 2);
byteArr[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
byte[] result = Rijndael.DecryptData(
byteArr,
Encoding.ASCII.GetBytes(password),
new byte[] { }, // Initialization vector
Rijndael.BlockSize.Block256, // Typically 128 in most implementations
Rijndael.KeySize.Key256,
Rijndael.EncryptionMode.ModeECB // Rijndael.EncryptionMode.ModeCBC
);
return ASCIIEncoding.ASCII.GetString(result);
}
Most default implementations will use a key size of 128, 192, or 256 bits. A block size at 128 bits is standard. Although some implementations allow block sizes other than 128 bits, changing the block size will just add another item into the mix to cause confusion when trying to get data encrypted in one implementation to properly decrypt in another.
UPDATE
Turns out I was wrong about one piece here; the EncryptionMode
should be set as EncryptionMode.ModeECB
, not EncryptionMode.ModeCBC
. "ECB" is less secure (https://crypto.stackexchange.com/questions/225/should-i-use-ecb-or-cbc-encryption-mode-for-my-block-cipher) because it doesn't cycle like CBC does, but that is how it was implemented in the VB version of the encryption.
Interestingly enough, using CBC on an ECB encrypted value WILL work for the first handful of bytes up until a certain point (i'd imagine this has to do with the block size) at which point the remainder of the value is mangled. You can see this particularly clearly when encrypting a long-ish string in the VB version and decrypting it with the code I posted above with a mode of EncryptionMode.ModeECB
这篇关于将Philips Fresle将VB6 AES Rijndael Block Cipher转换为C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!