Reputation: 23
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
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