Bölüm II: Ruby AES-256-CBC ve PHP MCRYPT_RIJNDAEL_128 birlikte iyi bir oyun yapmak için nasıl

2 Cevap php

Bu soru ile ilgili olarak, benim sonuncusu bir devamıdır How to make Ruby AES-256-CBC and PHP MCRYPT_RIJNDAEL_128 play well together. Ben şimdi bu çalışma var, ama ben yine de diğer yöne gitmek için mücadele ediyorum. PHP oluşturulan kriptogram sağlanan tüm bilgilere sahip gibi görünüyor, ama ben hata olmadan şifresini Ruby kodu alınamıyor.

İşte kriptogramını oluşturmak için kullanıyorum PHP kodu:

$cleartext = "Who's the clever boy?";
$key = base64_decode("6sEwMG/aKdBk5Fa2rR6vVw==\n");
$iv = base64_decode("vCkaypm5tPmtP3TF7aWrug==");
$cryptogram = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $cleartext, MCRYPT_MODE_CBC, $iv);
$result = base64_encode($cryptogram);
print "\n'$result'\n";

RESULT
'JM0OxMINPTnF1vwXdI3XdKI0KlVx210CvpJllFja+GM='

Öyleyse buraya Ruby şifresini çözmek için girişimde bulunuyor:

>> cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
>> cipher.key = Base64.decode64("6sEwMG/aKdBk5Fa2rR6vVw==\n")
>> cipher.iv = Base64.decode64("vCkaypm5tPmtP3TF7aWrug==")
>> cryptogram = Base64.decode64('JM0OxMINPTnF1vwXdI3XdKI0KlVx210CvpJllFja+GM=')
>> cleartext = cipher.update(cryptogram)
=> "Who's the clever"
>> cleartext << cipher.final
OpenSSL::Cipher::CipherError: bad decrypt
 from (irb):100:in `final'
 from (irb):100

Ne bu konuda gerçekten sinir bozucu o şifreli dize dışında tüm düz metin elde etmek mümkün olmasıdır. Yukarıdaki tekrarlanması, ancak Kriptogramın bir saçmalık pad ekleyerek:

  >> cleartext = cipher.update(cryptogram + 'pad')
  => "Who's the clever boy?\000\000\000\000\000\000\000\000\000\000\000"
  >> cleartext << cipher.final
  OpenSSL::Cipher::CipherError: bad decrypt
   from (irb):119:in `final'
   from (irb):119

Benim gerçek kullanım durumunda (sizden yana, JSON dize) cleartext yapılandırılmıştır, bu yüzden ben bu düzeni kullanmak anlatmak ve cipher.final yapmadan zayıf şifreli girişini tespit olabilecek bu noktada rahat hissediyorum. Ancak, benim kodunda kludge bu tür tahammül edemez, bu yüzden ben yakut kod incelikle son bloğu işlemek nasıl anlamak istiyorum.

2 Cevap

Sorun Ruby'nin OpenSSL bağlayıcı pkcs dolgusu olduğu varsayılan OpenSSL dolgu yöntemini kullanıyor ise mcrypt, son blok doldurma olmasıdır. Gerçekten OpenSSL belgelere açıklama geliştirmek olamaz:

PKCS padding works by adding n padding bytes of value n to make the total length of the data a multiple of the block size. Padding is always added so if the data is already a multiple of the block size n will equal the block size. For example if the block size is 8 and 11 bytes are to be encrypted then 5 padding bytes of value 5 will be added.

Elle şifreleyerek önce PHP düz yazı sonuna doğru doldurma eklemeniz gerekir. Bunu yapmak size (BlockSizeın 16 geçen) şifrelemeden önce PHP tarafında bu pkcs5_pad fonksiyonu ile $cleartext geçmek için.

function pkcs5_pad ($text, $blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad), $pad);
}

Ayrıca başka bir şekilde (Ruby şifrelemek ve mcrypt ile deşifre) giderseniz, şifresini çözdükten sonra dolgu bayt kapalı şerit gerekecek.

Eğer şifresini zaman biliyorum ki Side note: Eğer cleartext zaten blok boyutu (dolgu bütün bir blok) bir çoklu bile dolgu eklemek zorunda nedeni olduğunu son bloğunun son byte always dolgu miktarı ilave edilir. Aksi takdirde, tek bir dolgu bayt ve sadece değer sonunda oldu hiçbir doldurma bayt ile bir düz yazı ile düz yazı arasındaki farkı anlayamadı 0x01.

PHP \0 şifrelemeden önce düz metin yastıkları görünür. Sen doldurma devre dışı bırakmak için Ruby ayarlayabilirsiniz.

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/Cipher.html#method-i-padding-3D

Bu çalışır, ancak daha sonra el dolgu kapalı şerit olmalıdır.

1.9.3p125 :008 > cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
 => #<OpenSSL::Cipher::Cipher:0x0000000561ee78>
1.9.3p125 :009 > cipher.decrypt
 => #<OpenSSL::Cipher::Cipher:0x0000000561ee78>
1.9.3p125 :010 > cipher.padding = 0
 => 0
1.9.3p125 :011 > cipher.key = Base64.decode64("6sEwMG/aKdBk5Fa2rR6vVw==\n")
 => "\xEA\xC100o\xDA)\xD0d\xE4V\xB6\xAD\x1E\xAFW"
1.9.3p125 :012 > cipher.iv = Base64.decode64("vCkaypm5tPmtP3TF7aWrug==")
 => "\xBC)\x1A\xCA\x99\xB9\xB4\xF9\xAD?t\xC5\xED\xA5\xAB\xBA"
1.9.3p125 :013 > cryptogram =  Base64.decode64('JM0OxMINPTnF1vwXdI3XdI2j8NJ8kr+Du0fnkxorNl0=')
 => "$\xCD\x0E\xC4\xC2\r=9\xC5\xD6\xFC\x17t\x8D\xD7t\x8D\xA3\xF0\xD2|\x92\xBF\x83\xBBG\xE7\x93\x1A+6]"
1.9.3p125 :014 > cleartext = cipher.update(cryptogram)
 => "Who's the clever girl?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
1.9.3p125 :015 > cleartext << cipher.final
 => "Who's the clever girl?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"



1.9.3p125 :042 > cleartext.strip
 => "Who's the clever girl?"