如何在 .NET 中读取没有密码的 PFX 文件中的 public 密钥

How to read public key from PFX file without the password in .NET

我需要能够在不知道密码的情况下从 PFX 文件中读取 public 密钥。我很确定只有私钥被加密了,但是即使我不需要私钥,所有读取 PFX 格式的方便 API 似乎都没有密码就被破坏了。

知道如何读取 public 键吗?

我研究了一会儿,看看是否可以确定证书管理器如何能够打开 PFX 文件。我发现 cryptext.dll 是 "Crypto Shell Extensions" 并处理 PFX 文件。如果您在注册表中搜索 cryptext.dll,您会发现它处理许多不同的文件类型(CER、CRL、加密存储等)。它是使用 rundll32.exe 和 "verb" 调用的。从注册表中,您可以看到哪个动词与每种文件类型相关联。

Cryptext.dll 是一个 COM 组件。尽管它包含嵌入式类型库,但使用 TLBIMP 创建互操作程序集不提供对任何有趣的方法或属性的访问。基于OLEVIEW,它只实现了IUnknown接口。因此,没有明显的方法可以从 .NET 或非托管程序以编程方式访问它。

它是一个 COM 组件这一事实意味着它(几乎可以肯定)使用非托管加密 API。

这里有一些关于逆向工程的建议 cryptext.dll 看看它是如何工作的。转储文件中的 ASCII/UNICODE 字符串。你应该看到上面指出的各种动词。确定哪些动词最有可能支持打开 PFX 文件。尝试 运行 rundll32.exe 使用您通过 PFX 选择的动词作为输入。希望你能弄清楚哪个是正确的动词。

然后将 rundll32.exe 加载到调试器(即 Windbg)中。在调试器中设置命令行以使用您找到的动词以及您的测试 PFX 文件。在 DLL 的内存中将读取断点放在包含该动词的字符串的第一个 byte/word 上。 (您可以使用 windbg 搜索内存)。然后开始执行。当读取断点触发时,开始单步执行读取字符串的代码。它可能处于一个循环中,将命令行上指定的动词与程序中的每个动词进行比较。它应该在比较所讨论的动词的中间。因此它应该退出比较循环并转到该动词的处理程序。进入该处理程序并查看它调用的加密 API。希望了解加密 API 足以弄清楚如何访问 PFX 文件中的 public 密钥。