2009-09-08 23 views
10

RSA秘密鍵で一部のコンテンツを暗号化しようとしています。JavaのRSA秘密鍵で暗号化

私はこの例を次のようだ: http://www.junkheap.net/content/public_key_encryption_java

が、それはむしろ、公開よりも、秘密鍵を使用するように変換します。その例に続いて、私は何をする必要があるかと思いますされています

  • 読むには、DER形式でキー
  • プライベートプライベートキーオブジェクト
  • を得るためにするKeyFactoryからPCKS8EncodedKeySpec
  • コールgeneratePrivateを()の生成します

    キーがあちこちに生成されました:

ので、手順は、暗号化を行うためにCipherオブジェクトとその秘密鍵オブジェクトを使用しますm個のopenssl:その後、

openssl genrsa -aes256 -out private.pem 2048

とはしてDER形式に変換した:

openssl rsa -in private.pem -outform DER -out private.der

私はあるPKCS8EncodedKeySpecを生成します。

byte[] encodedKey = new byte[(int)inputKeyFile.length()]; 

try { 
    new FileInputStream(inputKeyFile).read(encodedKey); 
} catch (FileNotFoundException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey); 
return privateKeySpec; 

そして、秘密鍵を生成しますオブジェクト:

PrivateKey pk = null; 

try { 
    KeyFactory kf = KeyFactory.getInstance(RSA_METHOD); 
    pk = kf.generatePrivate(privateKeySpec); 
} catch (NoSuchAlgorithmException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (InvalidKeySpecException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
return pk; 

しかし、への呼び出しに:

pk = kf.generatePrivate(privateKeySpec); 

私が取得:

java.security.spec.InvalidKeySpecException: Unknown key spec. 
at com.sun.net.ssl.internal.ssl.JS_KeyFactory.engineGeneratePrivate(DashoA12275) 
at com.sun.net.ssl.internal.ssl.JSA_RSAKeyFactory.engineGeneratePrivate(DashoA12275) 
at java.security.KeyFactory.generatePrivate(KeyFactory.java:237) 

質問:

  • は、右の一般的なアプローチですか?
  • PCKS8EncodedKeySpecは正しいキーペックを使用しますか?
  • 無効なキー仕様のエラーについて考えていますか?すべての
+0

は、私はこの1つを経て、Javaを使用して生成された:http://stackoverflow.com/questions/19640735/load-public-key-data-from -file – Hayro

答えて

6

まずあなたは、むしろSignatureと契約するよりも、秘密鍵で暗号化するためにCipherを使用することを計画している理由は、私は困惑しています。すべてのRSA Cipherプロバイダがセットアップに正しいブロックタイプを使用するかどうかはわかりませんが、試してみる価値はあります。

しかし、私は、標準以外のOpenSSL形式のキーを読み込もうとしていると思います。 rsaでDERに変換するのは基本的に基本64デコードです。キーの構造はPKCS#8ではありません。

代わりに、genrsa後、暗号化されていないPKCS#8に生成されたキーを変換するopenssl pkcs8コマンドを使用して、DER形式:

openssl pkcs8 -topk8 -nocrypt -in private.pem -outform der -out private.der 

これはPKCS8EncodedKeySpecをロードすることができ、暗号化されていない秘密鍵を生成します。

+0

正直、私はシグネチャを知らなかった。 私はその使い方を理解するために、署名オブジェクトを初期化し、署名したいバイトでupdateを呼び出してから、signを呼び出します。そして、署名から返されたバイトをデジタル署名として保存できますか? – wadesworld

+0

はい、正しい使い方です。 – erickson

+0

こんにちは。誰もが最終的に問題を解決した?私はprivateKeyを持っているので、私はフェーズに署名するのを続けるためにjavaにロードできません。私のprivateKeyはRSA、PKCS#8 DERであり、パスワードを持っています。どのように私はそれをjavaにロードできますか?私の場合の例外は 'java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:IOException:DER入力、整数タグエラー' – BRabbit27

10

秘密鍵で暗号化することはできません。 JCEがそうすることを許可すれば、それはちょうど間違いなくです。

署名を使用する必要があります。

signer = Signature.getInstance("SHA1withRSA"); 
signer.initSign(privateKey); // PKCS#8 is preferred 
signer.update(dataToSign); 
byte[] signature = signer.sign(); 
+1

's/public/private /'を最初の行に追加します。 – caf

+0

パーフェクト - ありがとう! – wadesworld

4

秘密鍵での暗号化が許可されている事故はありません。署名を個々のハッシュと暗号化に分割する場合は、秘密鍵で暗号化することが不可欠です。 私は署名が必要な文書を持っていて、私の鍵はネットワークHSMにあります。今すぐ署名するために文書全体をHSMにストリーミングするか、ローカルハッシュを作成してHSMにストリームして暗号化のみを行うことができます。 私の選択は、ローカルのハッシュ計算が、ネットワークレイテンシを伴う委任されたハッシュ計算よりも優れたパフォーマンスを提供するかどうかによって異なります。

2

この質問はかなり古くなっていますが、私は最近、問題に遭遇しました(秘密鍵で暗号化が必要なプロトコルの要件を実装しています)。秘密鍵を使用することができないという判決を下した(それらがある誰でも)、私は最近、同じ問題につまずい

「開発」と協議した後、PMR 22265,49R、およびIBMサポートに提出した:私はちょうどforumからの投稿を引用します暗号化のために。私は、秘密鍵を暗号化の背後にある唯一の目的であるデータ保護に使用すべきではなく、非拒否を達成するために秘密鍵を暗号化に使用することはまったく問題ではないと主張したとしても、彼らの信念であなたは2x2 = 5と主張する人々を愛さなければならない。

ここで私はこの問題を回避しました。基本的に私は秘密鍵の暗号資料を使って公開鍵オブジェクトを作成しました。 「公開鍵は復号化に使用できません」という例外を避けるには、逆を行い、公開鍵の暗号資料を使用して秘密鍵オブジェクトを作成し、公開鍵で復号化する必要があります。

RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) ks.getKey(keyAlias, ksPassword.trim().toCharArray()); 
RSAPublicKeySpec spec = new RSAPublicKeySpec(
    privateKey.getModulus(), 
    privateKey.getPrivateExponent() 
); 
Key fakePublicKey = KeyFactory.getInstance("RSA").generatePublic(spec); 
encryptCipher.init(Cipher.ENCRYPT_MODE, fakePublicKey); 
+1

秘密鍵指数を公開指数として扱い、配布すると非常に危険です。秘密鍵(これは「公開鍵」と呼ばれます)が与えられれば、実際の公開鍵「私有鍵」と呼ぶ)。間違って「公開鍵」を公開しないでください。そうしないと、システムが侵害されます。 「秘密鍵」の指数が65537であることを推測するのと同じくらい簡単かもしれません。 –

+0

私はこれほど長いこと探していました。私はこの答えにとても感謝しています。このユースケースでは、「プライベートと公開鍵」という名前は全く間違っていますが、これが関連する状況があります。 –

+0

@ JimFlood私が正しく理解し、私の状況が似ている場合、ドミトリーは秘密鍵データを保持するための 'RSAPublicKeySpec'を作成しました。明らかに、彼は秘密鍵を配布するつもりはない。秘密鍵が暗号化用であったことを証明するために使用できる元の公開鍵(つまり、否認不可)のみである。 – Guss

0

これを試してみてください。

java.security.Security.addProvider(
        new org.bouncycastle.jce.provider.BouncyCastleProvider() 
      ); 
関連する問題