0

次のようなメッセージを暗号化/復号化します:文字列の暗号化->base64エンコードバイト->文字列のシリアル化->文字列の逆シリアル化->b64のデコード->バイトの復号化。

暗号化は次のようになります。

PublicKey pubKey = readPublicKey();
Cipher cipher;
cipher = Cipher.getInstance(CRYPTO_ALG);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData;
cipherData = cipher.doFinal(message.getBytes());
return cipherData;

復号化は次のように行われます。

PrivateKey pk = readPrivateKey();
Cipher cipher = Cipher.getInstance(CRYPTO_ALG);
cipher.init(Cipher.DECRYPT_MODE, pk);

return new String(cipher.doFinal(data));

キーは次のように読み取られます。

ObjectInputStream oin =
   new ObjectInputStream(new BufferedInputStream(is));
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();

RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privKey = fact.generatePrivate(keySpec);

return privKey;

ここではb64のものを省略しましたが、問題がそのコードに影響を与えないことを確認しました。

今起こっていることは、私が実際に正しい答えを得るということですが、それはバイナリのジブリッシュが前に付けられています。「TESTDATA」を暗号化すると、TESTDATAが取得されます。コードはプレーンJavaでは正常に機能しますが、Androidでは失敗します。誰かがこれを修正する方法を知っていますか?

編集:RSA / NONE/NoPaddingを使用した暗号化/復号化は役に立たないようです。また、プレーンJREではorg.bouncycastleを使用します。

4

1 に答える 1

1

私の経験では、デフォルトは、Java暗号の見つけにくいバグの途方もない終わりのない原因です。彼らは誰でも噛むことができますが、初心者を捕食します。初心者はデフォルトを選択する可能性が最も高いです。なぜなら、その性質上、混乱していて単純化しようとしているからです。そして、彼らはそこにいないので、見つけるのは難しく、実際にはほとんど見えません。あなたが見るとき、String.getBytes()それは完全に無実に見えます。new String(s.getBytes())なぜ初心者はこれまでと等しくないのではないかと疑うのでしょうsか?何よりも悪いことに、テストはそれが真実であることを示しているようです。バグに気付くのは、プラットフォームのデフォルトの文字セットが異なる別のプラットフォームに byte[]からを転送する場合のみです。s.getBytes()

使用しないでください。String.getBytes()常に使用してString.getBytes(Charset)ください。コンストラクターは使用しないでください。String(byte[])常にコンストラクターを使用してくださいString(byte [], Charset)。UTF-8文字セット()はいつでも使用できますCharset.forName("UTF-8")。私はそれを独占的に使用します。

同様に、ファクトリメソッドでは常に3つのコンポーネントすべてのアルゴリズム/モード/パディングを指定します。Cipher.getInstance(String)

于 2013-01-10T01:20:58.257 に答える