0

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

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.