10

Ruby スタックから PHP スタックに送信するデータを生成しています。Ruby 側では OpenSSL::Cipher ライブラリを使用し、PHP では 'mcrypt' ライブラリを使用しています。Ruby で 'aes-256-cbc' (256 ビット ブロック サイズ) を使用して暗号化する場合、PHP で MCRYPT_RIJNDAEL_128 (128 ビット ブロック サイズ) を使用して復号化する必要があります。cipher.iv_len が 16 であるため、Ruby コードが壊れていると思われます。私はそれが32であるべきだと信じています:

>> cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
=> #<OpenSSL::Cipher::Cipher:0x3067c5c>
>> cipher.key_len
=> 16
>> cipher.iv_len
=> 16
>> cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
=> #<OpenSSL::Cipher::Cipher:0x306de18>
>> cipher.key_len
=> 32
>> cipher.iv_len
=> 16

これが私のテストです。Ruby 側では、まずキーと iv を生成します。

>> cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
>> cipher.encrypt
>> iv = cipher.random_iv
>> iv64 = [iv].pack("m").strip
=> "vCkaypm5tPmtP3TF7aWrug=="
>> key = cipher.random_key
>> key64 = [key].pack("m").strip
=> "RIvFgoi9xZaHS/0Bp0J9WDRyND6Z7jrd3btiAfcQ8Y0="

次に、これらのキーを使用して暗号化を行います。

>> plain_data = "Hi, Don, this is a string."
>> cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
>> cipher.encrypt
>> cipher.key = Base64.decode64(key64)
>> cipher.iv = Base64.decode64(iv64)
>> encrypted_data = cipher.update(plain_data)
>> encrypted_data << cipher.final
>> crypt64 = [encrypted_data].pack("m").strip
=> "5gfC/kJcnAV2fJI0haxnLcdraIKWgtu54UoznVxf8K0="

PHPの復号化は次のとおりです。

$ruby_crypt = "5gfC/kJcnAV2fJI0haxnLcdraIKWgtu54UoznVxf8K0=";
$encrypted_data = base64_decode($ruby_crypt);
$key = base64_decode("RIvFgoi9xZaHS/0Bp0J9WDRyND6Z7jrd3btiAfcQ8Y0=");
$iv = base64_decode("vCkaypm5tPmtP3TF7aWrug==");
$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_data, MCRYPT_MODE_CBC, $iv);
$unencrypt = rtrim($result, "\x00..\x1F");
print "\nUnencrypted token:\n'$unencrypt'\n";

RESULT:
Unencrypted token:
'Hi, Don, this is a string.'

より長いブロックサイズを使用したいと思います。明らかに、私は API を誤解しています。ヘルプ?

4

4 に答える 4

13

上記の議論の説明を他の誰かが見つけるかもしれない例を書きました:

$猫出版社.rb

#!/usr/bin/env ruby

require 'openssl'
require 'base64'

key = '7fc4d85e2e4193b842bb0541de51a497'

cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
cipher.encrypt()
iv = cipher.random_iv

cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
cipher.encrypt()
cipher.key = key
cipher.iv = iv
crypt = cipher.update('This is my text')
crypt << cipher.final()

puts [Base64.encode64(crypt).strip(), Base64.encode64(iv).strip()].join('|')

$ 猫の消費者.php

$key256 = '7fc4d85e2e4193b842bb0541de51a497';

$fd = fopen("php://stdin", "r");
$tokens = '';
while (!feof($fd))
  $tokens .= fread($fd, 1024);
fclose($fd);

$tokens = explode('|', trim($tokens));
$crypt = $tokens[0];
$iv = $tokens[1];

$crypttext = base64_decode($crypt);
$iv = base64_decode($iv);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key256, $crypttext, MCRYPT_MODE_CBC, $iv);

print $decrypted ."\n";

テストするには、コマンドラインから次を試してください。

$ Rubypublisher.rb | php コンシューマー.php

これは私のテキストです

于 2010-12-06T10:46:20.480 に答える
7

PHP はわかりませんが、サイドバーの関連する質問を読んでみると、Converting Ruby AES256 decrypt function to PHP が表示されます。これには、このページへの参照が含まれており、128 inMCRYPT_RIJNDAEL_128はキー サイズではなく、暗号化のブロック サイズを指していることを指摘しています。Ruby と PHP の間で渡されたキーのサイズは、どちらの場合も 256 ビットであることがわかります。言い換えれば、これは予期された動作のようであり、より大きなキーを既に使用しています。

#!/usr/bin/ruby
require 'base64'

puts((Base64.decode64("RIvFgoi9xZaHS/0Bp0J9WDRyND6Z7jrd3btiAfcQ8Y0=").length * 8).to_s)

HTH

于 2009-12-07T21:17:56.487 に答える
0

PHP が 8 文字未満のパスワードを使用していたため、問題が発生しました。この場合、PHP と互換性を持たせるために、0 を追加する必要があります。

mcrypt-encrypt マニュアルページ "キー

データの暗号化に使用するキー。必要なキーサイズよりも小さい場合は、'\0' でパディングされます。キーに ASCII 文字列を使用しないことをお勧めします。 http://php.net/manual/en/function.mcrypt-encrypt.php mhash 関数を使用して、文字列からキーを作成することをお勧めします。"

require 'openssl'
cipher = OpenSSL::Cipher.new('DES-ECB')
cipher.encrypt
key =  'passwrd'[0...7].ljust(8, 0.chr)  #Pad the key smaller than 8 chars
cipher.key = key
encrypted = cipher.update('33')
encrypted << cipher.final
dec = Base64.encode64(encrypted).strip()
于 2013-09-05T15:24:25.650 に答える