2010-06-05 63 views
1

一個Ruby新手在這裏的一點 - 應該是一個簡單的問題: 我想用encrypted_strings寶石創建一個密碼加密的字符串: (從http://rdoc.info/projects/pluginaweek/encrypted_strings紅寶石 - encrypted_strings

的問題是:一切正常,但是我怎麼不需要密碼來解密字符串呢?假設我想將字符串存儲在某個地方一段時間,例如會話。密碼是否也與它一起存儲? (這看起來很奇怪?)。不,我不打算使用'祕鑰'或任何類似的黑客作爲密碼。

我打算使用uuid動態生成一個類變量@@密碼,我不會在內存中存儲它,並且可以從程序的一次運行切換到下一次。

對稱:

>> password = 'shhhh' 
=> "shhhh" 
>> crypted_password = password.encrypt(:symmetric, :password => 'secret_key') 
=> "qSg8vOo6QfU=\n" 
    >> crypted_password.class 
=> String 
>> crypted_password == 'shhhh' 
=> true 
>> password = crypted_password.decrypt 
=> "shhhh" 

回答

2

隨着對稱加密方案,您只需要進行加密和解密使用相同的密碼。而從外觀上來看,密碼存儲在加密的字符串的實例變量:

>> secret = '123' 
=> "123" 
>> crypted = secret.encrypt(:symmetric, :password => "password") 
=> "R5RVA511Nzw=\n" 
>> crypted.instance_variables 
=> ["@cipher"] 
>> crypted.instance_variable_get("@cipher") 
=> #<EncryptedStrings::SymmetricCipher:0x101192768 @password="password", @algorithm="DES-EDE3-CBC"> 

所以,是的,如果你存儲爲上述crypted對象,你會存儲密碼。目標是僅存儲crypted的字符串內容,而不包含其實例變量。我認爲crypted.to_sString(crypted)會做到這一點,但都沒有。作爲一種變通方法,您可以串插它,明確地把它傳遞給String#new,或者明確地刪除實例變量:

>> "#{crypted}".instance_variables 
=> [] 
>> String.new(crypted).instance_variables 
=> [] 
>> crypted.send :remove_instance_variable, :@cipher 
=> #<EncryptedStrings::SymmetricCipher:0x101192768 @password="password", @algorithm="DES-EDE3-CBC"> 
>> crypted.instance_variables 
=> [] 

一旦你只有字符串的內容,你可以在以後的密碼解密:

>> "R5RVA511Nzw=\n".decrypt(:symmetric, :password => "password") 
=> "123" 
+0

謝謝你。好。 但是 - 'crypted'是一個字符串,所以在它上調用to_s只會讓你回到同一個對象。 所以 - 子問題 - 我將如何獲得一個簡單的字符串與加密相同的內容? – 2010-06-05 15:23:27

+0

@Tom:在寫之前我應該​​測試一下。我已經更新了答案。 – 2010-06-05 15:31:10

1

好了 - 所以這裏是一個試圖回答我的問題:

  • 再次感謝馬克爲控制檯代碼。這使我這個:

您應該使用String.new()方法來創建從加密後一個外部存儲純字符串:

我覺得這是有點怪,有點危險的,即當一個字符串被加密時,默認行爲是將密碼包含在字符串中。

Loading development environment (Rails 2.3.8) 
>> secret = '123' 
=> "123" 
>> require 'encrypted_strings' 
=> [] 
>> crypted = secret.encrypt(:symmetric, :password => "password") 
=> "R5RVA511Nzw=\n" 
>> crypted.instance_variables 
=> ["@cipher"] 
>> crypted.instance_variable_get("@cipher") 
=> #<EncryptedStrings::SymmetricCipher:0x101c58b20 @algorithm="DES-EDE3-CBC", @password="password"> 
// note that this .to_s only passes back the crypted, since crypted _is_ a string. 
>> someString = crypted.to_s 
=> "R5RVA511Nzw=\n" 
>> someString.instance_variables 
=> ["@cipher"] 
>> crypted.instance_variable_get("@cipher") 
=> #<EncryptedStrings::SymmetricCipher:0x101c58b20 @algorithm="DES-EDE3-CBC", @password="password"> 
>> plainString = String.new(crypted) 
=> "R5RVA511Nzw=\n" 
>> plainString.instance_variables 
=> [] 
>> crypted.class 
=> String 
>> plainString.decrypt 
ArgumentError: Cipher cannot be inferred: must specify it as an argument 
    from /Library/Ruby/Gems/1.8/gems/encrypted_strings-0.3.3/lib/encrypted_strings/extensions/string.rb:98:in `decrypt' 
    from (irb):14 
>> plainString.decrypt(:symmetric, :password => "password") 
=> "123" 
+0

馬克更新了他的答案,因爲我正在打字。謝謝。 – 2010-06-05 15:33:38

+0

加密信息存儲在字符串中讓我切換到加密寶石。它不會將密碼等存儲在字符串中。 – 2010-06-05 16:56:14