From: Felipe Coury Date: 2009-03-24T15:27:03+09:00 Subject: Re: Mimic AES_ENCRYPT and AES_DECRYPT functions in Ruby Some more discoveries... According to the blog post I sent before, here's how MySQL works with the key you provide AES_ENCRYPT / DECRYPT: "The algorithm just creates a 16 byte buffer set to all zero, then loops through all the characters of the string you provide and does an assignment with bitwise OR between the two values. If we iterate until we hit the end of the 16 byte buffer, we just start over from the beginning doing ^=. For strings shorter than 16 characters, we stop at the end of the string." I don't know if you can read C, but here's the mentioned snippet: http://pastie.org/425161 Specially this part: bzero((char*) rkey,AES_KEY_LENGTH/8); /* Set initial key */ for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++) { if (ptr == rkey_end) ptr= rkey; /* Just loop over tmp_key until we used all key */ *ptr^= (uint8) *sptr; } So I came up with this method: def mysql_key(key) # The algorithm just creates a 16 byte buffer set to all zero, final_key = "\0" * 16 # Number of string "blocks" t = key.length / 16 t.times do |i| # For each block key_block = key[i*16, 16] # Runs bitwise XOR for each char on string # and the same char on the block 16.times do |j| final_key[j] ^= key_block[j] end end final_key end But it still fails: >> key = "82pjd12398JKBSDIGUSisahdoahOUASDHsdapdjqwjeASIduAsdh078asdASD087asdADSsdjhA7809asdajhADSs" => "82pjd12398JKBSDIGUSisahdoahOUASDHsdapdjqwjeASIduAsdh078asdASD087asdADSsdjhA7809asdajhADSs" >> mkey = mysql_key(key) => "\027\024GK\023P{#8?G!8[r." >> mkey.length => 16 >> decrypt(mkey, User.find(1).password) User Load (11.3ms) SELECT * FROM `users` WHERE (`users`.`id` = 1) OpenSSL::CipherError: bad decrypt from (irb):4:in `final' from (irb):4:in `aes' from (irb):12:in `decrypt' from (irb):42 >> decrypt(mkey, [User.find(1).password].pack("H*")) User Load (2.8ms) SELECT * FROM `users` WHERE (`users`.`id` = 1) OpenSSL::CipherError: wrong final block length from (irb):4:in `final' from (irb):4:in `aes' from (irb):12:in `decrypt' from (irb):43 Question is: did I miss something :) ? I have a feeling I am *almost* there... Thanks again! -- Felipe -- Posted via http://www.ruby-forum.com/.