BouncyCastle:将Pkcs7文件从附件转换为已分离,然后再转换为附件

时间:2018-10-31 16:31:31

标签: c# bouncycastle pkcs#7

只需共享更多代码即可。

    public static byte[] ExtrairConteudoDeArquivoAssinado(byte[] arquivo)
    {
        if (arquivo == null || arquivo.Length == 0)
        {
            throw new NegocioException("Arquivo nulo.");
        }
        try
        {

            CmsSignedDataParser c = new CmsSignedDataParser(arquivo);
            Stream content = c.GetSignedContent().ContentStream;

            byte[] arquivoDecriptografado = ToByteArray(content);
            content.Dispose();

            return arquivoDecriptografado;

        }
        catch (CmsException e)
        {
            throw new NegocioException("Não é possível extrair o conteúdo de um arquivo não assinado", e);
        }
        catch (OutOfMemoryException)
        {
            throw;
        }
        catch (Exception e)
        {
            throw new NegocioException("Arquivo corrompido.", e);
        }
    }

    private static byte[] ToByteArray(Stream content)
    {
        int maxBufferLength = 4096;
        List<byte[]> bufferList = new List<byte[]>();
        byte[] buffer = new byte[maxBufferLength];
        int totalBytesLidos = 0;
        int bytesLidosNaIteracao = 0;

        while ((bytesLidosNaIteracao = content.Read(buffer, 0, maxBufferLength)) > 0)
        {
            bufferList.Add(buffer);
            buffer = new byte[maxBufferLength];
            totalBytesLidos += bytesLidosNaIteracao;
        }
        byte[] arquivoDecriptografado = new byte[totalBytesLidos];

        for (int i = 0; i < bufferList.Count; i++)
        {
            int offset = i * maxBufferLength;
            int tamanhoACopiar = offset + maxBufferLength > totalBytesLidos ? totalBytesLidos - offset : maxBufferLength;
            Buffer.BlockCopy(bufferList[i], 0, arquivoDecriptografado, offset, tamanhoACopiar);
        }
        return arquivoDecriptografado;
    }


    public static byte[] AtacharAssinatura(byte[] arquivoOriginal, byte[] assinaturaDetached)
    {

        CmsSignedDataGenerator sg = new CmsSignedDataGenerator();
        CmsSignedData sigData = new CmsSignedData(assinaturaDetached);

        sg.AddAttributeCertificates(sigData.GetAttributeCertificates("Collection/AttributeCertificate"));
        sg.AddCertificates(sigData.GetCertificates("Collection/Certificate"));
        sg.AddCrls(sigData.GetCrls("Collection/CRL"));
        sg.AddSigners(sigData.GetSignerInfos());

        CmsSignedData cmsSigDataFinal = sg.Generate(new CmsProcessableByteArray(arquivoOriginal), true);

        return cmsSigDataFinal.GetEncoded();

    }




    public static byte[] DetacharAssinatura(byte[] arquivo)
    {
        CmsSignedDataGenerator sg = new CmsSignedDataGenerator();
        CmsSignedData sigData = new CmsSignedData(arquivo);

        sg.AddAttributeCertificates(sigData.GetAttributeCertificates("Collection/AttributeCertificate"));
        sg.AddCertificates(sigData.GetCertificates("Collection/Certificate"));
        sg.AddCrls(sigData.GetCrls("Collection/CRL"));
        sg.AddSigners(sigData.GetSignerInfos());

        CmsSignedData cmsSigDataFinal = sg.Generate(CmsSignedDataGenerator.Data, null, false);

        return cmsSigDataFinal.GetEncoded();

    }

这是我的第一个功能性解决方案。在我的情况下,在测试过程中,分离并再次附加后生成的文件与原始文件有点不同。 调试BouncyCastle代码,AlgorithmIdentifier类的编码将0x0500打印为参数的空数组。使用DerOutputStream类编码增强对象时,会有一个级联包络。拳头是物体的标签,然后是长度,然后是字节数组。 由于打印到最终文件的级联长度,空数组的这2个字节与原始文件和重新分类的文件之间存在一些差异。

那是我的第一个成功测试。也许我会发现更多错误,但是有些汇编信息使我更难以接受。

0 个答案:

没有答案