2010-06-05 106 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