菲尔Fresle转换VB6 AES的Rijndael分组密码到C# [英] Converting VB6 AES Rijndael Block Cipher to C# by Phil Fresle

查看:185
本文介绍了菲尔Fresle转换VB6 AES的Rijndael分组密码到C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我转换成一个传统的ASP应用到C#,并希望能够解密在C#中最初在传统的ASP加密的字符串。在传统的ASP code是这里,和C#code是< A HREF =htt​​p://www.frez.co.uk/csharp.aspx相对=nofollow>此处。我现在面临的问题是,在ASP VS C#中的加密和解密方法的签名是不同的。这里是我的ASP code解密,它包装解密code。

 功能AESDecrypt(sCypher)
 如果sCypher&LT;&GT; 然后    昏暗bytIn()
    昏暗bytOut
    昏暗bytPassword()
    昏暗lCount
    昏暗lLength
    昏暗的STEMP
    昏暗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(中间(spassword开头,lCount,1)))
    下一个    bytOut = DecryptData(bytIn,bytPassword)//',这是问题儿童    lLength = UBound函数(bytOut)+1
    STEMP =
    对于lCount = 0〜lLength - 1
        STEMP = STEMP&安培; CHR(bytOut(lCount))
    下一个    AESDecrypt = STEMP
 万一
结束功能

不过,在C#中我奋力这个函数转换,因为C#相当于DecryptData有更多的PARAMS

 公共静态的byte [] DecryptData(字节[]消息,字节[]密码,
            字节[] initialisationVector,BLOCKSIZE块大小,
            密钥大​​小密钥大小,EncryptionMode cryptMode)
        {...}

我可以使用什么值initialisationVector,块大小,密钥长度,cryptMode以便能够解密相同的方式传统的ASP code一样。


解决方案

使用菲尔Fresle的C#Rijndael算法的实现,你可以用下面的code已经成功解密与菲尔的ASP / VBScript版本加密的值。

您可以阅读我的​​答案这里加密:<一href=\"http://stackoverflow.com/questions/1679296/password-encryption-decryption-between-classic-asp-and-asp-net/14674957\">Password经典的ASP和ASP.NET

之间的加密/解密

 公共字符串DecryptData(字符串encryptedMessage,字符串密码)
    {
        如果(encryptedMessage.Length%2 == 1)
            抛出新的异常(二进制键不能有奇数个数字);        字节[] = byteArr新字节[encryptedMessage.Length / 2];
        对于(INT指数= 0;指数 - LT; byteArr.Length;指数++)
        {
            字符串=的byteValue encryptedMessage.Substring(索引* 2,2);
            byteArr [指数] = byte.Parse(的byteValue,NumberStyles.HexNumber,CultureInfo.InvariantCulture);
        }
        字节[]结果= Rijndael.DecryptData(
            byteArr,
            Encoding.ASCII.GetBytes(密码),
            新的字节[] {} //初始化向量
            Rijndael.BlockSize.Block256,//在大多数实现通常情况下128
            Rijndael.KeySize.Key256,
            Rijndael.EncryptionMode.ModeECB // Rijndael.EncryptionMode.ModeCBC
        );        返回ASCIIEncoding.ASCII.GetString(结果);
    }

大多数的默认实现将使用 128 192 256 位的密钥大小。位于 128 位块大小为标准。尽管一些实现允许块大小超过128位之外,改变块大小只会添加另一个项目到组合,以试图在一个实现获得加密数据到另一个正确解密时引起混乱。

更新

原来我错了这里一片;在 EncryptionMode 应设置为 EncryptionMode.ModeECB ,而不是 EncryptionMode.ModeCBC 。 ECB的安全性较低(<一个href=\"http://crypto.stackexchange.com/questions/225/should-i-use-ecb-or-cbc-encryption-mode-for-my-block-cipher\">http://crypto.stackexchange.com/questions/225/should-i-use-ecb-or-cbc-encryption-mode-for-my-block-cipher)因为它没有像周期不CBC,但这是它是如何在加密的VB版实现的。

有趣的是,使用上的ECB加密值CBC将为字节上的第一少数工作,直到某一点(ⅰ想像这具有与块尺寸做),在该点的值的余数是错位。加密在VB版长上下的字符串,并与code我和 EncryptionMode.ModeECB <的模式上面贴解密它的时候你可以特别清楚地看到这/ p>

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 (http://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

这篇关于菲尔Fresle转换VB6 AES的Rijndael分组密码到C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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