Phew! That was a LOT of new information all at once!
Thanks a lot for the crash course! :)
The restful_authentication analogy helped and I get what you mean by
thats one-way.
Now about your suggestion for generating a one-time key and storing it
in a global variable, not having decided on the hosting yet, I was
wondering if its still secure if both the database and the application
were on the SAME server. Or is it best to keep the IV/key on a
separate server?
Oh and yes, the Digest thing.. what you said helped me understand
better. :)
By the way, I tried your test code above on IRB and I dont get the
same encrypted string. Here're the results..

>> AESCrypt.encrypt("this","X" * 32,"I" * 32)
=> "\2...@\233?d\254u9]\241?m??"

>> AESCrypt.decrypt("\2...@\233?d\254u9]\241?m??","X" * 32,"I" * 32)
OpenSSL::CipherError: wrong final block length
        from /Users/fire/Sites/Vinay/ROR/RealApps/fi_rest_auth/config/
initializers/aes_crypt.rb:20:in `final'
        from /Users/fire/Sites/Vinay/ROR/RealApps/fi_rest_auth/config/
initializers/aes_crypt.rb:20:in `decrypt'
        from (irb):2

Im guessing the ? marks suggest something?
Thanks again for the guidance Michael. Appreciate it :).

On Feb 26, 4:59 pm, Michael Graff <[email protected]> wrote:
> (There is a bit of hand-waving in this reply, but it'll get you started.)
>
> AES-256-CBC means this:  AES algorithm. Block size 256-bits.
> Cipher-block-chaining.
>
> What this describes is a system where your data is encrypted in a
> 256-bit block, which GENERALLY means you need a 256-bit key.  The
> documentation for the Ruby OpenSSL system is, as near as I can tell,
> non-existent.  However, looking up the openssl library for C will tell
> you a lot -- Ruby just calls the C library your system has installed.
>
> In this case, AES-256-CBC requires a 256-bit key and IV.  (IV is
> "initialization vector" and is generally a random value.  Its purpose
> is to make the same plaintext encrypt to different cyphertext.)
>
> In my example, I generated 32-character long strings using the format:
>  "X" * 32.  This
> will make a string with 32-X's in it.  Probably not all that secure,
> but works for an example.   :)
>
> If you are running on a Unix system with /dev/random, and it has
> sufficient "real" randomness, you can use it to generate your IVs, and
> in your implementation, keys.
>
>   File.open("/dev/random") do |rnd|
>     key = rnd.read(32)
>     iv = rnd.read(32)
>   end
>
> If you are unable to use /dev/random, you could use /dev/urandom, but
> understand what the difference is.  /dev/random is probably strong
> (check with your system docs) and unless random data is available,
> will "block" -- not return until there is.  /dev/urandom is
> pseudo-random, and will return always.  However, it will use what
> little randomness exists and stretch it out.
>
> Note that your system is a lot like the method the
> restful_authentication plugin does.  restful_authentication uses a
> global, per-application "secret" that is used much like a key, and a
> per-user "salt" which is used as an IV.  Its only purpose is to make
> the password "mypassword" look different across users.  The main
> difference is that you can get the data back, while
> restful_authentication is a one-way thing -- you can't recover a
> password from what it stores.
>
> For your purposes, you can probably generate a one-time "secure"
> secret key, much like restful_authentication does, and store it in a
> global.  You would then generate per-item IVs of length 256-bits (32
> characters) and store those, along with the encrypted CC info.
>
> This is much more important to do if you have your application on one
> server and the database on another.  The database itself does not have
> all the bits needed to open the data.  Unfortunately, most people will
> break into your web server, not your database engine.
>
> As for what your digest thing does, it appears to "stretch" the
> passphrase out from an ASCII format to something much longer.  This is
> commonly referred to as "key crunching" and does not make a more
> secure key than just padding the value out by duplicating the
> passphrase until it is long enough.  That is, the digest thing is more
> or less the same as using the string:
> "whateverwhateverwhateverwhatever".  The difference is that you can
> look at the readable one and know it is a very bad key to use, while
> 9755571c6b7df2cdb1dddaaae2b399b7 almost looks random.  (It's not.)
>
> --Michael
>
> On Thu, Feb 26, 2009 at 5:37 AM, Ram <[email protected]> wrote:
>
> > Michael,
>
> > I do agree with you in that I really have little to no idea of
> > cryptography. Think I mentioned that in the OP itself. And I simply
> > left out the complex IV and key for the sake of making this post a
> > little more readable. Also, I have been reading up a bit and I hear
> > the same of what you say in that its safer to store the iv and key in
> > a database of their own. Thanks for that..
>
> > Well, the point though is that im getting an error that I dont have a
> > solution for. And I think im giving bad input to the encrypt and
> > decrypt methods and thats exactly what im trying to get someone to
> > bring me up to speed with. Even in your example, im guessing you're
> > generating a 32 bit something....? Well the real key and iv in my code
> > are generated like this
>
> > Digest::SHA1.hexdigest("whatever").unpack('a2'*32).map{|x| x.hex}.pack
> > ('c'*32)
>
> > Now I DID pick this up from the net so im not completely sure what
> > this does either.
>
> > I would appreciate it if you could establish the basics that I need to
> > know here.
> > Ive been trying to find relevant ROR specific documentation for the
> > OpenSSL gem but none that are understandable so far. Will look for
> > 'applied cryptography'.
> > Thanks for the response.
>
> > On Feb 26, 4:16 pm, Michael Graff <[email protected]> wrote:
> >> I'm going to seem rude probably, but it's still true.
>
> >> You are dabbling in crypto and you don't know what you're doing.
> >> Stop, and find someone who does.
>
> >> From what I read, you're trying to encrypt credit card data.  Before
> >> you leak all the data from your database by using the _current time_
> >> -- one of the weakest possible keys and IV values out there -- talk to
> >> someone, hire a consultant, or at least read 'applied cryptography.'
>
> >> >> AESCrypt.encrypt("this", "X" * 32, "I" * 32)
>
> >> => "\223\...@\233\323d\254u9]\241\351\031m\301\352">> 
> >> AESCrypt.decrypt("\223\...@\233\323d\254u9]\241\351\031m\301\352", "X" * 
> >> 32, "I" * 32)
>
> >> => "this"
>
> >> Your code works.  Your lack of understanding about the algorithm you
> >> are using, the meaning of a key in that context, how to securely
> >> generate one, and how important a secure IV is, has bitten you.
>
> >> Storing the key, IV, and encrypted data in a database is exactly the
> >> same as storing the unencrypted data.  It will stop casual browsing.
> >> If that is what you are trying to do, there are far easier methods,
> >> such as converting the whole thing into base64 or hex or something.
> >> If you believe your code actually adds security...
>
> >> --Michael
>
> >> On Thu, Feb 26, 2009 at 12:34 AM, Ram <[email protected]> wrote:
>
> >> > I just want to encrypt a string submitted through a form before saving
> >> > it to the DB. And then decrypt it again when I need to retrieve and
> >> > use it.
>
> >> > Im trying to use the OpenSSL::Cipher library. I have the following
> >> > module for encryption/decryption
> >> > [code]
> >> > require 'openssl'
>
> >> > module AESCrypt
> >> >  # Decrypts a block of data (encrypted_data) given an encryption key
> >> >  # and an initialization vector (iv).  Keys, iv's, and the data
> >> >  # returned are all binary strings.  Cipher_type should be
> >> >  # "AES-256-CBC", "AES-256-ECB", or any of the cipher types
> >> >  # supported by OpenSSL.  Pass nil for the iv if the encryption type
> >> >  # doesn't use iv's (like ECB).
> >> >  #:return: => String
> >> >  #:arg: encrypted_data => String
> >> >  #:arg: key => String
> >> >  #:arg: iv => String
> >> >  #:arg: cipher_type => String
> >> >  def AESCrypt.decrypt(encrypted_data, key, iv, cipher_type="aes-256-
> >> > cbc")
> >> >    aes = OpenSSL::Cipher::Cipher.new(cipher_type)
> >> >    aes.decrypt
> >> >    aes.key = key
> >> >    aes.iv = iv if iv != nil
> >> >    aes.update(encrypted_data) + aes.final
> >> >  end
>
> >> >  # Encrypts a block of data given an encryption key and an
> >> >  # initialization vector (iv).  Keys, iv's, and the data returned
> >> >  # are all binary strings.  Cipher_type should be "AES-256-CBC",
> >> >  # "AES-256-ECB", or any of the cipher types supported by OpenSSL.
> >> >  # Pass nil for the iv if the encryption type doesn't use iv's (like
> >> >  # ECB).
> >> >  #:return: => String
> >> >  #:arg: data => String
> >> >  #:arg: key => String
> >> >  #:arg: iv => String
> >> >  #:arg: cipher_type => String
> >> >  def AESCrypt.encrypt(data, key, iv, cipher_type="aes-256-cbc")
> >> >    aes = OpenSSL::Cipher::Cipher.new(cipher_type)
> >> >    aes.encrypt
> >> >    aes.key = key
> >> >    aes.iv = iv if iv != nil
> >> >    aes.update(data) + aes.final
> >> >  end
> >> > end
> >> > [/code]
> >> > And here is the model code where I encrypt and decrypt the string.
> >> > [code]
> >> >  def encrypt_cc_pass
> >> >    return if cc_pass.blank?
> >> >    self.cc_pass_key = Time.now.to_s
> >> >    self.cc_pass_iv = Date.today.to_s
> >> >    self.encrypted_cc_pass = AESCrypt.encrypt(cc_pass, cc_pass_key,
> >> > cc_pass_iv)
> >> >  end
>
> >> >  def decrypted_cc_pass
> >> >    AESCrypt.decrypt(encrypted_cc_pass, cc_pass_key, cc_pass_iv)
> >> >  end
> >> > [/code]
>
> >> > And this is the error I get
>
> >> > wrong final block length in:config/initializers/aes_crypt.rb:20:in
> >> > `final'
>
> >> > Anyone know what im doing wrong here?
> >> > Also, Im not able to understand the inners of encryption here. Is
> >> > there any gem with good documentation or simpler usage?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to