2012-06-28 6 views
8

私はAndroidアプリを開発中です。データ認証にはjava Signature classを使用する必要があります。RSA署名付きSHA256は、さまざまなAndroidデバイスで異なる出力を返します

各Android搭載端末で、データに署名してその署名を確認できます。しかし、署名するデータの明確な塊、明確なモジュラス、明確なプライベート指数および明確な公開指数を仮定すると、デバイスによっては、私の署名の出力が異なります。私はたくさんのデバイスを試してみましたが、Android 3.2と3.2.1では同じシグネチャを取得しましたが、Android 2.2.xデバイスとは異なるシグネチャを取得しました。

これまでに生成した定数フィールドの署名を、JavaプロジェクトのRSAでKeyFactoryを使用して計算します。キーサイズは2048ビットです。

ここでは、私がinvoque Signature and Verificationに使用するコードを引用しています。

public byte[] signData(byte[] data, PrivateKey privateKey) throws ... { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initSign(privateKey); 
     signature.update(data); 
     return signature.sign(); 
} 

public boolean verifyData(byte[] data, byte[] sigBytes, PublicKey publicKey) throws ... { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initVerify(publicKey); 
     signature.update(data); 
     return signature.verify(sigBytes); 
} 

私が誤解していない場合、RSAでSHA256を使用した署名は確定的です。それでは、どうやってそのような行動を説明できますか?もう1つ興味深い質問ですが、私はどのようにしてそのデバイスをクロスデバイスにすることができますか?つまり、署名は同じになります。

ありがとうございました、フランク!

+0

エラーハンドラを貼り付けることはほとんど必要ありませんでしたが、コードは正しいように見えます。署名する鍵とデータが同じであることを確認してください。 –

+0

@SevaAlekseyevはい、私は自分のシステムのすべての入力が同じであると確信しています。これらの定数を含むクラスでは、static finalとしてハードコーディングしました。私は便宜的に定数値をリンクしていませんでした。 – franckysnow

+0

ステップごとにデバッグします。まず、すべてのプラットフォームでSHA256ハッシュを計算し、それらを比較します。 –

答えて

11

はい、SHA256withRSAは完全に確定的です。

理論上、Androidバージョンの1つにある古い修正BouncyCastleライブラリバージョンのバグ(see an example)の影響を受ける可能性があります。代わりにSHA512withRSAを使用した場合、そのようなバグは排除されるかもしれません。少なくとも、参照されているものはそうです。

しかし、ハッシュアルゴリズムを掘り起こす前に、家に近づいてください。

String.getBytesを呼び出して、バイト配列を取得した可能性があります。この呼び出しは、Android 2.2とAndroid 2.3の間のdifferentであるデフォルトのプラットフォームエンコーディングに依存します。これは、両方の場合で文字列が同じであるにもかかわらず、バイト配列が一致しない可能性があることを意味します。

制御下エンコーディングを取得し、あなたのコードのプラットフォームに依存しないよう、パラメータとしてエンコーディングを指定するには、次の

plainText.getBytes("UTF-8") 

がこれを失敗すると、プラットフォームに依存しない実装を取得するには、いくつかのより多くの戦術があります。おそらくバギーライブラリと2.2まで

  • 待機が
  • は、お使いのソフトウェアで知られて良いのライブラリ(jarファイル)を配布して死にます。 BouncyCastleの場合は、Androidのクラスがロードされていないことを確認する際に問題が発生します。このソリューションはSpongyCastleと呼ばれています。
  • アライメント/パディングで再生します。独自の固定された埋め込みを追加することで、メッセージの長さをバイト数で0,55,56、または63の64に一致させるようにしてください。これらのオプションの1つがポータブル署名を開始することを願ってください。これらの値は、512ビットブロックにパディングされている疑わしいアルゴリズムの最も外側の部分と対話するように選択されます。
+0

答えJirkaありがとうございます。私は 'SHA256withRSA'を' SHA512withRSA'に変更しましたが、問題は修正されていません。私はまだ3.2.1と3.2のアンドロイドデバイスで同じシグネチャを持っていますが、エミュレータ(2.1)はまだ別のシグネチャを取得します。入力は 'String'ではなく、ハードコードされた' byte [] 'です。 万が一他のアイデアはありますか? – franckysnow

+0

エミュレートされた4.0.3デバイスで3.2.1と3.2と同じ出力が得られます。 – franckysnow

+1

@FranckStudiesCommEng - 次に検討する3つのルートで回答が拡大されました。 –

関連する問題