使用S/MIME对文件进行签名和加密 [英] Sign and encrypt a file using S/MIME

查看:117
本文介绍了使用S/MIME对文件进行签名和加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试适应一些脚本,这些脚本用于使用Java和BouncyCastle使用OpenSSL和S/MIME对加密/解密xml文件进行签名.

I am currently trying to adapt a few scripts we use to sign an encrypt/decrypt xml files using OpenSSL and S/MIME using Java and BouncyCastle.

对文件进行签名和加密的命令:

The command to sign and encrypt our file:

openssl smime -sign -signer Pub1.crt -inkey Priv.key -in foo.xml | openssl smime -encrypt -out foo.xml.smime Pub2.crt Pub1.crt

这将生成一个包含我们的xml文件的签名并加密的smime文件.当前,这是在Linux下使用OpenSSL库在Shell脚本集上发生的.将来,我们希望将此过程集成到我们的Java应用程序中.

This generates a signed and encrypted smime-file containing our xml file. Currently this happens using a set of shell scripts under linux using the OpenSSL library. In the future we want to integrate this process into our Java application.

我发现使用BouncyCastle库可以做到这一点(请参见

I've found out that this should be possible using the BouncyCastle library (see this post). The answer there provides two Java classes showing how to sign and encrypt an email using BouncyCastle and S/MIME. Comparing this to our OpenSSL command it seems that many of the things needed to sign an encrypt an email is not needed in our approach.

我们生成的文件中的一些元信息:

Some more meta information from our generated files:

签名文件

MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----709621D94E0377688356FAAE5A2C1321"

加密的文件

MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64

是否甚至可以像我们使用OpenSSL那样对简单文件进行签名和加密?我目前对签名和解密的知识不是很高,因此请原谅我不提供代码示例.我想我正在寻找的是对我需要做的事情的更多投入,也许是已经做过这项工作的人的一些专业知识.我希望这是问这个问题的正确地方.如果没有,请纠正我.

Is it even possible to sign and encrypt a simple file in the way we did it using OpenSSL? My current knowledge of signing and de/encryption is not very high at the moment so forgive me for not providing code samples. I guess what I am looking for is more input into what I need to do and maybe some expertise from people who have already done this. I hope this is the right place to ask this. If not, please correct me.

推荐答案

我和您有一个类似的问题,但我设法解决了.我必须警告您,我对签名和加密的知识也不是很高.但是这段代码似乎对我有用.

I had a similar question as you but I managed to solve it. I have to warn you, my knowledge about signing and encryption isn't that high either. But this code seemed to work for me.

在我的情况下,我使用了来自globalsign的personalsign pro 3证书,以前我只是从Java内部调用openssl.但是我想清除代码,决定改用充气城堡.

In my case I used a personalsign pro 3 certificate from globalsign, Previously I just called openssl from within java. But the I wanted to clean my code and decided to use bouncy castle instead.

 public static boolean signAllFiles(List<File> files) {
    Boolean signingSucceeded = true;
    KeyStore ks = null;
    char[] password = null;

    Security.addProvider(new BouncyCastleProvider());
    try {
        ks = KeyStore.getInstance("PKCS12");
        password = "yourpass".toCharArray();
        ks.load(new FileInputStream("full/path/to/your/original/certificate.pfx"), password);
    } catch (Exception e) {
        signingSucceeded = false;
    }

    // Get privatekey and certificate
    X509Certificate cert = null;
    PrivateKey privatekey = null;

    try {
        Enumeration<String> en = ks.aliases();
        String ALIAS = "";
        Vector<Object> vectaliases = new Vector<Object>();

        while (en.hasMoreElements())
            vectaliases.add(en.nextElement());
        String[] aliases = (String[])(vectaliases.toArray(new String[0]));
        for (int i = 0; i < aliases.length; i++)
            if (ks.isKeyEntry(aliases[i]))
            {
                ALIAS = aliases[i];
                break;
            }
        privatekey = (PrivateKey)ks.getKey(ALIAS, password);
        cert = (X509Certificate)ks.getCertificate(ALIAS);
        // publickey = ks.getCertificate(ALIAS).getPublicKey();
    } catch (Exception e) {
        signingSucceeded = false;
    }

    for (File source : files) {
        String fileName = "the/path/andNameOfYourOutputFile";

        try {
            // Reading files which need to be signed
            File fileToSign = source;
            byte[] buffer = new byte[(int)fileToSign.length()];
            DataInputStream in = new DataInputStream(new FileInputStream(fileToSign));
            in.readFully(buffer);
            in.close();

            // Generate signature
            ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
            certList.add(cert);
            Store<?> certs = new JcaCertStore(certList);
            CMSSignedDataGenerator signGen = new CMSSignedDataGenerator();

            ContentSigner sha1signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(
                    privatekey);
            signGen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                    new JcaDigestCalculatorProviderBuilder().build()).build(sha1signer, cert));
            signGen.addCertificates(certs);
            CMSTypedData content = new CMSProcessableByteArray(buffer);
            CMSSignedData signedData = signGen.generate(content, false);
            byte[] signeddata = signedData.getEncoded();

            // Write signature to Fi File
            FileOutputStream envfos = new FileOutputStream(fileName);
            byte[] outputString = Base64.encode(signeddata);
            int fullLines = (int)Math.floor(outputString.length / 64);
            for (int i = 0; i < fullLines; i++) {
                envfos.write(outputString, i * 64, 64);
                envfos.write("\r\n".getBytes());
            }

            envfos.write(outputString, fullLines * 64, outputString.length % 64);
            envfos.close();
        } catch (Exception e) {
            signingSucceeded = false;
        }
    }
    return signingSucceeded;
}

这只是签名文件的代码,希望对您有所帮助.

This is only the code to sign a file, I hope it helps.

这篇关于使用S/MIME对文件进行签名和加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆