Aes/Cbc Encrypt in Java, Decrypt in Ruby

Encrypt Ruby decrypt Java

The exact code that is produced by Ruby is not specified (which I would consider a bug), you can find the format by reading the source code, especially this part:

    blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
blob = "#{blob}--#{::Base64.strict_encode64 cipher.auth_tag}" if aead_mode?

Where the IV is a random IV, generated using Cipher::new of the openssl module.

Java equivalent of Ruby AES CBC Decryption

You're telling it to encrypt, not to decrypt. The corrected line of code is

cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));

Furthermore, if you want to use BouncyCastle for this, use

Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", BouncyCastleProvider.PROVIDER_NAME);

or make BouncyCastle the default:

Security.insertProviderAt(new BouncyCastleProvider(), 1);

Convert Encrypt code in java to Ruby

Encrypt Code:

def aes(key,string)
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
cipher.encrypt
cipher.padding = 1
cipher.key = hex_to_bin(Digest::SHA1.hexdigest('secret_key')[0..32])
cipher_text = cipher.update(string)
cipher_text << cipher.final
return bin_to_hex(cipher_text).upcase
end

Decrypt Code:

def aes_decrypt(key, encrypted)
encrypted = hex_to_bin(encrypted.downcase)
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
cipher.decrypt
cipher.padding = 1
cipher.key = hex_to_bin(Digest::SHA1.hexdigest('secret_key')[0..32])
d = cipher.update(encrypted)
d << cipher.final
end

hex_to_bin and bin_to_hex

def hex_to_bin(str)
[str].pack "H*"
end

def bin_to_hex(s)
s.unpack('C*').map{ |b| "%02X" % b }.join('')
end

In My case, The java code was using default initialization vector, So I did not set any iv, Also, there was hex_to_bin was a missing piece there. So after that, all started working properly.

I hope it helps someone if they come across this issue.

Ruby OPENSSL AES128 CBC decrypting with random iv not working

You're using a different, random IV on the decryption. This value must be identical. That is you capture it when encrypting:

iv = cipher.random_iv

Then you decrypt using that:

cipher.iv = iv

Then it decrypts properly. You need the same key + IV pair in order for the decryption to succeed.

Recode old AES 256 encryption from Java to Ruby

It was not that easy but here is my way to do it.

class ManualEncryption
class << self
attr_accessor :configuration

def config
@configuration ||= Configuration.new
end

def aes
return @aes if @aes
@aes = OpenSSL::Cipher.new(config.algo) # "AES-256-ECB"
@aes
end

def decodedKey
return @decodedKey if @decodedKey
@decodedKey = Base64.decode64(config.key_string) # "mySecretString"
end

def configure
yield(config)
raise 'Algo not specified' unless config.algo
raise 'key not specified' unless config.key_string
end

def encrypt(value)
raise 'No configuration done' unless config.algo && config.key_string
aes_perform('encrypt', value)
end

def decrypt(value)
raise 'No configuration done' unless config.algo && config.key_string
return value unless value
aes_perform('decrypt', value)
end

def aes_perform(status, value)
aes.reset
if status.eql?('encrypt')
aes.encrypt
aes.key = decodedKey
aes_val = aes.update(value) + aes.final
Base64::encode64(aes_val)
else
aes.decrypt
aes.key = decodedKey
decoded_value = Base64::decode64(value)
aes.update(decoded_value) + aes.final
end
end
end

class Configuration
attr_accessor :algo, :key_string
attr_reader :aes
end
end

Note: I still have a problem with the encryption. It creates \n inside my encrypted value and I don't know why. I'm working on it.



Related Topics



Leave a reply



Submit