2012-06-15 25 views
11

Necesito escribir una herramienta simple que encripta/descifra archivos.¿Cómo encriptar archivos con Ruby?

Creo que la mejor manera es usar OpenSSL:

generar una clave:

openssl rand -base64 2048 > secret_key 

cifrar un archivo:

openssl aes-256-cbc -a -e -in file -out file.enc -k secret_key 

descifrar un archivo:

openssl aes-256-cbc -d -in file.enc -out file -k secret_key 

¿Hay una manera fácil de implementar ¿Esto en Ruby? ¿Hay una mejor manera de hacer eso? ¿Usando PGP quizás?

+1

Entonces, ¿qué es exactamente la cuestión: el uso de OpenSSL sin la necesidad de llamar un programa externo? –

+0

el comando para descifrar debe ser: 'openssl aes-256-cbc -d -a -in file.enc -out file -k secret_key' o de lo contrario obtendrá un' mal número mágico' – aelor

Respuesta

17

OpenSSL de Ruby es una envoltura delgada alrededor de sí mismo OpenSSL y proporciona casi toda la funcionalidad que sí OpenSSL hace, así que sí, hay un mapeo uno a uno para todos sus ejemplos:

openssl rand -base64 2048 > secret_key 

que en realidad es exagerada , está utilizando AES-256, por lo que solo necesita una clave de 256 bits, no está utilizando RSA aquí. Ruby OpenSSL toma esta decisión de sus hombros, determinará automáticamente el tamaño de clave correcto dado el algoritmo que desea utilizar.

También está cometiendo el error de utilizar un determinista IV durante el cifrado. ¿Por qué? Debido a que no especifica un IV en absoluto, OpenSSL tendrá un IV de cero bytes por defecto. Eso no es algo bueno, así que le mostraré la forma correcta de hacerlo, para obtener más información, eche un vistazo al Cipher documentation.

require 'openssl' 

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

buf = "" 
File.open("file.enc", "wb") do |outf| 
    File.open("file", "rb") do |inf| 
    while inf.read(4096, buf) 
     outf << cipher.update(buf) 
    end 
    outf << cipher.final 
    end 
end 

# decryption 
cipher = OpenSSL::Cipher.new('aes-256-cbc') 
cipher.decrypt 
cipher.key = key 
cipher.iv = iv # key and iv are the ones from above 

buf = "" 
File.open("file.dec", "wb") do |outf| 
    File.open("file.enc", "rb") do |inf| 
    while inf.read(4096, buf) 
     outf << cipher.update(buf) 
    end 
    outf << cipher.final 
    end 
end 

Como se puede ver, el cifrado y descifrado son bastante similares, por lo que probablemente puede combinar la lectura de streaming/escritura en un método compartido y simplemente pasar un configurados correctamente Cipher además de los nombres de los archivos correspondientes, acabo de indicar explícitamente por el bien de la claridad.

Si desea Base 64 a codificar la clave (y probablemente el IV, también), puede utilizar el módulo Base64:

base64_key = Base64.encode64(key) 
+1

Me pregunto si esta respuesta necesita alguna actualización o no, de ser así sería tan agradable agregar alguna. –

4

Ruby tiene un OpenSSL library que debe encargarse del trabajo pesado.

+0

Gracias. Es posible que necesite pasar a PGP porque es compatible con PKI para los archivos (tengo archivos pequeños) para que pueda admitir fácilmente a varios usuarios sin tener problemas para almacenar la clave secreta. – Istvan

+0

@Istvan También hay soporte de PKI en OpenSSL. – emboss

Cuestiones relacionadas