注册并使用S / MIME加密文件(Sign and encrypt a file using S/

2019-10-22 08:55发布

目前我正在努力适应我们用来签署加密/解密使用使用Java和BouncyCastle的OpenSSL和S / MIME XML文件的几个脚本。

该命令进行签名和加密我们的文件:

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文件。 目前,这种情况使用使用OpenSSL库linux下的一组shell脚本。 在未来,我们希望这个过程融入我们的Java应用程序。

我发现,这应该是可能使用BouncyCastle的库(参见这篇文章 )。 答案有提供了两个Java类展示了如何签名和加密使用BouncyCastle的和S / MIME电子邮件。 这相较于我们的OpenSSL的命令,似乎有很多的签署加密在我们的做法是没有必要的电子邮件所需要的东西。

从我们的生成文件的一些更多的元信息:

签名档

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,我们所采取的方式一个简单的文件? 我现在的签名和DE /加密的知识是不是在那一刻非常高,所以请原谅我不能提供代码示例。 我想我正在寻找更投入什么,我需要做的,也许从谁已经做了这个人一定的专业知识。 我希望这是问这个正确的地方。 如果没有,请大家指正。

Answer 1:

我有一个类似的问题,因为你,但我设法解决这个问题。 我不得不提醒你,我对签名和加密知识不高任。 但是这个代码似乎为我工作。

在我来说,我使用GlobalSign的将对PersonalSign亲3证书,以前我刚打电话的OpenSSL从Java中。 但我想清理我的代码,并决定用充气城堡代替。

 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;
}

这仅是签署一个文件中的代码,我希望它能帮助。



文章来源: Sign and encrypt a file using S/MIME