【问题标题】:C# Rijndael key too short in RubyRuby 中的 C# Rijndael 键太短
【发布时间】:2017-02-22 17:11:53
【问题描述】:

我正在尝试在 Ruby 中重新实现 C# 代码。以下代码(具有不同的秘密)用于解密文件:

using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class Decrypt {
  private const string KEY = "FOOBARB";

  private static readonly byte[] IV = {
    126, 36, 216, 236, 247, 79, 205, 111, 240, 119, 197, 10, 19, 216, 139, 91
  };

  public static Stream ReadEncryptedFile(string filePath) {
    var fs = new FileStream(
      filePath,
      FileMode.OpenOrCreate,
      FileAccess.ReadWrite
    );

    byte[] key = new UnicodeEncoding().GetBytes(KEY);
    byte[] vector = IV;

    using (var rijndaelEncryption = new RijndaelManaged()) {
      var decryptor = rijndaelEncryption.CreateDecryptor(key, vector);
      return new CryptoStream(fs, decryptor, CryptoStreamMode.Read);
    }
  }

  public static void Main() {
    var crReader = ReadEncryptedFile(
      "/path/to/file"
    );
    StreamReader reader = new StreamReader(crReader);
    System.Console.WriteLine(reader.ReadToEnd());
  }
}

我知道CBC 是正确的密码模式,因为System.Console.WriteLine(rijndaelEncryption.Mode) 返回CBC。我知道输入和输出块大小是 256 位,因为 decryptor.OutputBlockSizedecryptor.InputBlockSize 都返回 16 32。(我意识到密钥大小也输入并确实将 AES 和 Rijndael 之间的区别定义为讨论了here——但我不确定它到底是如何工作的。)

无论如何,当我运行以下 Ruby 代码时,我会得到一个in 'key=': key length too short (OpenSSL::Cipher::CipherError)(我也尝试过 AES/CBC 的 128 位和 192 位版本,尽管在这里应该没什么区别):

require 'openssl'

f = File.read(
  'path/to/file'
)

key = 'FOOBARB'

iv = [126, 36, 216, 236, 247, 79, 205, 111, 240, 119, 197, 10, 19, 216, 139, 91]
     .pack('c*')

cipher = OpenSSL::Cipher.new('AES-256-CBC')

cipher.decrypt

cipher.key = key
cipher.iv = iv

puts cipher.update(f)

所以,我想,三个问题:

  1. C# 如何填充 56 位密钥以使其与至少需要 128 位密钥的算法一起使用?
  2. Rijndael 和 AES 之间的差异对于我尝试使用 Ruby 的 OpenSSL 库来完成这项任务是否是致命的?
  3. 一旦/如果我让密钥正常工作,我是否需要担心here 所述的字符编码?

谢谢。

【问题讨论】:

  • 到 1:它可能用 0x00 ('\0') 填充,直到密钥有 16 个字节。另外,请检查以下语句中的数学运算:“我知道输入和输出块大小为 256 位,因为 decryptor.OutputBlockSize 和 decryptor.InputBlockSize 都返回 16。” 它应该是 128 位。

标签: c# ruby encryption aes rijndaelmanaged


【解决方案1】:

如果您尝试将 AES 与 Rijndael 一起使用,您需要将块大小设置为 128 位(16 字节),这是 AES 唯一支持的块大小。许多 Rijndael 实现调用约定指定块大小,密钥大小由提供的密钥确定。

AES 密钥大小为 128、192 或 256 位,最好提供完全正确的大小,不要依赖于实现依赖的密钥填充。

【讨论】:

  • 澄清一点:C# 代码被另一方用于生成加密文件。目前尚不清楚我们是否可以改变这种情况。我知道上面清单中显示的 C# 代码可以解密它。我试图理解为什么我的 C# 代码可以工作——一个明显太短的密钥是如何解密加密文件的。
  • 你需要确定对方正在使用的块大小。使用 AES(块大小为 128 位的 Rijndael)确实是一个更好的主意,尤其是在互操作性方面。此外,还需要使用随机IV,通常作为加密数据的前缀,如果多次使用相同的密钥,固定IV可能会泄漏信息。
猜你喜欢
  • 1970-01-01
  • 2013-08-24
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 2023-03-23
相关资源
最近更新 更多