Rijndael:C ++加密,C#解密

时间:2016-02-17 07:55:55

标签: c# c++ encryption cryptography rijndael

我的情况:我正在用C ++重写一个用于学习目的的服务器。在某些时候,客户端将密码发送到加密的服务器。他们使用Rijndael加密密码。 您可以在此处找到原始加密类:

Rijndael.h:https://github.com/astorks/FlyFF/blob/master/Source/_Common/Rijndael.h

Rijndael.cpp:https://github.com/astorks/FlyFF/blob/master/Source/_Common/Rijndael.cpp#L926

正如您在.cpp文件中看到的那样,他们使用此密钥和IV:

char const* CRijndael::sm_chain0 = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

char    szDefaultKey[32] = "dldhsvmflvm";

以下是他们实际解密原始服务器中密码的部分(https://github.com/astorks/FlyFF/blob/master/Source/CERTIFIER/DPCertifier.cpp#L256

// MAX_PASSWORD is actually 42. So 16*42 = 672 byte
char szEnc[ 16 * MAX_PASSWORD ] = {0, };
char szDec[ 16 * MAX_PASSWORD ] = {0, };

ar.Read( szEnc, 16 * MAX_PASSWORD );

g_xRijndael->ResetChain();
g_xRijndael->Decrypt( szEnc, szDec, 16 * MAX_PASSWORD, CRijndael::CBC );

现在我正处于我从客户端正确获取数据包以及我需要解密密码的位置。我当前的C#代码没有正确解密数据,我无法弄清楚原因。这是我的代码:

public static class Rijndael
    {
        private static ICryptoTransform decryptor { get; set; }
        private static RijndaelManaged rijndael { get; set; }

        public static void Init()
        {
            byte[] decryptKey = Encoding.ASCII.GetBytes("dldhsvmflvm").Concat(Enumerable.Repeat((byte)0, 21).ToArray()).ToArray();
            byte[] decryptIV = Enumerable.Repeat((byte)0, 16).ToArray();
            // I've tried BlockSize 128 and 256. It actually should be 128 since it's 16 on the original server (16 * 8 = 128)
            rijndael = new RijndaelManaged() { Padding = PaddingMode.Zeros, Mode = CipherMode.CBC, KeySize = 256, BlockSize = 128, Key = decryptKey, IV = decryptIV };
            decryptor = rijndael.CreateDecryptor(decryptKey, decryptIV);
        }


        public static string decrypt(byte[] data)
        {
            string password = null;
            using (MemoryStream ms = new MemoryStream(data))
                using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    using (StreamReader sr = new StreamReader(cs))
                        password = sr.ReadToEnd();
            return password;
        }
    }

他们在服务器端挑选了32个字节,但只填充了11个字符:dldhsvmflvm。这就是为什么我用0填充其他21个字节。 32 * 8 = 256位= KeySize

当我使用类似IV的字节[32]并用0填充时,我得到一个错误。它表示像IV一样的smth不适合块大小。这就是为什么它现在有16个字节,并填充0.这可能是问题,如果是这样,我怎么能解决它?

除此之外,我不知道会出现什么问题。希望你能节省我的一天,Stackoverflow。 :)

1 个答案:

答案 0 :(得分:1)

正如xanatos所说,我已经添加了5个零而不是21个,因为它们的密钥应该只有16个字节而不是32个字节。 它现在没有问题。谢谢大家!