2012-04-26 19 views
4

Androidプロジェクトで解読の問題があります。公開鍵でのRSA解読

私は秘密鍵で署名された文字列を取得しており、公開鍵で検証(復号化)する必要があります。 私はPHPの機能を使用していたかのようにまったく同じ結果を取得したいのですが - 私は私のJavaプロジェクトでこれを行う必要がありopenssl_public_decrypt(http://php.net/manual/pl/function.openssl-public-decrypt.php

ので、私は、JavaのLIBS(例えばはBouncyCastle、または何かを使用することができます他の推奨事項はありますか?)

これを解決する方法はありますか?

これは私のコードです。 私はこの

PEMReader reader = new PEMReader(new InputStreamReader(ctx 
       .getAssets().open("pubkey.pem"))); 
     Object obj; 
     while ((obj = reader.readObject()) != null) { 
      if (obj instanceof RSAPublicKey) { 
       pubKey = (RSAPublicKey) obj; 
       return pubKey; 
      } 
     } 

のような公開鍵を取得していると私はいつも何の問題もなく公開鍵を取得します。私は、PHPの関数は sd8dsa348acvcx87|00454|OK|15000|CDEを返し、これは正しい出力である022c06571c6a263b389fcd93159cb311abb880bddf51b7c916dd1ae...

を取得

Cipher c = Cipher.getInstance("RSA/NONE/NoPadding", "SC"); 
c.init(Cipher.DECRYPT_MODE, pubKey); 
byte[] result = c.doFinal(data_to_decrypt.getBytes()); 

その結果(文字列にバイトを変換した後)。

+2

公開鍵暗号化では、秘密鍵を使って署名し、解読/解読します。 (署名)を検証し、公開鍵を使用して暗号化/暗号化します。あなたはどちらをしようとしていますか? – Bruno

+0

私は公開鍵でデータを解読しようとしているようです。 – Mike

+3

公開鍵でデータを復号化することはできません。(PHPの命名方法にもかかわらず)理解できません。 "*私は秘密鍵で暗号化された文字列を取得しています*":それは本当に意味をなさない。それは最高で署名されています。確かに、RSAでは、これは多かれ少なかれ同じ操作になります(ただし、DSAの場合はそうではありません)。問題は、メッセージの署名がほぼ確実にハッシュを含むため、元のメッセージを取得することは不可能です。 – Bruno

答えて

5

JavaにはJava暗号化拡張フレームワークが用意されています。これはこれらのために設計されたものです。

BouncyCastleは、このフレームワークの暗号化プロバイダです。つまり、暗号アルゴリズムの実装をJava Cryptography Extensionに提供します。

あなたは次のことを試みることができる公開鍵を使ってメッセージを復号化するには、パッケージにjava.securityjavax.crypto

を、このための基本的なクラスを見つけることができます:

// Use RSA/NONE/NoPadding as algorithm and BouncyCastle as crypto provider 
Cipher asymmetricCipher = Cipher.getInstance("RSA/NONE/NoPadding", "BC"); 

// asume, that publicKeyBytes contains a byte array representing 
// your public key 
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes); 

KeyFactory keyFactory; 
keyFactory = KeyFactory.getInstance(publicKeySpec.getFormat()); 
Key key = keyFactory.generatePublic(publicKeySpec); 

// initialize your cipher 
asymmetricCipher.init(Cipher.DECRYPT_MODE, key); 
// asuming, cipherText is a byte array containing your encrypted message 
byte[] plainText = asymmetricCipher.doFinal(cipherText); 

注意してください、この例でその非常にです。いくつかのtry catchブロックがありません。また、パディングなしで非対称暗号を使用しないでください。リプレイ攻撃に対して脆弱になります。キーの長さに問題が発生することもあります。一部のJavaパッケージでは、許容される最大キー長が制限されています。これは、無制限の強度ポリシーファイルを使用することで解決できます。

これは、Java暗号化を使い始めるのに役立ちます。

+0

あなたの答えをありがとう。私は前に似たような解決策を持っていましたが、それはうまくいきましたが、結果として次のようになりました:022c06571c6a263b389fcd93159cb311abb880bddf51b7c916dd1ae ... php関数は解読された文字列を返します。 – Mike

+0

このメソッドはバイト配列を返します。結果を文字列に変換しましたか? また、私はdoFinalメソッドの結果を変数に代入していないことを認識しています...答えを編集しようとしています... – Francis

+0

結果をStringに変換し、前のコメントの出力をStringに変換しますバイトの配列から – Mike

関連する問題