Email with attachments and images signed with bouncycastle can't be verified by email client

浪尽此生 提交于 2019-12-10 18:49:35

问题


I have a MailComposer that builds a mime message and digitally signs the body part (content) using a MailSigningService.

Signing is implemented in the sign() and buildSignedGenerator() methods.

After receiving the mail, the mail client detects a signature but complains that the mail may have been tampered. The mail client is able to show the certificate, it shows all certificates (incl the CA).

So, either the signing implementation based on Bouncycastle is not done properly or the message itself is not built as it should be. Any hints what could go wrong here?

MailComposer.java

private MimeMessage buildMimeMessage(com.jumio.jump.domain.Message message, String[] recipients, String subject, Session session) throws MessagingException, IOException {

    MimeMultipart parts = buildContentParts(message);
    parts = (message.getSendOnBehalfOfDomain() != null) ? signContentParts(message, parts) : parts;

    return buildMimeMessage(message, recipients, subject, session, parts);
}

private MimeMessage buildMimeMessage(com.jumio.jump.domain.Message message, String[] recipients, String subject, Session session, MimeMultipart parts) throws MessagingException {
    MimeMessage mimeMessage = new MimeMessage(session);
    mimeMessage.setSubject(subject, "UTF-8");
    mimeMessage.setHeader("Content-ParamType", "text/html; charset=UTF-8");
    mimeMessage.setSentDate(new Date());
    mimeMessage.setFrom(buildFromEmailAddress(message));
    for (String recipient : recipients) {
        if (recipient == null) {
            continue;
        }
        InternetAddress addressTo = new InternetAddress(recipient);
        mimeMessage.addRecipient(Message.RecipientType.TO, addressTo);
    }
    mimeMessage.setContent(parts);
    return mimeMessage;
}

private MimeMultipart signContentParts(com.jumio.jump.domain.Message message, MimeMultipart contentParts)
        throws MessagingException {
    MimeBodyPart body = new MimeBodyPart();
    body.setContent(contentParts);
    MimeMultipart result;
    try {
        result = mailSigningService.sign(body, signerCertificate, certificateChain,
                privateKey);
    } catch (Exception e) {
        logger.error(String.format("Error signing message $s, sending unsigned", message), e);
        return contentParts;
    }
    return result;
}

MailSigningService.java

@Override
public MimeMultipart sign(MimeBodyPart mimeBodyPart, X509Certificate signerCertificate,
        Certificate[] caCertificateChain,  PrivateKey privateKey)
        throws SMIMEException, OperatorCreationException, CertificateEncodingException, NoSuchProviderException,
        NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    Validate.notNull(signerCertificate, "Valid certificate required, check keystore and/or keystore " +
            "configuration");
    Validate.notNull(privateKey, "Valid private key required, check keystore and/or keystore configuration");

    SMIMESignedGenerator generator = buildSignedGenerator(signerCertificate, caCertificateChain, privateKey);
    return generator.generate(mimeBodyPart);
}


private SMIMESignedGenerator buildSignedGenerator(X509Certificate signerCertificate, Certificate[] caCertificateChain, PrivateKey privateKey)
        throws OperatorCreationException, CertificateEncodingException, NoSuchProviderException,
        NoSuchAlgorithmException, InvalidAlgorithmParameterException {

    SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
    capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
    capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
    capabilities.addCapability(SMIMECapability.dES_CBC);

    ASN1EncodableVector attributes = new ASN1EncodableVector();
    attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(new IssuerAndSerialNumber(new X509Name(
            signerCertificate.getIssuerDN().getName()), signerCertificate.getSerialNumber())));
    attributes.add(new SMIMECapabilitiesAttribute(capabilities));

    SMIMESignedGenerator generator = new SMIMESignedGenerator();


    generator.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(SECURITY_PROVIDER_NAME)
            .setSignedAttributeGenerator(new AttributeTable(attributes)).build(SIGNER_ALGORITHM, privateKey,
                    signerCertificate));


    List<Certificate> certificates=new ArrayList<Certificate>();
    if (caCertificateChain !=null && caCertificateChain.length>0) {
        certificates.addAll(Arrays.asList(caCertificateChain));
    } else {
        certificates.add(signerCertificate);
    }
    Store certificateStore = new JcaCertStore(certificates);
    generator.addCertificates(certificateStore);
    return generator;
}

来源:https://stackoverflow.com/questions/11295760/email-with-attachments-and-images-signed-with-bouncycastle-cant-be-verified-by

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!