Serhii
Serhii

Reputation: 23

Encrypt Ruby decrypt Java

Good afternoon. Interested in the question someone tried to decrypt data in Java that was encrypted in Ruby. I'm trying to encrypt a word in Ruby (using the Marshal module) and decrypt in Java. If the Marshal module is used, can it be transferred to other languages ​​or not?

This is my test in Ruby:

let(:key) { "12345678901234567890123456789012" }
let(:str) { "Serhii" }

it "encrypt_content" do
  crypt = ActiveSupport::MessageEncryptor.new(key, cipher: 'aes-256-cbc')
  encrypted_content = crypt.encrypt_and_sign(str)
  encrypted_content
end
    

The code methods are:

def encrypt_and_sign(value, expires_at: nil, expires_in: nil, purpose: nil)
  verifier.generate(_encrypt(value, expires_at: expires_at, expires_in: expires_in, purpose: purpose))
end

def _encrypt(value, **metadata_options)
  cipher = new_cipher
  cipher.encrypt
  cipher.key = @secret

  iv = cipher.random_iv
  cipher.auth_data = "" if aead_mode?

  encrypted_data = cipher.update(Messages::Metadata.wrap(@serializer.dump(value), metadata_options))
  encrypted_data << cipher.final

  blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"`enter code here`
  blob = "#{blob}--#{::Base64.strict_encode64 cipher.auth_tag}" if aead_mode?
  blob
end
    

The decrypt Java is:

private static final String key = "12345678901234567890123456789012";

@SneakyThrows
public static String decrypt(String encrypted) {
    byte[] firstByte = Base64.getDecoder().decode(encrypted.replaceAll("\n", "").getBytes(StandardCharsets.UTF_8));
    String first = new String(firstByte);
    String[] parts = first.split("--");
    byte[] secondByte = Base64.getDecoder().decode(parts[0].getBytes(StandardCharsets.UTF_8));
    String second = new String(secondByte);
    String[] parts2 = second.split("--");

    byte[] encryptedData = Base64.getDecoder().decode(parts2[0].getBytes(StandardCharsets.UTF_8));

    SecretKeySpec aesKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(new byte[16]));
    byte[] result = cipher.doFinal(encryptedData);

    return new String(result);
}

public static void main(String[] args) throws Exception {
    String encrypted = "S3l0cVEybDRUM2sxU1hFMk5YVlhOa3A2VXpRNFEyZFFibTVwZVdRMVdEUlpN\n" +
            "bkkxUzBaUGNsbFJaejB0TFRWWlVtVkNVWEJXZWxselJuWkVhbFJyWlU5VmNr\n" +
            "RTlQUT09LS0yZDA5M2FhZTg0OTJjZmIyZjdiNDA0ZWVkNGU2ZmQ4NDQ1ZTM4\n" +
            "ZjIx";
    System.out.println("Decrypted: " + decrypt(encrypted));
    }
}

Result �'��m�Qի��� What could be the reason?

Upvotes: 1

Views: 249

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 93978

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.

Upvotes: 1

Related Questions