simple-java-mail
simple-java-mail copied to clipboard
Encrypt mail with multiple certificate
hello,
more a question for a new feature than an issue. Is it planned to implement encrypted mail for multiple recipients ?
Thanks !
My knowledge on this is limited, but I think it should already work with multiple recipients, if their keys were signed with a shared CA certificate. Or something like that.
Sorry for delay to answer. To encrypt mail for multiple recipients, you have to encrypt it with each recipient certificate (public key), then, they will be able to decrypt the mail on their side with their private key. I'll will try to work with you on this !
At one of the companies I worked, they configured a single (CA?) cert, which was used to sign (encrypt?) all emails without needing recipients individual public keys. Is your use case actually really a common one? Seems like a hassle!
I think my case is a common one.
Usually, a company has its own CA, they use it to sign internal certificates. Each employee then has a key pair (private and public key).
Let's say I want to send an encrypted mail to Alice and I want her to be the only one to be able to decrypt it. I encrypt it with her public key. The only person able to decrypt the sent mail is the one with the corresponding private key (=Alice).
Now, I want to send an encrypted mail to Alice and Bob (at the same time, = multiple recipients). If I encrypt it only with Alice public key, only Alice will be able to read it. Bob can't. That's why I need to encrypt it twice : one time with Alice's public key, one time with Bob's one.
Right now, if I want to do that with simple-java-mail, I have to send 2 distincts emails instead of one.
I don't know the company you're talking about but if you use only one certificate (you usually don't use a CA for that) to encrypt each email, that means, everybody share the private key and everybody can decrypt them.
The same if everybody use the same key to sign each email, you can't be sure of who really send it. Usually, you sign it with your private key.
But maybe that's what they intended to do...
By the way, in the lib, sign case is ok because you always sign a mail once (= with one private key).
By the way, in the lib, sign case is ok because you always sign a mail once (= with one private key).
Ahh then that might have been the case at the company I worked for at the time.
You made a convincing case, one question: this change would mean being able to sign on a per-email basis (so using EmailBuilder). Would it ever make sense to be able to do it on Mailer level as well, affecting all emails that don't have their own key added for signing/encrypting?
you mean to encrypt on a per-email basis ?
Not sure to understand your question: "do it on Mailer level... emails that don't have their own key added for signing/encrypting"
As encryption is for a specific recipient, I think certificates has to be done explicitely set in emailBuilder (no default value). For signing, it can be configured as default (as you can choose to sign all your email).
I think certificates has to be done explicitely set in emailBuilder (no default value)
So no use case whatsoever to allow a default. Ever. (just double checking)
Sign -> can set a default to sign email Encrypt -> no default value (as it is recipient dependant)
Yes, I am also having the same use case as @nathinthesky explained, encrypting message for each recipient. I just ported my code from Commons Apache to Simple Java Mail and come to know that it is not possible 😞
With Commons Apache we used to encrypt mail in following way :
- Fetch each recipient certificate (X509Certificate) from LDAP
- By using list of X509Certificate and
SMIMEEnvelopedGeneratorfromorg.bouncycastle.mail.smime,MimeBodyPartis encrypted
Here is the code for encrypting MimeMessage object
public MimeMessage encryptMessage(MimeMessage message, List<X509Certificate> recipientCertList)
{
try {
Security.addProvider(new BouncyCastleProvider());
// Create the generator for creating an smime/encrypted message
SMIMEEnvelopedGenerator generator = new SMIMEEnvelopedGenerator();
//Add Recipient Public Certificates.
for (X509Certificate cert : recipientCertList) {
generator.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert)
.setProvider(BouncyCastleProvider.PROVIDER_NAME));
}
MimeBodyPart msg = new MimeBodyPart();
msg.setContent(message.getContent(), message.getContentType());
MimeBodyPart mp = generator.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC)
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build());
message.setContent(mp.getContent(), mp.getContentType());
message.saveChanges();
return message;
} catch (Exception e) {
throw new EmailGenericException(e);
}
}
After this function just use Transport.send(); with returned message object. And if messages signing is also need to be done then that has to be done first then encryption. Moreover if DKIM signing should also be the last step. So the flow will always be S/MIME sign --> S/MIME encryption --> DKIM sign.
@bbottema Really looking forward to have this facility to encrypt message per recipient into this library. Also, if I get any rough idea where would the most of the changes will come then I can create PR for the same.
I had no idea that was even possible with LDAP. That's pretty cool actually. As I'm winding down on the open issues, I am looking into some of the older reports, such as this one, so I think I'm going to start work on this soon.
And if messages signing is also need to be done then that has to be done first then encryption. Moreover if DKIM signing should also be the last step. So the flow will always be S/MIME sign --> S/MIME encryption --> DKIM sign.
Correct, this is how Simple Java Mail already has implemented this.
What I'm going to do is to allow both default signing or encrypting on Mailer level as well as on Email level and then everyone can figure out there own use case and use the library as they see fit.
I also would like to send an encrypted email to multiple recipients that is also signed. Any idea if/when this might make it in?