我目前正在尝试将此c#代码转换为ruby,但我在使用正在使用的十六进制转换时遇到了困难
public static string Decrypt(string hexString, string key, string iv)
{
var bytes = Enumerable.Range(0, hexString.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
.ToArray();
//===== AES provider
var provider = new AesCryptoServiceProvider();
provider.Mode = CipherMode.CBC;
provider.Key = Encoding.UTF8.GetBytes(key);
provider.IV = Encoding.UTF8.GetBytes(iv);
var transform = provider.CreateDecryptor();
using (var ms = new MemoryStream(bytes))
{
using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
cs.Flush();
var plainText = sr.ReadToEnd();
return plainText;
}
}
以下是工作代码的小提琴:https://dotnetfiddle.net/JI8SID
使用这些输入:
var iv = "8E394493F1E54545";
var key = "36D65EA1F6A849AF9964E0BAA98096B3";
var encrypted = "0A1D18A104A568FDE4770E0B816870C6";
我应该得到:
"testing"
我的代码如下,但我不断获得key length too short (OpenSSL::Cipher::CipherError)
。我猜测我的hex_to_bin转换有什么问题,但它让我很难过。
require 'openssl'
def hex_to_bin(str)
str.scan(/../).map { |x| x.hex.chr }.join
end
def decrypt(data, hex_key, hex_iv)
decipher = OpenSSL::Cipher::AES256.new(:CBC)
decipher.decrypt
decipher.key = hex_to_bin(hex_key)
decipher.iv = hex_to_bin(hex_iv)
(decipher.update(hex_to_bin(data)) + decipher.final)
end
iv = "8E394493F1E54545"
key = "36D65EA1F6A849AF9964E0BAA98096B3"
encrypted = "0A1D18A104A568FDE4770E0B816870C6"
puts decrypt(encrypted, key, iv)
提前谢谢!
答案 0 :(得分:2)
使用指定长度完全相同的密钥长度,在给定AES256
的情况下,使密钥长度完全为32个字节。否则,实现可以从空填充中执行任何操作,垃圾字节超过键的末尾或抛出错误。
在代码中有一个32字节的十六进制密钥,然后通过调用将其转换为16字节的二进制密钥:hex_to_bin(hex_key)
。
以类似的方式,通过调用:hex_to_bin(hex_iv)
将16字节十六进制iv减少为8字节。
您确实需要提供更长的十六进制密钥。只是消除转换调用将导致128位密钥材料。
答案 1 :(得分:1)
你的直觉是正确的 - 问题是在key和iv上调用hex_to_bin。这是一个有效的解密例程,当插入到示例代码中时会发出字符串'testing':
def decrypt(data, hex_key, hex_iv)
decipher = OpenSSL::Cipher::AES256.new(:CBC)
decipher.decrypt
decipher.key = hex_key
decipher.iv = hex_iv
(decipher.update(hex_to_bin(data)) + decipher.final)
end