【问题标题】:Rijndael: Same input / different output on multiple machinesRijndael:多台机器上的相同输入/不同输出
【发布时间】:2012-10-09 11:21:54
【问题描述】:

我编写的一些软件使用 .Net4.0 中的 Rijndael 算法来加密和解密许可证信息。

问题如下: 该程序生成一个字符串,该字符串被转换为一个字节[]。然后用 Rijndael 将这个 byte[] 加密为另一个 byte[],然后将其传输到其他计算机。 在那里,这个加密的 byte[] 再次被解密,得到的 byte[] 再次转换回字符串以从中检索信息。

基本上这工作得很好......但我猜不是那么完美。

我们办公室里有一台计算机似乎以不同的方式加密和解密。

如果我尝试在另一台计算机上解密 byte[],它会给我类似的东西:

{"Zeichenabstände sind ungültig und können nicht entfernt werden."}
 bei System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
 bei System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
 bei System.Security.Cryptography.CryptoStream.FlushFinalBlock()
 bei System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
 bei System.IO.Stream.Close()

进行加密的代码如下所示:

private byte[] EncryptBytes(byte[] originalBytes) {
    MemoryStream ms = new MemoryStream();
    Rijndael crypt = Rijndael.Create();
    crypt.Key = KeyBytes;
    crypt.IV = IVBytes;
    CryptoStream cs = new CryptoStream(ms, crypt.CreateEncryptor(), CryptoStreamMode.Write);
    cs.Write(originalBytes, 0, originalBytes.Length);
    cs.Close();
    Byte[] cryptedBytes = ms.ToArray();
    ms.Close();
    return cryptedBytes;
}

解密也是一样的,只是用 CreateDecryptor() 而不是 CreateEncryptor()。

为了测试和解决问题,我做了以下工作:

在两台计算机上,我加密了完全相同的字符串。 我检查了这个字符串在两台机器上都被转换成完全相同的字节[]。 Rijndael 对象在两台机器上具有相同的属性值,因此其配置方式相同(键、IV、填充等)

之后加密的 byte[] 输出在两台机器上完全不同。

这就是我卡住的地方。我想不出这种行为的原因,互联网也无法帮助我。两台计算机都运行带有 .Net4.0 的 Windows XP x86

我非常感谢任何提示,并提前感谢您, 毫升

有趣的事实:它在 12 台不同的计算机上运行良好,13 台机器在乱跑:)

【问题讨论】:

  • 您是否确保在所有机器上都设置了链接方法(例如密码块链接)。填充也很重要。
  • 感兴趣的是机器 13 在不同的架构上(32 位而不是 64 位,反之亦然)?所有字符串都会出现这种情况吗?您是否注意到任何带有琐碎字符串的内容(例如发送单个空字节)?
  • 验证密钥、IV 和密文的字节数组在所有机器上是否相同。在此过程中可能存在一些编码问题会破坏数据。
  • 与您的问题没有直接关系:您的 IV 使用可能是错误的。每次加密时都应该选择一个新的随机 IV。使用一个常量完全忽略了 IV 的意义。

标签: c# rijndael


【解决方案1】:

消息的意思

Padding is invalid and cannot be removed

我猜测被加密的实际数据是不同的。如果假定相同,则差异可能在于编码。我认为系统默认编码可能会有所不同,系统区域设置(System.Globalization.Culture 和 CurrentCulture)也会有所不同。

无论如何,在其中一种情况下,填充不正确。 Rijndael 输入需要填充到特定大小才能支持加密。您应该查看 Rijndael crypt 的文档。

很有可能,您可以使用一个标志自动对输入进行默认填充(解密时请注意这一点,因为您将获得源 + 填充,而不仅仅是来源)

【讨论】:

  • 所有机器上的填充都是 PKCS7。机器本身是带有 x86 操作系统的 x64 硬件。
  • 数据不能被破坏,我一直在将其写入文本文件以比较输入和输出。两台机器实际上加密完全相同的字节[]。我目前正在使用其他字符串进行测试以验证
  • 在这种情况下将“Padding”翻译为“Zeichenabstände”是很奇怪的。德国维基百科使用“Padding”和“Füllbytes”:de.wikipedia.org/wiki/Padding
  • @CodesInChaos 这不是我编的。我从谷歌(搜索)获得了翻译
  • 好吧,解决方法很简单。小字符串具有相同的行为。 IV 是从双精度值到字符串值生成的,以创建或多或少不可预测的 IV。 sehe 对文化环境的看法是完全正确的。当每台其他计算机使用类似德语的 , 作为十进制分隔符生成其 IV 时,我的同事在这里使用 .在他的系统上。我应该早点检查确切的密钥和 iv 字节。但是感谢所有有用的 cmets :)
猜你喜欢
  • 1970-01-01
  • 2020-12-28
  • 2015-11-05
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多