刘顺江
刘顺江

Reputation: 11

org.bouncycastle.cms.CMSSignerDigestMismatchException: message-digest attribute value does not match calculated value

please look my android code about verify signature using bouncycastle. condition: have one cms file and root.crt, use root.crt verify cms file. first use:openssl smime -verify -CAfile root.crt -in index.cms -out index_verify.log, it's successful. but i want to code to android app, but it's bad. code as below:

private boolean verifySMIMESignature(String smime, String xmlHash) {
    try {
        Provider provider = new BouncyCastleProvider();
        Security.addProvider(provider);

        String orignal_value = "<cms>\n" +
                "    <file>\n" +
                "        <name>index.xml</name>\n" +
                "        <digest>/R/6Y0pYNL3egASx2X3cxP4kixMesXMHEU2pYFp/mB8=</digest>\n" +
                "        <digesttype>sha256</digesttype>\n" +
                "        <path>.</path>\n" +
                "    </file>\n" +
                "</cms>";
        
        CMSSignedData signedData = new CMSSignedData(new CMSProcessableByteArray(orignal_value.getBytes()), extractCMSFromSMIME(smime));
        Store<X509CertificateHolder> certStore = signedData.getCertificates();
        SignerInformation signer = signedData.getSignerInfos().getSigners().iterator().next();
        
        
        Collection<X509CertificateHolder> certCollection = certStore.getMatches(signer.getSID());
        X509CertificateHolder certHolder = certCollection.iterator().next();
        X509Certificate signerCert = new JcaX509CertificateConverter().getCertificate(certHolder);
        Log.d(TAG, "Using signer certificate: " + signerCert.getSubjectDN());

        
        SignerInformationVerifier verifier = new JcaSimpleSignerInfoVerifierBuilder()
                .setProvider(provider)
                .build(signerCert);

        return signer.verify(verifier);

    } catch (Exception e) {
        Log.e(TAG, "verify fail: " + e.getMessage(), e);
        return false;
    }
}

private byte[] extractCMSFromSMIME(String smimeData) {
    String[] lines = smimeData.split("\n");
    boolean cmsBegin = false;
    String boundary = null;
    StringBuilder contentBuilder = new StringBuilder();
    for (String line : lines) {
        if (line.contains("boundary=")) {
            int start = line.indexOf("boundary=\"") + "boundary=\"".length();
            int end = line.length() - 2;
            Log.d(TAG, "starttttttt: " + start + " end: " + end);
            boundary = line.substring(start, end);
            Log.d(TAG, "find boundary: " + boundary);
            continue;
        }
        if (!cmsBegin && line.contains("Content-Disposition:")) {
            cmsBegin = true;
            continue;
        }
        if (cmsBegin) {
            if (!TextUtils.isEmpty(boundary) && line.contains(boundary)) {
                break;
            } else {
                contentBuilder.append(line);
            }
        }
    }
    String cmsString = contentBuilder.toString();
    Log.d(TAG, "cms: " + cmsString);
    return Base64.getDecoder().decode(cmsString);
}

extractCMSFromSMIME is to be extract signature from cms file. orignal_value is orignal value. code not use root.crt, and use it's self cert also fail. result show org.bouncycastle.cms.CMSSignerDigestMismatchException: message-digest attribute value does not match calculated value.

i try many method, not luckly all fail. please help to resolve it. thanks

Upvotes: 0

Views: 40

Answers (0)

Related Questions