I tried using bouncy castle but it says digital signature isn't valid/ can't be verified at receiver end.
I don't want to encrypt the email, only add digital signature.
Please see below code snippet where I'm passing MimeMessage and returning signed MimeMessage, which is then send using Java mail sender
MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mailcap.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
mailcap.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
mailcap.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
mailcap.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
CommandMap.setDefaultCommandMap(mailcap);
Security.addProvider(new BouncyCastleProvider());
KeyStore ks = KeyStore.getInstance("PKCS12");
File file = ResourceUtils.getFile(certificatePath);
ks.load(new FileInputStream(file), certificatePassword.toCharArray());
Enumeration<String> es = ks.aliases();
String alias = "";
boolean isAlias = false;
while (es.hasMoreElements()) {
alias = es.nextElement();
if (isAlias = ks.isKeyEntry(alias)) {
break;
}
}
if (isAlias) {
KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(certificatePassword.toCharArray()));
PrivateKey myPrivateKey = pkEntry.getPrivateKey();
Certificate[] chain = ks.getCertificateChain(alias);
chain[0].verify(chain[1].getPublicKey());
SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
capabilities.addCapability(SMIMECapability.dES_CBC);
capabilities.addCapability(SMIMECapability.aES256_CBC);
ASN1EncodableVector attributes = new ASN1EncodableVector();
attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
new IssuerAndSerialNumber(
new X500Name(((X509Certificate) chain[0])
.getIssuerDN().getName()),
((X509Certificate) chain[0]).getSerialNumber())));
attributes.add(new SMIMECapabilitiesAttribute(capabilities));
SMIMESignedGenerator signer = new SMIMESignedGenerator();
signer.addSigner(
myPrivateKey,
(X509Certificate) chain[0],
"DSA".equals(myPrivateKey.getAlgorithm()) ? SMIMESignedGenerator.DIGEST_SHA1
: SMIMESignedGenerator.DIGEST_MD5,
new AttributeTable(attributes), null);
List certList = new ArrayList();
certList.add(chain[0]);
CertStore certs = CertStore.getInstance("Collection",
new CollectionCertStoreParameters(certList), "BC");
signer.addCertificatesAndCRLs(certs);
MimeMultipart mm = signer.generate(mimeMessage, "BC");
MimeMessage signedMessage = new MimeMessage(mimeMessage);
signedMessage.setContent(mm);
signedMessage.saveChanges();
LOG.info("{EMAIL SIGNING] Successfully signed email");
return signedMessage;
I'm able to read the mail but the mail client shows error saying certificates isn't valid/verified.
I have followed this example