使用Java 7验证OpenSSL生成的S / MIME数字签名文件 [英] Using Java 7 to Verify OpenSSL Generated S/MIME Digital Signature Files

查看:185
本文介绍了使用Java 7验证OpenSSL生成的S / MIME数字签名文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个使用OpenSSL生成S / MIME数字签名的过程,稍后需要使用Java 7对其进行验证。一方面,我们使用OpenSSL读取文本文件并生成一个签名的数字输出,稍后进行验证。 / p>

我们曾经使用OpenSSL进行验证,但现在我们需要Java(注意:我们不能指望现在可以使用OpenSSL)。



我们使用它来签名: openssl smime -sign -inkey private.key -signer public.key -in $ {f}> $ {f} .signed 并进行验证: openssl smime -verify -noverify -in $ {f} .signed



注意:验证不验证证书,仅检查签名/内容。



我需要将此过程的验证部分更改为Java应用程序,最好是Java 7(我认为现在内置了JCE)。



示例输出类似于...

  MIME版本:1.0 
内容类型:多部分/已签名; protocol = application / x-pkcs7-signature; micalg = sha-256; boundary = ---- 185C6C544BB34D30B0835B915C158544

这是一条经过S / MIME签名的消息

------ 185C6C544BB34D30B0835B915C158544
四个分数和七年前我们的父亲在自由大陆上孕育了这个大陆,一个
的新国家,致力于所有
的人都被创造平等的主张。

现在我们正在进行一场内战,测试该国是否...
------ 185C6C544BB34D30B0835B915C158544
内容类型:application / x-pkcs7 -签名; name = smime.p7s
Content-Transfer-Encoding:base64
Content-Disposition:附件;文件名= smime.p7s

MIIKAAYJKoZIhvcNAQcCoIIJ8TCCCe0CAQExDzANBglghkgBZQMEAgEFADALBgkq
hkiG9w0BBwGgggchMIIHHTCCBgWgAwIBAgIEUzuEpzANBgkqhkiG9w0BAQsFADCB
hzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEoMCYGA1UE
CxMfRGVwYXJ0bWVudCBvZiBIb21lbGFuZCBTZWN1cml0eTEiMCAGA1UECxMZQ2Vy
dGlm ...
... JIQeeE =

------ 185C6C544BB34D30B0835B915C158544--

签名算法为sha256WithRSAEncryption;例如...

  openssl smime -pk7out -in message.signed | openssl pkcs7 -text -noout -print_certs 
证书:
数据:
版本:3(0x2)
序列号:1396409511(0x533b84a7)
签名算法:sha256WithRSAEncryption
发行者:C = US,O = Corp,OU = Acme,OU = CA
有效期
不早于:5月16日15:27:56 2014 GMT
不晚于:5月16日15:57:56 2015 GMT
主题:C = US,O = Corp,OU = Acme,OU = CBP,CN = foo.acme.corp.com
主题公钥信息:
公钥算法:rsaEncryption
公钥:(2048位)
模量:
00:00:00:00:00:b1:b6:49:6e:ca:d7: 61:07:a0:18:
...
c9:de:ab:a7:2f:97:e4:f6:64:37:ec:3a:9d:ae:c0:
16:03
指数:65537(0x10001)
X509v3扩展名:
X509v3密钥用法:关键
数字签名,密钥加密外围设备
X509v3证书策略:
策略:2.16.840.1.101.3.2.1.3.8
...

我看了很多例子,尝试了多个例子,但都没有成功。我希望可以与您分享一些资料,但是到目前为止,我取得的成功至少没有帮助。

解决方案

这可以使用Bouncy Castle Crypto API来完成,您可以在其中使用以下官方示例作为参考, https://github.com/bcgit/bc-java/blob/master/mail/src/main/java /org/bouncycastle/mail/smime/examples/ValidateSignedMail.java


对于更简单的示例,您可以对签名的电子邮件进行完整的验证,包括证书链类似于 org.bouncycastle:bcmail-jdk15on:1.52

  import org。 bouncycastle.cms.SignerInformation; 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.mail.smime.validator.SignedMailValidator;

import javax.mail.internet.MimeMessage;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.PKIXParameters;

公共类SignedMailValidatorExample {
public static void main(String [] args)引发异常{
Security.addProvider(new BouncyCastleProvider());
FileInputStreamsignedEmailInputStream = new FileInputStream( signed_email.eml);
MimeMessagesignedEmailMimeMessage = new MimeMessage(null,signedEmailInputStream);
KeyStore trustStore = KeyStore.getInstance( JKS);
trustStore.load(new FileInputStream( truststore.jks), changeit .toCharArray());
PKIXParameters pkixParameters =新的PKIXParameters(trustStore);
pkixParameters.setRevocationEnabled(false);
SignedMailValidator SignedMailValidator =新的SignedMailValidator(signedEmailMimeMessage,pkixParameters);
boolean successValidation = true;
(SignerInformation signerInformation:signedMailValidator.getSignerInformationStore()。getSigners())
if(!signerValidationResult.isValidSignature()){
successValidation = false;
休息时间;
}
}
if(successfulValidation){
System.out.println(签名电子邮件已正确验证。);
} else {
System.out.println(签名电子邮件验证失败。);
}
}
}

其中 truststore.jks 应该包含一个CA证书(例如,发行CA),该证书链接到用于签署电子邮件的证书。现在,您可以使用 https://keystore-explorer.org/ 之类的软件轻松创建此文件。


We have a process that uses OpenSSL to generate S/MIME digital signatures which need to be verified later using Java 7. On one side we use OpenSSL to read in text files and generate a signed digital output which is verified later.

We used to have the verification using OpenSSL but now we need Java (note: we cannot count on OpenSSL being available now).

We use this to sign: openssl smime -sign -inkey private.key -signer public.key -in ${f} > ${f}.signed and this to verify: openssl smime -verify -noverify -in ${f}.signed

Note: that the verify does not validate the certificates, only checks the signature/contents.

I need to change the verify part of this process to be a java application, preferably with Java 7 (which I think now has the JCE built in).

A sample output is something like ...

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

This is an S/MIME signed message

------185C6C544BB34D30B0835B915C158544
Four score and seven years ago our fathers brought forth on this continent, a
new nation, conceived in Liberty, and dedicated to the proposition that all
men are created equal.

Now we are engaged in a great civil war, testing whether that nation, ...
------185C6C544BB34D30B0835B915C158544
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

MIIKAAYJKoZIhvcNAQcCoIIJ8TCCCe0CAQExDzANBglghkgBZQMEAgEFADALBgkq
hkiG9w0BBwGgggchMIIHHTCCBgWgAwIBAgIEUzuEpzANBgkqhkiG9w0BAQsFADCB
hzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDEoMCYGA1UE
CxMfRGVwYXJ0bWVudCBvZiBIb21lbGFuZCBTZWN1cml0eTEiMCAGA1UECxMZQ2Vy
dGlm ...
... JIQeeE=

------185C6C544BB34D30B0835B915C158544--

The signature algorithm is sha256WithRSAEncryption; example ...

openssl smime -pk7out -in message.signed | openssl pkcs7 -text -noout -print_certs
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1396409511 (0x533b84a7)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Corp, OU=Acme, OU=CA
        Validity
            Not Before: May 16 15:27:56 2014 GMT
            Not After : May 16 15:57:56 2015 GMT
        Subject: C=US, O=Corp, OU=Acme, OU=CBP, CN=foo.acme.corp.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:00:00:00:00:b1:b6:49:6e:ca:d7:61:07:a0:18:
                    ...
                    c9:de:ab:a7:2f:97:e4:f6:64:37:ec:3a:9d:ae:c0:
                    16:03
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Certificate Policies: 
                Policy: 2.16.840.1.101.3.2.1.3.8
...

I have looked at many, many examples, tried multiple ones without success. I wish had had some source to share with you, but the success I have had so far would not be helpful in the least.

解决方案

This can be done using the Bouncy Castle Crypto APIs where you can use the following official example as reference, https://github.com/bcgit/bc-java/blob/master/mail/src/main/java/org/bouncycastle/mail/smime/examples/ValidateSignedMail.java.

For a simpler example to perform a full validation of a signed email including the certification chain you would do something like this with org.bouncycastle:bcmail-jdk15on:1.52:

import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.mail.smime.validator.SignedMailValidator;

import javax.mail.internet.MimeMessage;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.PKIXParameters;

public class SignedMailValidatorExample {
    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        FileInputStream signedEmailInputStream = new FileInputStream("signed_email.eml");
        MimeMessage signedEmailMimeMessage = new MimeMessage(null, signedEmailInputStream);
        KeyStore trustStore = KeyStore.getInstance("JKS");
        trustStore.load(new FileInputStream("truststore.jks"), "changeit".toCharArray());
        PKIXParameters pkixParameters = new PKIXParameters(trustStore);
        pkixParameters.setRevocationEnabled(false);
        SignedMailValidator signedMailValidator = new SignedMailValidator(signedEmailMimeMessage, pkixParameters);
        boolean successfulValidation = true;
        for (SignerInformation signerInformation : signedMailValidator.getSignerInformationStore().getSigners()) {
            SignedMailValidator.ValidationResult signerValidationResult = signedMailValidator
                    .getValidationResult(signerInformation);
            if (!signerValidationResult.isValidSignature()) {
                successfulValidation = false;
                break;
            }
        }
        if (successfulValidation) {
            System.out.println("Signed email validated correctly.");
        } else {
            System.out.println("Signed email validation failed.");
        }
    }
}

Where truststore.jks should contain a CA certificate (e.g. the issuing CA) that chains to the certificate used to sign the email. Now, you can easily created this file using a software like https://keystore-explorer.org/.

这篇关于使用Java 7验证OpenSSL生成的S / MIME数字签名文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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