只需共享更多代码即可。
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个字节与原始文件和重新分类的文件之间存在一些差异。
那是我的第一个成功测试。也许我会发现更多错误,但是有些汇编信息使我更难以接受。