可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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