2010-11-18 3 views
3

暗号化についてよく分かりませんが、PHPでAESをやってもらえました。PHP AESの暗号化...私がやっていることは分かりません

function aes_decrypt($val,$ky) 
{ 
    $key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 
    for($a=0;$a<strlen($ky);$a++) 
     $key[$a%16]=chr(ord($key[$a%16])^ord($ky[$a])); 
    $mode = MCRYPT_MODE_ECB; 
    $enc = MCRYPT_RIJNDAEL_128; 
    $dec = @mcrypt_decrypt($enc, $key, $val, $mode, @mcrypt_create_iv(@mcrypt_get_iv_size($enc, $mode), MCRYPT_RAND)); 
    return rtrim($dec,((ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord(substr($dec,strlen($dec)-1,1))):null)); 
} 

function aes_encrypt($val,$ky) 
{ 
    $key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 
    for($a=0;$a<strlen($ky);$a++) 
     $key[$a%16]=chr(ord($key[$a%16])^ord($ky[$a])); 
    $mode=MCRYPT_MODE_ECB; 
    $enc=MCRYPT_RIJNDAEL_128; 
    $val=str_pad($val, (16*(floor(strlen($val)/16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16))); 
    return mcrypt_encrypt($enc, $key, $val, $mode, mcrypt_create_iv(mcrypt_get_iv_size($enc, $mode), MCRYPT_RAND)); 
} 

これらはわずかcomment on the PHP documentation page for mcryptから変更されています。ここで私が使用していますカップルの機能があります。 (私はdev_urandomが利用できないWindowsマシン上で午前と私は、ランドにdev_urandomから変更。)

とにかく、私は、この機能で使用するキーは、次のように定義されています

define("PSK", pack("H*", "abcd7b5ca46e12345678a8161fdacee9")); 

私は私の呼び出しこのような機能は:

echo bin2hex(aes_encrypt("wootwootwootwootwootwootwoo", PSK));

次に、得られた16進文字列の最初の16バイト(32桁)が微細です。次の16バイトは予想されるものと一致しません。

を参照してください。このデータを外部Webサービスに送信してから復号化しています。私は(残念なことに)私の暗号鍵とデータを渡さずに私が持っている1つのテストケースを与えることはできません。私はそれを大変申し訳なく思っていますが、mcryptに精通した人がこれを見て、私が間違っていることを教えてくれることを願っています。

もう一度申し訳ありませんが、固体テストケースの欠如については、私は非常にあなたが与えることができる任意の助けに感謝しています!

EDIT:私が投稿しているプロバイダは、null IVを使用しているようです。ルックのアドバイスに続いて、私はCBCモードに切り替え、キーに関連する不要なコードを削除しました。

function aes_decrypt($val,$key) 
{ 
    $mode = MCRYPT_MODE_CBC; 
    $enc = MCRYPT_RIJNDAEL_128; 
    $dec = @mcrypt_decrypt($enc, $key, $val, $mode, null); 
    return rtrim($dec,((ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord(substr($dec,strlen($dec)-1,1))):null)); 
} 

function aes_encrypt($val,$key) 
{ 
    $mode = MCRYPT_MODE_CBC; 
    $enc=MCRYPT_RIJNDAEL_128; 
    $val=str_pad($val, (16*(floor(strlen($val)/16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16))); 
    return mcrypt_encrypt($enc, $key, $val, $mode, null); 
} 

答えて

5

この暗号化サービスでは、CBCのような異なるブロック暗号モードが使用されている可能性があります。 null ivがCBCモードで使用されている場合、ECBとCBCの最初のブロック(この場合16バイト)は同じ暗号テキストを生成します。 ECBモードは、何らかの理由で誰にも使用されるべきではありません。

alt text

+0

あなたのコメントは参考になりましたが、間違いなく正しかったと思いますが、最後の編集に感謝します。 ECBとCBCの仕組みについていくつかの調査をした後、私はCBCに切り替えました。しかし、私は制御できない私のオンラインサービスで機能する出力を得るのに問題があります。私はnull IV(恐ろしい)と最初のブロック行を必要なものまで設定しましたが、2番目のブロックはまだ一致しません。私は今、他のモードを試していますが、あなたが私に与えるアドバイスが最も役立ちます。あなたの時間と反応に感謝します。 – Brad

+0

@Brad Your String2KeyFunction(forループXoR'ing nulls)は珍しいことです。彼らは別のstring2keyを使用している場合、おそらく問題を引き起こします。あなたが使用しているキーが16バイト未満の場合は、それは単なる平文のキーですが、これはデザインが悪いだけでなく一般的なものです。最初の投稿については申し訳ありませんが、それは心配していませんでした。 – rook

+0

@Rook、私は正しい長さのバイナリキーを渡していたので、とにかくビットは問題ではないことが分かります。私は奇妙な長さのキーを扱うためにしか存在しなかったと思う。私はそれを削除して、あらかじめ定義されたキーを使用しています。私は最初のブロックが一致するので、重要な部分が正しいと信じています。 2番目のブロックだけが実行しません。私は私の現在の機能を反映するために上記の投稿を編集します。 – Brad

1

Meおよび暗号化データを復号化するために、上記の方法を使用して、ここでiPhoneアプリをコーディングし、鉱山の大学:ここ

は、例えば、ECBモードで暗号化されたメッセージです。しかし、自分のiPhoneから読み取るデータを暗号化しているときに問題が発生しました。 iPhoneはPKCS7パディングを使用しました。上記のコードは余分なパディングを追加していたため、iPhoneの復号化方法が失敗することになりました。

public static function aes128Encrypt($key,$val) 
{ 
    $mode = MCRYPT_MODE_CBC; 
    $enc=MCRYPT_RIJNDAEL_128; 
    $blocksize= mcrypt_get_block_size($enc,$mode); 
    $stringLength = strlen($val); 
    $paddingLength =$blocksize-($stringLength%$blocksize); 
    $val=str_pad($val,$paddingLength+$stringLength,chr($paddingLength)); 
    return base64_encode(mcrypt_encrypt($enc, $key, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")); 
} 
関連する問題