Проверка S / MIME с сертификатом x509 - PullRequest
1 голос
/ 21 декабря 2011

У меня проблемы с проверкой подписанного сообщения S / Mime с сертификатом x509.Это мой код:

public class verifyMsg {

private static void verify(SMIMESignedParser s) throws Exception {

    Security.addProvider(new BouncyCastleProvider());
    System.out.println("wbilem");
    CertStore certs = s.getCertificatesAndCRLs("Collection", "BC");

    SignerInformationStore signers = s.getSignerInfos();
    Collection c = signers.getSigners();
    Iterator it = c.iterator();

    while (it.hasNext()) {
        File f = new File("signature.crt");
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        byte[] keyBytes = new byte[(int) f.length()];
        dis.readFully(keyBytes);
        dis.close();
        fis.close();
        SignerInformation signer = (SignerInformation) it.next();
        Collection certCollection = certs.getCertificates(signer.getSID());
        Iterator certIt = certCollection.iterator();
        FileInputStream fr = new FileInputStream("signature.crt");
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        X509Certificate cert = (X509Certificate) cf.generateCertificate(fr);


        if (signer.verify(cert, "BC")) { //problem is there...
            System.out.println("signature verified");
        } else {
            System.out.println("signature failed!");
        }

    }
}

public static void main(String[] args) throws Exception {
    Properties props = System.getProperties();
    Session session = Session.getDefaultInstance(props, null);

    try {
        FileInputStream fr = new FileInputStream("signature.crt");
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        X509Certificate c = (X509Certificate) cf.generateCertificate(fr);
        System.out.println("Read in the following certificate:");
        System.out.println("\tCertificate for: " + c.getSubjectDN());
        System.out.println("\tCertificate issued by: " + c.getIssuerDN());
        System.out.println("\tThe certificate is valid from " + c.getNotBefore() + " to " + c.getNotAfter());
        System.out.println("\tCertificate SN# " + c.getSerialNumber());
        System.out.println("\tGenerated with " + c.getSigAlgName());
        System.out.println(c.getPublicKey());
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("G:\\MIME.txt"));
        if (msg.isMimeType("multipart/signed")) {

            SMIMESignedParser s = new SMIMESignedParser((MimeMultipart) msg.getContent());
            System.out.println("Status:");
            verify(s);
        } else if (msg.isMimeType("application/pkcs7-mime")) {

            // in this case the content is wrapped in the signature block.
            //
            SMIMESignedParser s = new SMIMESignedParser(msg);
            System.out.println("Status1:");
            verify(s);
        } else {
            System.err.println("Not a signed message!");
        }

    } catch (MessagingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (CMSException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

И у меня проблема с этим исключением:

CMSSignerDigestMismatchException: значение атрибута message-digest не соответствует вычисленному значению.Я не знаю, что я делаю не так.Я использую JDK 1.4.2.

Ответы [ 2 ]

1 голос
/ 22 декабря 2011

Я только что узнал, что проблема с сообщением.Я преобразовал байтовый массив в строку, а затем эту строку во входной поток.Теперь я даю байтовый массив inputtream без преобразования, и все в порядке :)

0 голосов
/ 18 декабря 2013

Я решил эту проблему. Если вы подписываете данные с помощью S / MIME, то в соответствии со стандартом S / MIME у нас должны быть MIME-версия, Content-Type ... и т. Д., А заголовки отделяются от сообщения, которое должно быть подписано пустой строкой. . Большую часть времени, когда сообщение имеет тип «text / plain», мы не будем добавлять к сообщению заголовки, что очевидно. Но если вы используете S / MIME для подписи данных, оно будет искать стандартные заголовки и проблемы S / MIME. произойдет мисс мах в дайджесте.

Добавить следующие заголовки в сообщение перед подписью MIME-версия: 1.0 Тип содержимого: текст / обычный;

Или просто добавьте одну пустую строку перед сообщением.

Вышеописанный подход работает нормально для меня.

...