шифрование электронной почты с использованием сертификата EC X509 - PullRequest
2 голосов
/ 16 августа 2011

Я пытаюсь использовать пакет SMIME BouncyCastle для создания зашифрованного сообщения с использованием сертификатов ECDSA X509. Согласно примечаниям к выпуску BouncyCastle, это поддерживается с 1.32 (я использую 1.46), но я продолжаю получать исключение, утверждающее, что для OID ECDSA не может быть найден шифр.

org.bouncycastle.cms.CMSException: исключение ключа содержимого ключа: невозможно создать шифр: не удается найти поставщика, поддерживающего 1.2.840.10045.2.1

Вот фрагмент из одного из тестовых сертификатов, которые я использую

  Version: V3
  Subject: EMAILADDRESS=bob@example.com
  Signature Algorithm: SHA256withECDSA, OID = 1.2.840.10045.4.3.2

  Key:  EC Public Key

Код, который я использую для создания зашифрованного сообщения, выглядит следующим образом:

// allow the use of the BC JCE
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
JceKeyTransRecipientInfoGenerator rig = new JceKeyTransRecipientInfoGenerator(cert);
gen.addRecipientInfoGenerator(rig);

MimeBodyPart msg = new MimeBodyPart();
msg.setText(message);

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

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

// TODO: This is incorrect.  Perhaps AKA is better?
String to = cert.getSubjectDN().getName();

Address fromUser = new InternetAddress(from);
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(filename));

Я уверен, что я делаю что-то явно не так, но сейчас я этого не вижу. Есть идеи?

Ответы [ 2 ]

2 голосов
/ 19 августа 2011

Как предложил Томас Порнин (выше), 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 = "bob@example.com";

Address fromUser = new InternetAddress("alice@example.com");
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 голос
/ 17 августа 2011

ECDSA - это алгоритм подписи, а не алгоритм шифрования или обмена ключами.Чтобы зашифровать сообщение, вам нужен ключ RSA или ключ Диффи-Хеллмана (возможно, ECDH) получателя.

...