How to decode Rijndael in ruby (encoded in VB.net)

匿名 (未验证) 提交于 2019-12-03 01:57:01

问题:

I am using Rinjael to encode in VB.NET and need to decode in Ruby. My VB.NET encryption class looks like this:

Private Class Encryptor         Private symmetricKey As System.Security.Cryptography.RijndaelManaged         Private iVector As Byte()         Private Key As Byte()         Public Function encrypt(ByVal data As String) As String             Try                 Dim plainTextBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(data)                 Dim encryptor As System.Security.Cryptography.ICryptoTransform = symmetricKey.CreateEncryptor(Key, iVector)                 Dim memoryStream As New System.IO.MemoryStream                 Dim cryptoStream As System.Security.Cryptography.CryptoStream = New System.Security.Cryptography.CryptoStream(memoryStream, encryptor, System.Security.Cryptography.CryptoStreamMode.Write)                 cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)                 cryptoStream.FlushFinalBlock()                 Dim cipherTextBytes As Byte() = memoryStream.ToArray()                 memoryStream.Close()                 cryptoStream.Close()                 Return Convert.ToBase64String(cipherTextBytes)             Catch                 Return ""             End Try         End Function         Public Function decrypt(ByVal data As String) As String             Try                 Dim crypted As Byte() = Convert.FromBase64String(data)                 Dim decryptor As System.Security.Cryptography.ICryptoTransform = symmetricKey.CreateDecryptor(Key, iVector)                 Dim memoryStream As New System.IO.MemoryStream(crypted)                 Dim cryptoStream As System.Security.Cryptography.CryptoStream = New System.Security.Cryptography.CryptoStream(memoryStream, decryptor, System.Security.Cryptography.CryptoStreamMode.Read)                 Dim plain(crypted.Length) As Byte                 Dim count As Integer = cryptoStream.Read(plain, 0, plain.Length)                 memoryStream.Close()                 cryptoStream.Close()                 Return System.Text.Encoding.UTF8.GetString(plain, 0, count)             Catch                 Return ""             End Try         End Function          Public Sub New(ByVal clientkey As String)             iVector = System.Text.Encoding.ASCII.GetBytes("1234567890123456")             Key = System.Text.Encoding.ASCII.GetBytes(clientkey)             symmetricKey = New System.Security.Cryptography.RijndaelManaged             symmetricKey.Mode = System.Security.Cryptography.CipherMode.CBC         End Sub     End Class 

this works ok and I am able to decrypt in java using the AES/CBC/PKCS5Padding. Now, my password and iv are 16 characters long (16*16bit = 256). When I try to decrypt in Ruby, it complains that my password is to short... I assume that it is using 8bit chars. I use this class for decryption in ruby:

    require 'openssl'  module Crypt   # Decrypts a block of data (encrypted_data) given an encryption key   # and an initialization vector (iv).  Keys, iv's, and the data    # returned are all binary strings.  Cipher_type should be   # "AES-256-CBC", "AES-256-ECB", or any of the cipher types   # supported by OpenSSL.  Pass nil for the iv if the encryption type   # doesn't use iv's (like ECB).   #:return: => String   #:arg: encrypted_data => String    #:arg: key => String   #:arg: iv => String   #:arg: cipher_type => String   def Crypt.decrypt(encrypted_data, key, iv, cipher_type)     aes = OpenSSL::Cipher::Cipher.new(cipher_type)     aes.decrypt     aes.key = key     aes.iv = iv if iv != nil     aes.update(encrypted_data) + aes.final     end    # Encrypts a block of data given an encryption key and an    # initialization vector (iv).  Keys, iv's, and the data returned    # are all binary strings.  Cipher_type should be "AES-256-CBC",   # "AES-256-ECB", or any of the cipher types supported by OpenSSL.     # Pass nil for the iv if the encryption type doesn't use iv's (like   # ECB).   #:return: => String   #:arg: data => String    #:arg: key => String   #:arg: iv => String   #:arg: cipher_type => String     def Crypt.encrypt(data, key, iv, cipher_type)     aes = OpenSSL::Cipher::Cipher.new(cipher_type)     aes.encrypt     aes.key = key     aes.iv = iv if iv != nil     aes.update(data) + aes.final         end end 

Now. By trying to decrypt using Crypt.decrypt(data,key,iv, "AES-CBC-256") i am certain that preliminary string/byte transformations have to be done on my data,key,iv to work correctly.

How shall I call Crypt.decrypt using key = "passwordpassword" and iv="1234567890123456"? Do I need to base64 decode my data?

Here's my decryption call, which doesn't seem to work (trying padding with zeroes):

   text = Base64.decode64(text)    pass = Digest::SHA1.hexdigest("#{@pass}0000000000000000").unpack('a2'*32).map{|x| x.hex}.pack('c'*32)    iv = Digest::SHA1.hexdigest("12345678901234560000000000000000").unpack('a2'*32).map{|x| x.hex}.pack('c'*32)    return Crypt.decrypt(text,pass,iv,"AES-256-CBC") 

回答1:

Solution. It was a 128bit encryption (wrongly thinking that the default in .NET managed was 256). Hence, this code works (notice "AES-128-CBC"):

   text = Base64.decode64(text)    pass = "passwordpassword"    iv = "1234567890123456"    return Crypt.decrypt(text,pass,iv,"AES-128-CBC") 


回答2:

Because the VB app encodes the result as base64, it does look like the ruby script will need to use the Base64 module to decode it first.

I believe the key given to the Ruby AES key must be 256 bits. So your password would need to be 32 bytes long exactly in that case. It would be better to use a scheme such as this.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!