c# - Phil Fresle 将 VB6 AES Rijndael 分组密码转换为 C#

标签 c# encryption vbscript asp-classic

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

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

但是,在 c# 中,我很难转换此函数,因为 DecryptData 的 c# 等价物具有更多参数

public static byte[] DecryptData(byte[] message, byte[] password, 
            byte[] initialisationVector, BlockSize blockSize, 
            KeySize keySize, EncryptionMode cryptMode)
        {...}

我可以为 initialisationVector、blockSize、keySize、cryptMode 使用什么值,以便能够像经典的 asp 代码一样解密。

最佳答案

使用 Phil Fresle 的 C# Rijndael 实现,您可以使用以下代码成功解密使用 Phil 的 ASP/VBScript 版本加密的值。

你可以在这里阅读我关于加密的回答: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);
    }

大多数默认实现将使用 128192256 位的 key 大小。 128 位的 block 大小是标准的。尽管某些实现允许 block 大小不是 128 位,但更改 block 大小只会将另一项添加到混合中,从而在尝试让在一种实现中加密的数据在另一种实现中正确解密时造成混淆。

更新

原来我在这里错了一件; 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 版本的加密中的实现方式。

有趣的是,在 ECB 加密值上使用 CBC 将对前几个字节起作用,直到某个点(我想这与 block 大小有关),此时剩余的值被破坏.当在 VB 版本中加密一个长字符串并使用我在上面发布的代码以 EncryptionMode.ModeECB

模式对其进行解密时,您可以特别清楚地看到这一点

关于c# - Phil Fresle 将 VB6 AES Rijndael 分组密码转换为 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20801952/

相关文章:

python - Cryptography.Hazmat AES 密码输出长度

vba - 如何使用用户定义的类型?

go - 从 golang 应用程序发送字符串时出现意外的 StrComp 结果

c# - 是否可以从控制台应用程序发送 Toast 通知?

c# - Xml 反序列化和默认值

c# - ASP .NET 应用程序启动了多少次

html - 经典的 asp 密码验证 sql

c# - 当我选择身份验证选项时,Visual Studio 2013 没有创建数据库

c - 在c中制作一长串加密子字符串

python - 使用aes在python中加密文件