web-dev-qa-db-ja.com

RSA暗号化:JavaとAndroid

RSAを使用してAndroidのユーザー名とパスワードを暗号化し、サーバー(Tomcat 6、Java 1.6)で復号化します。 Android暗号化:

    PublicKey pubKey = readPublicKeyFromFile(mod, ex);
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, pubKey);
    byte[] cipherData = cipher.doFinal(data);
    return cipherData;

Java Tomcat復号:

    PrivateKey pubKey = readPrivateKeyFromFile(mod, ex);
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, pubKey);
    byte[] cipherData = cipher.doFinal(data);
    return cipherData;

Androidの外側でAndroidを使用する場合(メインの方法でのみ)正常に動作します。しかし、私のAndroid(エミュレーター)の中ではありません。サーバー側では、次のエラーが発生します。

javax.crypto.BadPaddingException: Blocktype mismatch: 0
    at Sun.security.rsa.RSAPadding.unpadV15(RSAPadding.Java:311)
    at Sun.security.rsa.RSAPadding.unpad(RSAPadding.Java:255)
    at com.Sun.crypto.provider.RSACipher.a(DashoA13*..)
    at com.Sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)

ModとexをBigIntegers定数として保持するため、ファイルに書き込まないようにします。 Java1.6とJava 1.5の暗号化には違いがあるので、どちらもJava 1.6でコンパイルされています。

デバッグ情報:

Androidのデバッグ中に、pubKeyにモジュラスと指数が16進数で含まれていることがわかります。そして、メインメソッドでデバッグした場合(これも同じコードです)、pubKeyに10進数の係数と指数が含まれていることがわかります。

何が悪いのですか?

ありがとう

26
bsobat

Android 2.2+でRSA暗号化を行い、Tomcat 6で復号化するJava 1.6サーバー。

私はこの正確な問題を抱えていて、あちこちを読んでいて、一部には@Femiの回答のおかげで、必要なものに出くわしました。

解決策は、暗号に次のアルゴリズム仕様を使用することでした。

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

これは、AndroidとBlackBerryスマートフォンの両方から暗号化を行います。質問が出されてから4か月が経過していることを知っていますが、誰かがこの問題を経験した場合に備えて。

42
blindstuff

特定の暗号の初期化を使用することをお勧めします。例として、

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");

両方で動作します。デフォルトの暗号初期化パディングがデスクトップJVMとAndroid JVMの間で異なるように見えるため、取得している例外(BadPaddingException)が発生しています。

11
Femi

まず、公開鍵で両方の暗号を初期化しているようです。暗号化は公開鍵を使用し、復号化は秘密鍵を使用します。私はそれが単なるタイプミスであることを願っています。

RSA暗号化にも多くの問題があり、多くは試行錯誤でした。別のプロバイダーを試すことをお勧めします。 BouncyCastleを使用してRSAを実装することができました。

Cipher wrapper = Cipher.getInstance("RSA", "BC");
wrapper.init(Cipher.ENCRYPT_MODE, publicKey);
encryptedData= wrapper.doFinal(unencryptedData);

ただし、これはセッションの暗号化であるため、独自のキーペアを生成しました。

kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        KeyPair kp = kpg.genKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();
1
Jeremy Jem Lee