私は現時点でActionScript 3を初めて使用し、処理のためにサーバーに送信する前に、as3cryptoライブラリを使用してblowfishアルゴリズムで一部のデータを暗号化しようとしています。https を使用できることはわかっていますが、ほとんどのブラウザーは引き続き送信データを表示するため、ユーザーは簡単にリクエストを偽装できます。そのため、ユーザーにページ要求を表示させたいのですが、復号化せずにデータを読み取ることはできません。
残念ながら、as3crypto ライブラリの decumentation は、コード内のコメント (あまり役に立ちません) を除けば、ほとんど存在しません。as3crypto フグ暗号化を「実装」するためにいくつかの静的関数を使用してフラッシュ側をセットアップしましたが、フラッシュ内でのみ暗号化/復号化に問題なく動作します。問題は、mcrypt ライブラリを使用して PHP でキーを使用して復号化しようとすると発生します。私が得た出力は元のコードではなく、なぜ役に立たないのかを理解するために数日を費やしました。
以下、コードと解説です。この例では、使用されるキーは「mykey」(引用符なし) で、エンコードされたデータは「Hello World」(引用符なし) です。
フラッシュ コード (as3crypto フグ ヘルパー):
package lib.ef.crypto
{
import com.hurlant.util.Base64;
import com.hurlant.crypto.Crypto;
import flash.utils.ByteArray;
import com.hurlant.crypto.symmetric.IPad;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.crypto.symmetric.NullPad;
public class Blowfish
{
/**
* Encrypts a string.
* @param text The text string to encrypt.
* @param key A cipher key to encrypt the text with.
*/
static public function encrypt($text:String, $key:String=""):String
{
var cryptKey:ByteArray = new ByteArray();
cryptKey.writeUTF( $key );
var iPad:IPad = new NullPad();
var crypt:ICipher = Crypto.getCipher('blowfish-cfb',cryptKey,iPad);
iPad.setBlockSize( crypt.getBlockSize() );
var cryptText:ByteArray = new ByteArray();
cryptText.writeUTF( $text );
crypt.encrypt( cryptText );
trace( Base64.encodeByteArray( cryptText ) );
return null;
}
static public function decrypt($text:String, $key:String=""):String
{
return new String();
}
}
}
その出力は実行ごとに異なりますが、この実行例の目的のために、得られる base64 でエンコードされた出力は「EkKo9htSJUnzBmxc0A==」です。
そのコードを PHP に取り込むと、復号化するために以下のメソッドに渡される前に base64 でデコードされます。
public static function decrypt($crypttext,$key)
{
if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
$plaintext = '';
$td = mcrypt_module_open('blowfish', '', 'cfb', '');
$blocksize = mcrypt_enc_get_block_size($td);
$iv = substr($crypttext, 0, $blocksize);
$crypttext = substr($crypttext, $blocksize);
if (true)
{
mcrypt_generic_init($td, $key, $iv);
$plaintext = mdecrypt_generic($td, $crypttext);
}
return $plaintext;
}
この時点で、出力は完全に読めなくなります。この問題は、blowfish の as3crypto 実装が正しくない (可能性は低い) か、使用するパディング (現在は null パディング) に関係している可能性があるか、最後に私が考えたことが原因であると思われます。エンコードされた文字列の先頭に追加されていない as3crypto でランダムに生成された初期化ベクトルと関係がありますか? as3crypto ライブラリは大規模で複雑であり、文書化されていないため、最後の 1 つを実際にテストすることはできませんでした。私はこの問題をグーグルで検索し、数日間すべてをテストしましたが、PHP で使用できないデータを見つけ続けています。Flash から PHP へのシステムを動作させることができるかどうかはわかっています。それをリバース エンジニアリングして、PHP から Flash への暗号化も実行することができます。
実際に夜の睡眠が犠牲になっているので、この件に関するすべての意見を歓迎します笑 よろしくお願いします:)
今日、さらにテストを行い、疑ったように初期化ベクトルであるかどうかを確認しようとしました。それが問題だとは思いません。エンコードされた出力を生成するために使用される IV の出力を取得できるように、フラッシュでいくつかのことを変更しました。
package lib.ef.crypto
{
import com.hurlant.util.Base64;
import com.hurlant.crypto.Crypto;
import flash.utils.ByteArray;
import com.hurlant.crypto.symmetric.IPad;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.crypto.symmetric.NullPad;
public class Blowfish
{
/**
* Encrypts a string.
* @param text The text string to encrypt.
* @param key A cipher key to encrypt the text with.
*/
static public function encrypt($text:String, $key:String=""):String
{
var cryptKey:ByteArray = new ByteArray();
cryptKey.writeUTF( $key );
var iPad:IPad = new NullPad();
var crypt = Crypto.getCipher('blowfish-cfb',cryptKey,iPad);
iPad.setBlockSize( crypt.getBlockSize() );
var cryptText:ByteArray = new ByteArray();
cryptText.writeUTF( $text );
crypt.encrypt( cryptText );
cryptText.position = 0;
var iv:ByteArray = crypt.IV;
iv.position = 0;
trace( Base64.encodeByteArray( iv ) );
trace( Base64.encodeByteArray( cryptText ) );
return null;
}
static public function decrypt($text:String, $key:String=""):String
{
return new String();
}
}
}
この例では、「1bcGpqIbWRc=」のエンコードされた IV と「XpgART3hNQO10vcgLA==」のエンコードされた暗号化データを取得しました。base64_decode() でそれらを ing した後、これらを修正した PHP 関数にプラグインしました。
public static function decrypt($crypttext,$key,$iv=NULL)
{
if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
$plaintext = '';
$td = mcrypt_module_open('blowfish', '', 'cfb', '');
if( $iv === NULL ){
$ivsize = mcrypt_enc_get_iv_size($td);
echo '<pre>'.$ivsize.'</pre>';
$iv = substr($crypttext, 0, $ivsize);
echo '<pre>'.strlen($iv).'</pre>';
$crypttext = substr($crypttext, $ivsize);
}
if ($iv)
{
mcrypt_generic_init($td, $key, $iv);
$plaintext = mdecrypt_generic($td, $crypttext);
}
return $plaintext;
}
この出力でさえ正しくありません。IV が Flash と PHP の両方で正しいサイズであることを確認するためにいくつかのテストを行いましたが、何らかの理由で PHP 側では Flash からのフグでエンコードされた出力を復号化できません。as3crypto で NULL と PKCS5 の両方のパディングを使用してみましたが、どちらも PHP のシステムでは機能しません。IV 文字列が Flash と PHP の両方で同じであることを確認するためにテストしました。どちらも同じキーを使用しています。どちらもCFBモードを使用しています。理解できません。同じアルゴリズム、同じキー、同じ IV、同じモードですが、互いに復号化できません。フグの as3crypto 実装が正しくないように思えます。誰でもこれを確認できますか?