java实现smime证书签名,类openssl smime功能

时间:2021-6-4 作者:qvyue

说到证书smime签名,通常使用openssl实现,比如

openssl smime -sign -md sha256 -text -in index.xml -out index.cms -signer FOTA_POC.crt -inkey private.key -certfile Demo_CA.crt

上面命令中,就是把index.xml文件用 FOTA_POC.crt证书(中间证书为Demo_CA.crt)的私钥加签,加密方法为sha256,输出加签结果为index.cms(含原文)
要想实现这样的效果用java来操作的话,当然可以直接调用linux命令,但是java本身也有api来支持这种加签方式。

gradle引入jar包:

compile("org.bouncycastle:bcmail-jdk15on:1.68")
compile("javax.mail:mail:1.4.7")

代码如下:

public static JSONObject SMIMESignData(byte[] dataByte, String privateKeyPem, String intermediateCa,
            String sinerCa) {
        JSONObject resultObj = new JSONObject();
        Boolean signingSucceeded = true;
        X509Certificate cert = null;
        PrivateKey privatekey = null;

        try {
            privatekey = RSAUtils.privateKey(privateKeyPem);
        } catch (Exception e) {
            signingSucceeded = false;
        }

        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");

            InputStream signCertStream = new ByteArrayInputStream(sinerCa.getBytes());
            java.security.cert.X509Certificate signCert = (X509Certificate) cf.generateCertificate(signCertStream);

            InputStream origCertStream = new ByteArrayInputStream(intermediateCa.getBytes());

            java.security.cert.X509Certificate origCert = (X509Certificate) cf.generateCertificate(origCertStream);

            ArrayList certList = new ArrayList();
            certList.add(origCert);
            certList.add(signCert);

            Store> certs = new JcaCertStore(certList);
            SMIMESignedGenerator gen = new SMIMESignedGenerator();
            gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC")
                    .build("SHA256WithRSA", privatekey, signCert));
            gen.addCertificates(new JcaCertStore(certList));
            MimeBodyPart msg = new MimeBodyPart();
            msg.setText(new String(dataByte, StandardCharsets.UTF_8));
            MimeMultipart smime = gen.generate(msg);

            Properties props = System.getProperties();
            Session session = Session.getDefaultInstance(props, null);
            MimeMessage body = new MimeMessage(session);
            body.setContent(smime, smime.getContentType());
            body.saveChanges();

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            body.writeTo(out);
            String signed = new String(out.toByteArray(), StandardCharsets.UTF_8);
            System.out.println(signed);
            resultObj.put("signed", signed);
        } catch (Exception e) {
            signingSucceeded = false;
        }
        resultObj.put("success", signingSucceeded);

        return resultObj;
    }

如此输出的加签字符串格式和上面openssl命令的格式结果是差不多的。
补充一下导入的包

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import javax.crypto.Cipher;
import javax.mail.Session;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;

import com.alibaba.fastjson.JSONObject;
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。