Получить SignedContent от P7M

Я использую библиотеку java (jdk 1.7) и bouncycastle для получения содержимого подписанного файла p7m.

В путь сборки я добавил следующие файлы:

bcpkix-jdk15on-160.jar
commons-io-2.1.jar
log4j-1.2.17.jar
bcprov-ext-jdk15on-160.jar
bcprov-jdk15on-160.jar

Это код, который я использую:

public static void main(String[] args) throws Exception {
    File f = new File("E:\\test\\file.xml.p7m");

    logger.debug(f.getAbsolutePath());
    byte[] content = org.apache.commons.io.FileUtils.readFileToByteArray(f);

    byte[] contentUnsigned = removeP7MCodes(f.getName(), content);
    if (contentUnsigned != null)
        logger.debug(new String(contentUnsigned));
}

public static byte[] removeP7MCodes(final String fileName, final byte[] p7bytes) {
    try {

        if (p7bytes == null)
            return p7bytes;

        if (!fileName.toUpperCase().endsWith(".P7M")) {
            return p7bytes;
        }

        // This is where I get the exception
        CMSSignedData cms = new CMSSignedData(p7bytes); 

        if (cms.getSignedContent() == null) {
            logger.error("Unable to find signed Content during decoding from P7M for file: " + fileName);               
            return null;
        }

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        cms.getSignedContent().write(out);

        return out.toByteArray();
    } catch (CMSException e) {
        logger.error("CMSException from P7M for file: " + fileName, e);
    } catch (IOException e) {
        logger.error("IOException from P7M for file: " + fileName, e);
    }
    return null;
}

Для большинства протестированных мной p7m все работает без ошибок/проблем.

Есть некоторые файлы p7m, которые я не могу декодировать, и я получаю следующую ошибку (я пытался проверить их с помощью онлайн-инструментов, и файлы были подлинными):

11:01:30 DEBUG [DecoderTester:45] - E:\test\file.xml.p7m
11:01:30 ERROR [DecoderTester:75] - CMSException from P7M for file: file.xml.p7m
org.bouncycastle.cms.CMSException: Malformed content.
    at org.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
    at org.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
    at org.bouncycastle.cms.CMSSignedData.<init>(Unknown Source)
    at com.decoder.DecoderTester.removeP7MCodes(DecoderTester.java:63)
    at com.decoder.DecoderTester.main(DecoderTester.java:48)
Caused by: java.lang.IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.DERApplicationSpecific
    at org.bouncycastle.asn1.ASN1Sequence.getInstance(Unknown Source)
    at org.bouncycastle.asn1.cms.ContentInfo.getInstance(Unknown Source)
    ... 5 more

Я попытался удалить одну библиотеку между следующими двумя: bcprov-ext-jdk15on-160.jar и bcprov-jdk15on-160.jar, но получил ту же ошибку.

У тебя есть идеи?


person Marcx    schedule 10.01.2019    source источник
comment
Вы проверили, что содержимое file.xml.p7m является двоичным, а не base64?   -  person pedrofb    schedule 10.01.2019
comment
Спасибо. Я решил проблему, добавив декодирование base64 перед созданием экземпляра для CMSSignedData... Я добавил try { p7bytes = org.bouncycastle.util.encoders.Base64.decode(p7bytes); } catch (Exception e) { logger.debug("File P7m non in base64, tengo content standard" + e.getMessage()); }, не уверен, что есть лучший способ сделать это.   -  person Marcx    schedule 10.01.2019
comment
С этим кодом, я думаю, этого достаточно. Отметьте это, если вам больше нравится этот вариант stackoverflow.com/questions/8571501/   -  person pedrofb    schedule 10.01.2019