2011-08-16 23 views
2

BouncyCastleのSMIMEパッケージを使用して、ECDSA X509証明書を使用して暗号化メッセージを作成しようとしています。 BouncyCastleのリリースノートによれば、これは1.32(私は1.46を使用しています)からサポートされていますが、ECDSA OIDの暗号が見つからないという例外が続きます。EC X509証明書を使用して電子メールを暗号化する

org.bouncycastle.cms.CMSException:例外ラッピングコンテンツキー: は暗号を作成することはできません。ここで 1.2.840.10045.2.1

をサポートしているすべてのプロバイダは、テストの1からの抜粋です見つけることができません私は暗号化されたメッセージを作成するために使用しています

Version: V3 
    Subject: [email protected] 
    Signature Algorithm: SHA256withECDSA, OID = 1.2.840.10045.4.3.2 

    Key: EC Public Key 

コードを使用していた証明書は、次のようになります。

私は間違ったことをしていると確信していますが、今は見ていません。何か案は?

答えて

2

Thomas Pornin(上記)が示唆したように、ECDHを使用してこの作業を行う必要がありました。そのため、JceKeyTransRecipientInfoGeneratorを使用する代わりに、JceKeyAgreeRecipientInfoGeneratorを使用する必要がありました。

SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); 
JceKeyAgreeRecipientInfoGenerator rig = new JceKeyAgreeRecipientInfoGenerator(CMSAlgorithm.ECDH_SHA1KDF, senderPrivateKey, senderPublicKey, CMSAlgorithm.AES128_WRAP); 
rig.setProvider("BC"); 
gen.addRecipientInfoGenerator(rig); 

MimeBodyPart msg = new MimeBodyPart(); 
msg.setText("This is a secret message"); 

MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build()); 

Properties props = System.getProperties(); 
Session session = Session.getDefaultInstance(props, null); 

String to = "[email protected]"; 

Address fromUser = new InternetAddress("[email protected]"); 
Address toUser = new InternetAddress(to); 

MimeMessage body = new MimeMessage(session); 
body.setFrom(fromUser); 
body.setRecipient(Message.RecipientType.TO, toUser); 
body.setSubject("example encrypted message"); 
body.setContent(mp.getContent(), mp.getContentType()); 
body.saveChanges(); 

body.writeTo(new FileOutputStream("/tmp/encrypted.msg")); 
1

ECDSAは署名アルゴリズムであり、暗号化アルゴリズムや鍵交換アルゴリズムではありません。メッセージを暗号化するには、受信者のRSAキーまたはDiffie-Hellmanキー(おそらくECDH)が必要です。

+0

EC公開鍵はECDSAとECDHの両方に使用できますか?私は、SHA256withECDSAを署名アルゴリズムに使用しても、署名だけの鍵の使用を制限しないと仮定しました。それは間違っていますか? – senecaso

+1

ECDSAキーとECDHキーは同じ構造を共有します。ただし、通常は別個のライフサイクルとストレージポリシーが必要です(たとえば、致命的なデータ損失のシナリオを避けるために、通常は暗号化キーのバックアップやエスクローを維持したいと思っていますが、署名キーではやりたくはありません。秘密鍵の妥協の結果は、鍵の種類によってかなり異なる)。多くのX.509証明書は、暗号化に署名キーを使用することを禁じる意図された使用法(Key Usage拡張)を明示しています。 –

+0

はい、私は以前の[ECDSAとECDH]の説明(http://stackoverflow.com/questions/4969570/is-there-a-difference-between-ecdh-and-ecdsa-keys)に触れましたが、私は、証明書のキー使用を、使用が許可されているすべてのもの(別個の問題)にマークしている限り、考えました。この場合、BCで失敗しているコードの部分は、単に公開鍵のOIDを抽出し、それをCipher.getInstance()に渡すだけなので、何か他のことが起こっていると思います。 OIDはECの "キータイプ"用であるため、有効なCipherが見つかるとは思いません – senecaso

関連する問題