【发布时间】: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.OutputBlockSize 和 decryptor.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)
所以,我想,三个问题:
- C# 如何填充 56 位密钥以使其与至少需要 128 位密钥的算法一起使用?
- Rijndael 和 AES 之间的差异对于我尝试使用 Ruby 的 OpenSSL 库来完成这项任务是否是致命的?
- 一旦/如果我让密钥正常工作,我是否需要担心here 所述的字符编码?
谢谢。
【问题讨论】:
-
到 1:它可能用 0x00 (
'\0') 填充,直到密钥有 16 个字节。另外,请检查以下语句中的数学运算:“我知道输入和输出块大小为 256 位,因为 decryptor.OutputBlockSize 和 decryptor.InputBlockSize 都返回 16。” 它应该是 128 位。
标签: c# ruby encryption aes rijndaelmanaged