电子邮件与BouncyCastle的签署附件和图像无法通过电子邮件客户端进行验证(Email wit

2019-09-18 23:59发布

我有建立一个MIME消息和数字签名使用MailSigningService主体部(内容)一个MailComposer。

签署是符号()buildSignedGenerator()方法来实现。

收到邮件后,邮件客户端检测到的签名,但抱怨的邮件都可能被篡改。 邮件客户端能够显示的证书,它会显示所有证书(包括对CA)。

所以,无论是基于BouncyCastle的签署实施做得不好或消息本身没有内置理所应当的。 任何提示什么可能错在这里?

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;
}
文章来源: Email with attachments and images signed with bouncycastle can't be verified by email client