如何在 ruby 中解码 Rijndael(在 VB.net 中编码)
我正在使用 Rinjael 在 VB.NET 中进行编码,并需要在 Ruby 中进行解码。我的 VB.NET 加密类如下所示:
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
这工作正常,我可以使用 AES/CBC/PKCS5Padding 在 java 中解密。现在,我的密码和 iv 都是 16 个字符长(16*16bit = 256)。当我尝试用 Ruby 解密时,它抱怨我的密码太短......我假设它使用 8 位字符。我在 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
现在。通过尝试使用 Crypt.decrypt(data,key,iv, "AES-CBC-256") 进行解密,我确信必须对我的 data,key,iv 进行初步字符串/字节转换才能正常工作。
我该如何使用 key = "passwordpassword" 和 iv="1234567890123456" 调用 Crypt.decrypt ? 我需要对数据进行 Base64 解码吗?
这是我的解密调用,它似乎不起作用(尝试用零填充):
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")
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")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案。它是 128 位加密(错误地认为 .NET 管理中的默认值是 256)。因此,此代码有效(注意“AES-128-CBC”):
Solution. It was a 128bit encryption (wrongly thinking that the default in .NET managed was 256). Hence, this code works (notice "AES-128-CBC"):
由于 VB 应用程序将结果编码为 Base64,因此 ruby 脚本看起来确实需要首先使用 Base64 模块对其进行解码。
我相信给予 Ruby AES 密钥的密钥必须是 256 位。因此,在这种情况下,您的密码长度需要为 32 个字节。最好使用诸如this之类的方案。
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.