【问题标题】:Why does RijndaelManaged 256 bit is giving me "specified key is not a valid size for this algorithm" error?为什么 RijndaelManaged 256 位给我“指定的密钥不是该算法的有效大小”错误?
【发布时间】:2014-10-19 02:47:07
【问题描述】:

我无法使 C# RijndaelManaged 加密与 PHP mcrypt_encrypt 一起使用,因为我不断收到“指定的密钥不是此算法的有效大小”。

PHP 规范使用 256 位,采用 ECB 密码模式。我的理解是在 ECB 模式下不使用初始化向量。

我们正在使用临时密钥来让这个在开发项目中工作,以继续构建开发应用程序,我们将在很久以后发布一个新的安全密钥。

[PHP]
$plaintext = '1~ABCDEFG~1408740350~0~';

for($i = 1; $i <= 32; $i++) { $key .= chr($i); }

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plaintext, 'ecb', '');


[C#]
string postFormData = "1~ABCDEFG~1408740350~0~";
StringBuilder sb = new StringBuilder();
foreach (var b in Encoding.ASCII.GetBytes(String.Concat(Enumerable.Range(1, 32)))) { sb.AppendFormat("{0}", b); }
postedFormData = RijndaelAES.Encrypt(postedFormData, sb.ToString());

public static string Encrypt(string plainText, string key)
{
    string cipherText;
    var rijndael = new RijndaelManaged()
    {
        Key = Encoding.UTF8.GetBytes(key),
        Mode = CipherMode.ECB,
        BlockSize = 256, //128,
        Padding = PaddingMode.Zeros//, 
        //IV = new byte[] { 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 }
    };
    ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, null);

    using (var memoryStream = new MemoryStream())
    {
        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
        {
            using (var streamWriter = new StreamWriter(cryptoStream))
            {
                streamWriter.Write(plainText);
                streamWriter.Flush();
            }
            cipherText = Convert.ToBase64String(memoryStream.ToArray());
        }
    }
    return cipherText;
}

【问题讨论】:

  • for($i = 1; $i &lt;= 32; $i++) { $key .= chr($i); }foreach (var b in Encoding.ASCII.GetBytes(String.Concat(Enumerable.Range(1, 32)))) 不同。如果不是在你的 PHP 中使用这种循环方法,你可以硬编码一个固定的、非计算的键,你可以复制和粘贴?
  • 我对此有一个先前的答案。签出:stackoverflow.com/questions/11873878/…我标记了帮助我到达那里的答案,但完整的解决方案低于此。
  • @Juventus18 我注意到它使用的是 CBC 密码模式,而不是 ECB 密码模式。
  • @fletchsod 是的,这就是 PHP 函数的作用,但这不是 String.Concat(Enumerable.Range(1, 32)) 的作用。这将为您提供“123 ...”,您需要“\0x1\0x2\0x3...”。您的 C# 代码中根本不需要字符串,只需创建 byte[32] key; 并执行 for(int i = 0; i &lt; 32; i++) { key[i] = i + 1; }

标签: c# rijndael rijndaelmanaged


【解决方案1】:

Rijndael/AES 的块大小固定为 128(在所有实现中)。您可能打算设置键大小,而不是块大小。

此外,将密钥转换为字节的方式非常不寻常(实际上这很神奇)。我认为您并不真正了解编码。这是一个重要的研究课题。可能,那个 PHP 版本假设字符串是 ASCII。在 C# 中,您可以这样做:

string keyStr = ...;
Debug.Assert(keyStr.Length == (256 / 8));

byte[] keyBytesASCII = Encoding.ASCII.GetBytes(keyStr);
Debug.Assert(keyBytesASCII.Length == (256 / 8));
Debug.Assert(keyBytesASCII.Length == keyStr.Length);

将来您可以通过使用调试器查看重要值来调试此类问题。我想你会发现你设置的密钥不是预期的长度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-22
    • 2011-02-24
    • 2020-09-25
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多