C#从签名文件中获取签名CMS的实现 我使用C++ Cuth32.DLL实现了从签名的C汇编程序DLL中提取SigNEDCMS对象。

C#从签名文件中获取签名CMS的实现 我使用C++ Cuth32.DLL实现了从签名的C汇编程序DLL中提取SigNEDCMS对象。,c#,c++,certificate,digital-signature,C#,C++,Certificate,Digital Signature,用于签署dll的证书已过期,但其中包含有效的证书链。重要的是,证书由三个证书组成,我都想提取它们 该函数工作得很好,但由于crypt32.dll函数是非擦洗的,我正在寻找一个纯C#实现,它也在做同样的事情,并提供SignedCms对象 到目前为止,我能找到的最接近的是X509证书 X509Certificate2 cert = new X509Certificate2(fileName) 解决方案 感谢下面的帖子,我可以实现一个纯C#方法来提取SignedCms 唯一不完美的地方是sta

用于签署dll的证书已过期,但其中包含有效的证书链。重要的是,证书由三个证书组成,我都想提取它们

该函数工作得很好,但由于crypt32.dll函数是非擦洗的,我正在寻找一个纯C#实现,它也在做同样的事情,并提供SignedCms对象

到目前为止,我能找到的最接近的是X509证书

X509Certificate2 cert = new X509Certificate2(fileName)


解决方案

感谢下面的帖子,我可以实现一个纯C#方法来提取SignedCms

唯一不完美的地方是startindex被关闭了8个字节,而大小则小了10个字节

    public static SignedCms GetSignedCmsFromFile(string fileName)
    {
        var result = new SignedCms();

        uint startIndex = 0;
        uint size = 0;

        var reader = new PeHeaderReader(fileName);
        if (reader.Is32BitHeader)
        {
            startIndex = reader.OptionalHeader32.CertificateTable.VirtualAddress;
            size = reader.OptionalHeader32.CertificateTable.Size;
        }
        else
        {
            startIndex = reader.OptionalHeader64.CertificateTable.VirtualAddress;
            size = reader.OptionalHeader64.CertificateTable.Size;
        }

        //var data = File.ReadAllBytes(fileName).Skip((int)startIndex).Take((int)size).ToArray();

        //Somehow the start index and size are not fitting perfectly and I have to adapt them
        var data = File.ReadAllBytes(fileName).Skip((int)startIndex + 8).Take((int)size - 10).ToArray();

        result.Decode(data);

        return result;
    }

我还没有找到与该调用相当的CNG,但这里有一个可以让您提取PKCS#7(签名CMS的字节):

说明书上说:

Authenticode签名可以“嵌入”在Windows PE文件中,在 由可选标头中的证书表项指定的位置 数据目录

以下是PE头中字节的详细概述: - -

以及几乎所有的细节:

在github上,我发现一个托管示例读取PE头:

编辑:根据@martin-s的评论,github上的代码不可靠,他成功地使用了以下替代方案:


所有的部分都应该完成这项工作。

请参阅下面帖子中的Art(最后一个答案)。如果你有没有最新更新的Win XP版本,他会问你一个好问题:这里是微软论坛上的同一个问题,供参考,还有一个,看看这个:谢谢你提供的信息。我可以实现它,让它工作。唯一不完美的地方是startindex被关闭了8个字节,而PE Header类中的大小则小了10个字节。你知道为什么会这样吗?是MSIL、x86还是x64编译的程序集?同时我发现了问题。您提供的链接中的PE解析器在这方面似乎有点缺陷。我在网上发现了一个不同的、更新的PE文件解析器实现,它可以在没有这些问题的情况下工作。
    public static SignedCms GetSignedCmsFromFile(string fileName)
    {
        var result = new SignedCms();

        uint startIndex = 0;
        uint size = 0;

        var reader = new PeHeaderReader(fileName);
        if (reader.Is32BitHeader)
        {
            startIndex = reader.OptionalHeader32.CertificateTable.VirtualAddress;
            size = reader.OptionalHeader32.CertificateTable.Size;
        }
        else
        {
            startIndex = reader.OptionalHeader64.CertificateTable.VirtualAddress;
            size = reader.OptionalHeader64.CertificateTable.Size;
        }

        //var data = File.ReadAllBytes(fileName).Skip((int)startIndex).Take((int)size).ToArray();

        //Somehow the start index and size are not fitting perfectly and I have to adapt them
        var data = File.ReadAllBytes(fileName).Skip((int)startIndex + 8).Take((int)size - 10).ToArray();

        result.Decode(data);

        return result;
    }