将c#crypto代码转换为ruby

时间:2016-06-23 14:36:19

标签: c# ruby

我目前正在尝试将此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)

提前谢谢!

2 个答案:

答案 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