将二进制字符串(SecureRandom.random_bytes)转换为十六进制字符串?

时间:2016-10-16 09:37:25

标签: ruby encryption binary hex

对于我的AES-256 CBC generating我是Ruby encryption implementation一个32字节密钥和16字节iv:

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=='

问题:

如何将密钥和iv转换为十六进制字符串,以便将它们传输到其他应用程序?

上下文:

在另一个使用Javascript via CryptoJS的应用程序中,我需要接收密钥和iv并将它们转换回如下字节:

CryptoJS.AES.encrypt(
    "Hello!",
    CryptoJS.enc.Utf8.parse(key),
    { iv: CryptoJS.enc.Utf8.parse(iv) }
).toString()                                     // 'qAnTLy7jyiLRkUqBnME8sw=='

在第三个PHP应用程序中,我将直接使用Hex字符串:

<?php
openssl_encrypt(
  'Hello!', 'aes-256-cbc',
  key,
  0,
  iv
);                                               // => 'qAnTLy7jyiLRkUqBnME8sw=='

1 个答案:

答案 0 :(得分:2)

我认为这应该可以胜任:

key = SecureRandom.random_bytes(32)
key_as_str = key.each_byte.map{ |byte| '%02x' % byte }.join

我使用以下脚本验证了此解决方案:

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";

在我的机器上看起来一样。