Convert a binary string (SecureRandom.random_bytes) into a hexadecimal string?
I'm generating a 32 byte key and 16 byte iv for my AES-256 CBC Ruby encryption implementation:
key = SecureRandom.random_bytes(32) # => "m\xD4\x90\x85\xF9\xCD\x13\x98\xAB\v\xBB\xCD\x0E\x17\xFAA\xF9\x99\xAF\e\x8A\xB5\x8Ate\x93[m\x9As\xC7\xCB"
iv = SecureRandom.random_bytes(16) # => "\xDF\x95[\xD5\xDD(\x0F\xB8SE\xFCZr\xF1\xB1W"
ruby_cipher = SymmetricEncryption::Cipher.new(
key: key,
iv: iv,
cipher_name: 'aes-256-cbc'
)
ruby_cipher.encrypt("Hello!") # => 'qAnTLy7jyiLRkUqBnME8sw=='
Question:
How do I convert the key and iv to a hexadecimal string, so I can transport them to the other applications?
Context:
In another application, that uses Javascript via CryptoJS I need to receive the key and iv and convert them back to bytes like this:
CryptoJS.AES.encrypt(
"Hello!",
CryptoJS.enc.Utf8.parse(key),
{ iv: CryptoJS.enc.Utf8.parse(iv) }
).toString() // 'qAnTLy7jyiLRkUqBnME8sw=='
In a third PHP application I will use the Hex strings directly like this:
<?php
openssl_encrypt(
'Hello!', 'aes-256-cbc',
key,
0,
iv
); // => 'qAnTLy7jyiLRkUqBnME8sw=='
I think this should do the job:
key = SecureRandom.random_bytes(32)
key_as_str = key.each_byte.map{ |byte| '%02x' % byte }.join
I did verify this solution with the following scripts:
test.rb
require 'securerandom'
require 'symmetric-encryption'
key = SecureRandom.random_bytes(32)
iv = SecureRandom.random_bytes(16)
ruby_cipher = SymmetricEncryption::Cipher.new(
key: key,
iv: iv,
cipher_name: 'aes-256-cbc'
)
hex_key = key.each_byte.map{ |byte| '%02x' % byte }.join
hex_iv = iv.each_byte.map{ |byte| '%02x' % byte }.join
encoded = ruby_cipher.encrypt("Hello!")
puts "Ruby encoded: #{encoded}"
system("php test.php #{hex_key} #{hex_iv}")
test.php
<?php
$encoded = openssl_encrypt(
'Hello!', 'aes-256-cbc',
hex2bin($argv[1]),
0,
hex2bin($argv[2])
);
print "php encoded: $encoded\n";
looks the same on my machine.