2012-06-15 90 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