13

PHPとJAVAのblowfish暗号化スクリプトがあり、問題が発生した今日まで正常に機能していました。

同じコンテンツは、JavaとPHPで2文字しか暗号化されていないため、非常に奇妙です。

PHP

wTHzxfxLHdMm/JMFnoh0hciS/JADvFFg

Java

wTHzxfxLHdMm/JMFnoh0hciS/D8DvFFg
-------------------------^^

ご覧のとおり、これら2つの位置は一致していません。残念ながら、値は実際のメールアドレスであり、共有することはできません。また、テストした他のいくつかの値では問題を再現できませんでした。JavaでBase64エンコードクラスを変更しようとしましたが、どちらも役に立ちませんでした。

PHPのソースコードはここにあり、Javaのソースコードはここにあります。

この問題を解決するにはどうすればよいですか?

4

3 に答える 3

8

Javaコードを見てみましょう。

String c = new String(Test.encrypt((new String("thevalue")).getBytes(),
                                   (new String("mykey")).getBytes()));
...
System.out.println("Base64 encoded String:" +
                   new sun.misc.BASE64Encoder().encode(c.getBytes()));

ここで行っていることは次のとおりです。

  1. システムのデフォルトのエンコーディングを使用して、プレーンテキストの文字列をバイトに変換します
  2. システムのデフォルトのエンコーディングを使用して、キーをバイトに変換します
  3. バイトを暗号化する
  4. システムのデフォルトのエンコーディングを使用して、暗号化されたバイトを文字列に変換し直します
  5. システムのデフォルトのエンコーディングを使用して、暗号化された文字列をバイトに変換し直します
  6. Base64を使用してこれらの暗号化されたバイトをエンコードします。

問題はステップ4にあります。これは、任意のバイト配列がシステムのデフォルトエンコーディングの文字列を表し、この文字列を再度エンコードすると同じbyte[]が得られることを前提としています。これは、一部のエンコーディング(ISO-8859たとえば、シリーズ)には有効ですが、他のエンコーディングには有効ではありません。Javaでは、特定のエンコーディングで一部のバイト(またはバイトシーケンス)を表現できない場合、他の文字に置き換えられ、後で再変換するためにバイト63(ASCII ?)にマップされます。実際、ドキュメントには次のようにも書かれています。

指定されたバイトがデフォルトの文字セットで有効でない場合のこのコンストラクターの動作は指定されていません。

あなたの場合、これを行う理由はまったくありません。encryptメソッドが直接出力するバイトを使用して、Base64に変換するだけです。

byte[] encrypted = Test.encrypt("thevalue".getBytes(),
                                "mykey".getBytes());
System.out.println("Base64 encoded String:"+ new sun.misc.BASE64Encoder().encode(encrypted));

new String("...")(これはあなたの問題とは関係ありませんが、ここで余分なコンストラクター呼び出しを削除したことにも注意してください。)

覚えておくべきポイント:文字列のエンコードに由来しない任意のbyte[]を文字列に変換しないでください。暗号化アルゴリズム(および復号化を除く他のほとんどの暗号化アルゴリズム)の出力は、文字列に変換してはならないデータのカテゴリに確実に属します。

また、ポータブルプログラムが必要な場合は、システムのデフォルトのエンコーディングを使用しないでください。

于 2011-08-20T16:37:50.447 に答える
0

あなたのコードは私には正しいようです。

これらのプログラムの1つへの入力に末尾の空白があるように見えますが、これは1つだけです。理由をお話しします:

これらの4文字のブロックはそれぞれ、暗号化された文字列の3文字を表します。異なる部分(7番目のブロックのJAとD8)は、実際には1つの異なるキャラクターから来ています。

wTHz xfxL HdMm / JMF noh0 hciS / JAD vFFg

wTHz xfxL HdMm / JMF noh0 hciS / D8D vFFg

私が正しく理解していれば、あなたのメールアドレスは19文字です。入力文字列の1つの20番目の文字は空白です。

于 2011-07-21T03:10:28.303 に答える
0

質問:PHPで生成された暗号化テキストを復号化するために、関連するPHP復号化ライブラリを試しましたか?関連するJAVA復号化ライブラリを試し、JAVA暗号化テキストを復号化しましたか?

両方が異なる出力を生成する場合、一方は復号化に失敗しなければなりません(MUST)。

それはPHPですか、それともJavaですか?

どちらの場合でも、公に共有可能な文字列を使用して別のそのような失敗を複製しようとします...その文字列を単体テストとして提供します-ラウンドの言語で暗号化/復号化コードを作成した開発者にトリップ暗号化/復号化はで失敗します。

次に...彼らがそれを修正するのを待ちます。

より高速なソリューションがわからない-暗号化/復号化ライブラリプロバイダーを変更するか、独自のプロバイダーをロールすることを除いて...

于 2011-08-12T02:06:30.917 に答える