Ruby - encrypted_strings

时间:2010-06-05 15:02:47

标签: ruby-on-rails security encryption

这里有一点Ruby新手 - 应该是一个简单的问题: 我想使用encrypted_strings gem来创建密码加密字符串: (来自http://rdoc.info/projects/pluginaweek/encrypted_strings

问题是:一切正常,但为什么我不需要密码来解密字符串?说我想将字符串存储在某处,就像会话一样。密码是否也随之存储? (这看起来很奇怪?)不,我不打算使用'秘密密钥'或任何类似的黑客作为密码。

我打算使用uuid动态生成一个类变量@@ password,我不会将其存储在内存中,并且可以从一个程序运行更改为下一个。

对称:

>> 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 个答案:

答案 0 :(得分: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"

答案 1 :(得分:1)

好的 - 所以这是试图回答我自己的问题:

  • 再次感谢Mark提供的控制台代码。这让我想到了这个:

你应该使用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"