2012-06-14 17 views
21

En una aplicación Rails 3.0 (Rubí 1.9.2) Estoy tratando de cifrar algunos datos utilizando algo como esto:Cómo cifrar datos en una cadena UTF-8 utilizando OpenSSL :: Cipher?

cipher = OpenSSL::Cipher.new 'aes-256-cbc' 
cipher.encrypt 
cipher.key = cipher.random_key 
cipher.iv = cipher.random_iv 

encrypted = cipher.update 'most secret data in the world' 
encrypted << cipher.final 

que entrará en una base de datos UTF-8. Mi problema es que

> encrypted.encoding 
=> #<Encoding:ASCII-8BIT> 

> encrypted.encode 'utf-8' 
Encoding::UndefinedConversionError: "\xF7" from ASCII-8BIT to UTF-8 

¿Cómo puedo obtener una cadena cifrada UTF-8?

Respuesta

39

la solución es para convertir la cadena ASCII-8BIT a Base64 y luego codificar a UTF-8.

cipher = OpenSSL::Cipher.new 'aes-256-cbc' 
cipher.encrypt 
cipher.key = cipher.random_key 
cipher.iv = cipher.random_iv 

encrypted = cipher.update 'most secret data in the world' 
encrypted << cipher.final 

encoded = Base64.encode64(encrypted).encode('utf-8') 

Una vez persistido y se recupera de la base de datos,

decoded = Base64.decode64 encoded.encode('ascii-8bit') 

y finalmente descifrarlo.


PD: Si tienes curiosidad:

cipher = OpenSSL::Cipher.new 'aes-256-cbc' 
cipher.decrypt 
cipher.key = random_key 
cipher.iv = random_iv 

decrypted = cipher.update encoded 
decrypted << cipher.final 

> decrypted 
=> 'most secret data in the world' 
+0

¡Gracias por esto! – Brandon

+0

'» codificada = Base64.encode64 ('Tromsø'). Codificar ('utf-8') => "VHJvbXPDuA == \ n" »Base64.decode64 (encoded.encode ('ascii-8bit')) => "Troms \ xC3 \ xB8" ' – mhenrixon

+0

¡Gracias, salvó mi día! – ti6on

0

Creo que su mejor opción es usar force_encoding encontrado here.

> encrypted.encoding 
    => #<Encoding:ASCII-8BIT> 

> encrypted.force_encoding "utf-8" 

> encrypted.encoding 
    => #<Encoding:UTF-8> 
+4

'.encode' de ASCII-8BIT a UTF-8 no funciona, por lo que' .force_encoding' sólo le permite generar una secuencia de bytes no válido. –