2012-06-15 56 views
11

我需要编写一个简单的工具来加密/解密文件。如何使用Ruby加密文件?

我想最好的办法就是使用OpenSSL:

生成密钥:

openssl rand -base64 2048 > secret_key 

加密文件:

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

解密文件:

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

有没有一种简单的方法来实施在Ruby中如此?有没有更好的方法来做到这一点?使用PGP也许?

+1

那么究竟是什么问题:使用OpenSSL,而无需调用一个外部程序? – 2012-06-15 03:50:59

+0

解密的命令应该是:'openssl aes-256-cbc -d -a -in file.enc -out file -k secret_key'否则你会得到一个'不好的魔法数字' – aelor

回答

17

Ruby的OpenSSL是周围的OpenSSL本身瘦包装,并提供几乎所有的OpenSSL本身并没有的功能,所以是的,有一个一对一的映射为所有的例子:

openssl rand -base64 2048 > secret_key 

这实际上是夸大了,您正在使用AES-256,因此您只需要一个256位密钥,但您在此处不使用RSA。 Ruby OpenSSL将这个决定放在你肩上,它会根据你想使用的算法自动确定正确的密钥大小。

您在加密过程中也犯了一个使用确定性IV的错误。为什么?因为你根本没有指定IV,OpenSSL本身将默认为所有零字节的IV。这不是一件好事,所以我会告诉你正确的做法,更多信息请看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 

正如你所看到的,加密和解密都非常相似,所以你也许可以结合流读取/写入到一个共享的方法,只是把它传递一个正确配置Cipher加上相应的文件名,我只是说为了清楚起见,他们明确表示。

如果您想为Base64编码的钥匙(也可能是四,太),你可以使用Base64模块:

base64_key = Base64.encode64(key) 
+1

我不知道这个答案是否需要更新或者不需要,如果是这样的话,添加一些会很好。 –

4

红宝石有一个OpenSSL library应该照顾繁重的工作。

+0

谢谢。我可能需要迁移到PGP,因为它支持文件的PKI(我有小文件),所以我可以轻松地支持多个用户,而无需存储密钥。 – Istvan

+0

@Istvan OpenSSL也支持PKI。 – emboss