将Philips Fresle将VB6 AES Rijndael Block Cipher转换为C# [英] Converting VB6 AES Rijndael Block Cipher to C# by Phil Fresle

查看:241
本文介绍了将Philips Fresle将VB6 AES Rijndael Block Cipher转换为C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一个经典的asp应用程序转换为C#,并希望能够解密最初在经典asp中加密的c#中的字符串。经典的asp代码是 here ,而c#代码是 here 。我所面临的问题是asp和C#中加密和解密方法的签名是不同的。这里是我的解密代码,它包裹了解密码。

 功能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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆