Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将C#加密例程转换为Ruby_C#_.net_Ruby_Encryption_Rijndaelmanaged - Fatal编程技术网

将C#加密例程转换为Ruby

将C#加密例程转换为Ruby,c#,.net,ruby,encryption,rijndaelmanaged,C#,.net,Ruby,Encryption,Rijndaelmanaged,我一直在尝试各种方法,但.Net代码似乎在解密之前将字符串和密钥转换为二进制,这让我大吃一惊。我反复阅读AES本质上是Rijndael,因此我一直在使用Ruby 1.9.3中内置的开放SSL库 RijndaelManaged crypto = new RijndaelManaged(); crypto.Padding = PaddingMode.PKCS7; crypto.Key = ASCIIEncoding.ASCII.GetBytes(secretKey); crypto.IV = ASC

我一直在尝试各种方法,但.Net代码似乎在解密之前将字符串和密钥转换为二进制,这让我大吃一惊。我反复阅读AES本质上是Rijndael,因此我一直在使用Ruby 1.9.3中内置的开放SSL库

RijndaelManaged crypto = new RijndaelManaged();
crypto.Padding = PaddingMode.PKCS7;
crypto.Key = ASCIIEncoding.ASCII.GetBytes(secretKey);
crypto.IV = ASCIIEncoding.ASCII.GetBytes(initializationVector);

byte[] byteArray = new byte[stringToDecrypt.Length / 2];
for (int i = 0; i < stringToDecrypt.Length / 2; i++)
{
  int index = (Convert.ToInt32(stringToDecrypt.Substring(i * 2, 2), 16));
  byteArray[i] = (byte)index;
}

MemoryStream memStream = new MemoryStream();
CryptoStream cryStream = new CryptoStream(memStream, crypto.CreateDecryptor(), CryptoStreamMode.Write);
cryStream.Write(byteArray, 0, byteArray.Length);
cryStream.FlushFinalBlock();

StringBuilder stringBuilder = new StringBuilder();

foreach (byte dByte in memStream.ToArray())
{
  stringBuilder.Append((char)dByte);
}

return stringBuilder.ToString();
RijndaelManaged crypto=new RijndaelManaged();
crypto.Padding=PaddingMode.PKCS7;
crypto.Key=ascienceoding.ASCII.GetBytes(secretKey);
crypto.IV=ascienceoding.ASCII.GetBytes(初始化向量);
byte[]byteArray=新字节[stringToDecrypt.Length/2];
对于(int i=0;i
下面是我当前的Ruby代码,它没有起到作用。它运行(除了最后一行),但会返回垃圾

我很确定问题出在MemoryStream/CryptoStream函数上,但我不知道从何处开始使用Ruby

text = Base64.encode64(cipher_text)
cypher = OpenSSL::Cipher::AES.new(256, :CBC)
cypher.decrypt
cypher.key = Base64.encode64("<cypher key>")
cypher.iv = Base64.encode64("<cypher iv>")
cypher.padding = 1
aes = cypher.update(cipher_text)
aes << cypher.final
text=Base64.encode64(密码文本)
cypher=OpenSSL::Cipher::AES.new(256,:CBC)
密码解密
cypher.key=Base64.encode64(“”)
cypher.iv=Base64.encode64(“”)
cypher.padding=1
aes=cypher.update(密码文本)

aes只要密钥、IV和密文相同,Ruby代码的输出与C#代码相同

在你的C#中试试这个:

在你的红宝石中:

cypher.key = "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
cypher.iv = "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
text = "\x7d\x7f\x06\x32\xd6\x43\x03\x64\x85\x64\xcc\x81\xae\xfa\x29\xf5"
你会发现它很好用

无论C#字节数组中有什么,您都需要Ruby字符串中的字节对字节,用于这些值。这就是问题所在——您没有使用相同的值

编辑:

这里有一个更好的例子。用C#试试这个:

在Ruby中:

cypher.key = "the quick brown fox jumps over t"
cypher.iv = "the quick brown "
text = [0xf8, 0x8b, 0xf1, 0x24, 0x65, 0x14, 0x0d, 0xe5, 0x25, 0xf1, 0xa4, 0x91, 0x45, 0x51, 0x73, 0x8e].map {|x| x.chr }.join
最后一行将密文转换为ASCII字符串“\xF8\x8B\xF1$e\x14\r\xE5%\xF1\xA4\x91EQs\x8E”。Ruby OpenSSL库希望密钥、iv和密文作为字符串。(我想您可以将编码称为8位ASCII。)


我给出的密文只是一个例子,它产生了纯文本“hello\n”。

我只是需要解决同样的基本问题,我想我应该为下一个出现的人添加一点对话内容

我遇到的最大困难是C#libraries在幕后到底在做什么,模棱两可。(在下面的选项列表中,正确的选项排在第一位并以粗体显示)

具体来说,
new AesManaged().CreateEncryptor()
使用的AES加密的“模式”是什么(CBC、CFB、OFB、CTR或ECB)

new SHA256Managed().ComputeHash()返回什么类型?(原始字节,十六进制编码,base64编码?)

此外,C#程序是否会自动向加密流添加最终填充?(是,否)

为了找到这些答案并与C#library的结果相匹配,我编写了Ruby代码来列举所有(30)种可能性并输出结果。也许有一天这会帮助某人

def self.encode(data, key, iv, opts={})
    # Setup our default strategies and apply overrides if specified
    aes_type = opts[:aes_type] || :CBC
    sha_method = opts[:sha_method] || :digest
    final_padded = (opts[:final_padded].nil?) ? true : opts[:final_padded]
    cipher = OpenSSL::Cipher::AES256.new(aes_type)
    cipher.encrypt
    cipher.key = Digest::SHA256.send(sha_method, key)
    cipher.iv = iv
    r = cipher.update(data) 
    (r << cipher.final) if final_padded
    Base64.encode64(r)
end

# Try all the different ways that AES-256 encryption might be interpreted
def self.encode_possibilities(data, key, iv)
    results = {}
    [:CBC, :CFB, :OFB, :CTR, :ECB].each do |type|
        [:digest, :base64digest, :hexdigest].each do |sha_type|
            [true, false].each do |final_padded|
                r = encode(data, key, iv, 
                                        aes_type: type, 
                                        sha_method: sha_type, 
                                        final_padded: final_padded)
                results["AES(#{type})-SHA-ENCODING(#{sha_type})-FINAL(#{final_padded})"] = r
            end
        end
    end
    puts "\n"
    results.each{|k,v| puts "#{k}  ==>  #{v}"}
    puts "\n"
end
def self.encode(数据、键、iv、选项={})
#设置默认策略并应用覆盖(如果指定)
aes_类型=选择[:aes_类型]| |:CBC
sha_方法=选择[:sha_方法]| |:摘要
最终填充=(选择[:最终填充].nil?)?正确:选项[:最终填充]
cipher=OpenSSL::cipher::AES256.new(aes_类型)
加密
cipher.key=Digest::SHA256.send(sha_方法,key)
4.iv=iv
r=密码更新(数据)

(r问题是什么?你只是在寻找这个的ruby版本吗?抱歉@Smith.h.Neil我添加了我当前的代码。我有一个操作函数,它会给我带来垃圾。我认为问题在于MemoryStream/CryptoStream。不确定从哪里开始将其翻译成ruby。字符串、密钥和iv以纯文本形式提供给我。如果它们被转换为字节数组(?),Ruby应该可以工作吗?不,你只是把它们当作字符串使用。在我的回答中,请参阅我上面的编辑。哦,好的。那么我如何将C#字节数组代码块复制到Ruby中呢?我想这是我最困惑的地方。搜索Ruby pack/unpack的信息,你会发现很多从字节到字符串再到字符串的例子。我从这里开始。
crypto.Key = ASCIIEncoding.ASCII.GetBytes("the quick brown fox jumps over t");
crypto.IV = ASCIIEncoding.ASCII.GetBytes("the quick brown ");
byteArray = new byte[] { 0xf8, 0x8b, 0xf1, 0x24, 0x65, 0x14, 0x0d, 0xe5, 0x25, 0xf1, 0xa4, 0x91, 0x45, 0x51, 0x73, 0x8e };
cypher.key = "the quick brown fox jumps over t"
cypher.iv = "the quick brown "
text = [0xf8, 0x8b, 0xf1, 0x24, 0x65, 0x14, 0x0d, 0xe5, 0x25, 0xf1, 0xa4, 0x91, 0x45, 0x51, 0x73, 0x8e].map {|x| x.chr }.join
def self.encode(data, key, iv, opts={})
    # Setup our default strategies and apply overrides if specified
    aes_type = opts[:aes_type] || :CBC
    sha_method = opts[:sha_method] || :digest
    final_padded = (opts[:final_padded].nil?) ? true : opts[:final_padded]
    cipher = OpenSSL::Cipher::AES256.new(aes_type)
    cipher.encrypt
    cipher.key = Digest::SHA256.send(sha_method, key)
    cipher.iv = iv
    r = cipher.update(data) 
    (r << cipher.final) if final_padded
    Base64.encode64(r)
end

# Try all the different ways that AES-256 encryption might be interpreted
def self.encode_possibilities(data, key, iv)
    results = {}
    [:CBC, :CFB, :OFB, :CTR, :ECB].each do |type|
        [:digest, :base64digest, :hexdigest].each do |sha_type|
            [true, false].each do |final_padded|
                r = encode(data, key, iv, 
                                        aes_type: type, 
                                        sha_method: sha_type, 
                                        final_padded: final_padded)
                results["AES(#{type})-SHA-ENCODING(#{sha_type})-FINAL(#{final_padded})"] = r
            end
        end
    end
    puts "\n"
    results.each{|k,v| puts "#{k}  ==>  #{v}"}
    puts "\n"
end