我的情况:我正在用C#重写服务器,出于学习目的,该服务器是用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位=密钥大小
当我使用像byte [32]这样的IV并将其填充为0时,我得到一个错误。它说的像IV的东西不适合块大小。这就是为什么它现在有16个字节并填充为0。这可能是问题所在,如果是,我该如何解决?
除此之外,我不知道会出什么毛病。希望您能拯救我的一天,Stackoverflow。 :)
最佳答案
正如xanatos所说,我添加了5个零而不是21个,因为它们的密钥应该只有16个字节而不是32个字节。
现在可以正常工作了。谢谢大家!