これを短くするために、gzencode(または他の非テキストデータ)の結果をmcrypt_encrypt関数に渡すときに既知の問題がありますか?
詳細:
基本的に、プレーンテキストに対して暗号化/復号化が機能するという問題がありますが、圧縮データを暗号化関数に渡してから復号化して解凍すると、解凍中にエラーが発生します。
したがって、PHPでは、gzencode()の結果を暗号化関数に渡します。次に、WebサービスのWebページに結果を表示するためにbase64エンコードします。次に、Javaアプリで、GZIPInputStreamを使用してbase64をデコード、復号化、および解凍しています。最後のステップでエラーが発生します。
ただし、圧縮手順をスキップすると(プレーンテキストを暗号化関数に渡すだけで)、すべてが正常に機能します。暗号化をスキップして圧縮を行うだけでも、すべて正常に機能します。したがって、これらの関数を組み合わせない場合、これらの関数はPHP側とJava側の両方で正常に機能するようです。
public static function encrypt($str,$key,$iv) {
$str=Crypto2::pkcs5Pad($str,mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
$encrypted=mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$key,$str,MCRYPT_MODE_CBC,$iv);
return $encrypted;
}
public static function pkcs5Pad ($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
$padded=$text . str_repeat(chr($pad), $pad);
return $padded;
}
Java関数:
public static byte[] decrypt(byte[] inputbuffer) throws Exception {
Key key = new SecretKeySpec(keybyte, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, key, ivSpec);
c.getBlockSize();
System.out.println("Block size="+c.getBlockSize());
int outlen = c.getOutputSize(inputbuffer.length);
System.out.println("Output length will be:"+outlen);
byte[] result=c.doFinal(inputbuffer);
return result;
}
public static byte[] decodeBase64(String data) throws IOException{
BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(data);
return decodedBytes;
}
public static void unzipPrint(byte[] data) throws Exception{
InputStream is=new GZIPInputStream(new ByteArrayInputStream(data));
int ch2;
while((ch2=is.read())!=-1) {
System.out.print((char)ch2);
}
}
したがって、PHPでこれを行う場合:base64_encode(encrypt(gzencode($ plain_text)));
そしてこれはJavaで
unzipPrint(decrypt(decodeBase64(data)));
解凍フェーズ中に、「java.util.zip.ZipException:オーバーサブスクライブされた動的ビット長ツリー」という恐ろしいものが表示されます。
繰り返しますが、両端で圧縮/解凍の手順をスキップすると、すべて問題ありません。そして、両端で暗号化をスキップすると、圧縮/解凍は正常に機能します。
編集:奇妙なことに、圧縮されたデータの結果のバイト配列をバイトごとにチェックした後(base64のデコードと復号化の後)、値が1だけずれている(元のPHPバイト配列と比較して)SINGLEバイトが見つかりました。これはバイト番号14(Javaではインデックス13)で、値は111ではなく110でした。これがどのように当てはまるのかまったくわかりません。
したがって、その1バイトを110から111に変更すると、GZIPOutputStreamを使用してデータを正常に解凍できます。
だから私は何が悪いのかは知っていますが、理由はわかりません。
編集2:これは解決されました-> Owlsteadによるコメントのおかげで、私はIV値を再確認し、phpとjavaコードの間にわずかな不一致があることを発見しました。これがどのようにして結果の復号化されたデータにわずか1バイトの違いをもたらすことができるのか私にはわかりません。
それは私のIVの0x12の代わりに単一の0x13で1日無駄になりました。