gpt4 book ai didi

c# - 使用 RSACryptoServiceProvider 从 XML 导入 RSA 公钥将属性 PublicOnly 设置为 false

转载 作者:太空狗 更新时间:2023-10-29 23:50:53 25 4
gpt4 key购买 nike

我正在创建一个工具来管理 Windows 上的 RSA key 对,因为没有内置的功能,我们广泛使用 .NET 中的 RSA 加密功能。

该工具提供各种功能,例如列出现有 RSA key 对、创建新 key 、删除 key 、导出 key 以及从先前创建的 XML 导出(使用 ASPNet_RegIIS.exe 导出)导入 key 。

除了只导入用于加密操作的公钥之外,我拥有所有的功能。当最初在服务器上创建 key 对时,使用 aspnet_regiis.exe 将公共(public)和公共(public)/私有(private)导出到 xml。

我热衷于提供在其他机器上加密配置文件的选项,以防止私钥被分发,除非绝对必要。

每次我从先前导出的 XML block 中导入公钥时,RSACryptoServiceProviderPublicOnly 属性都设置为 false,表示 key 对具有公钥和私钥 key 。我已确认 xml 不包含私钥信息,因此问题不在 xml 文件中。

问题似乎发生在使用 CspParameters 对象并将标志指定为 CspProviderFlags.UseMachineKeyStore 时。如果您在未指定任何 Csp 参数的情况下构建 RSACryptoServiceProvider,然后从 xml 导入 key ,则 PublicOnly 属性正确设置为 false。

String xmlText = File.ReadAllText(filePath);
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
csp.FromXmlString(xmlText);
//csp.PublicOnly equals true;

但是,由于我需要给它的 key 容器一个名称,以便以后可以将其用于加密操作,因此在构造 RSACryptoServiceProvider 时,我不得不使用 CspParameters 对象因为没有其他方法可以命名 key 容器。

String xmlText = File.ReadAllText(filePath);
CspParameters cspParams = new CspParameters();
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.KeyContainerName = keyContainerName;
RSACryptoServiceProvider csp = new RSACryptoServiceProvider(cspParams);
csp.PersistKeyInCsp = true;
csp.FromXmlString(xmlText);
//csp.PublicOnly equals false;

我尝试了此代码的各种版本,但问题仍然存在。我注意到有类似的问题,例如 RSA Encryption public key not returned from container?但是我认为这个问题是不同的,并且没有给出令人满意的答案。

因此,问题是如何从 XML 导入 RSA 公钥并为 key 容器命名,同时确保容器中只存在一对公钥?

编辑

围绕此领域的进一步研究还表明,从 xml 导入完整 key 并设置标志以允许导出 key 时会出现问题。

CspProviderFlags.UseArchivableKey;

当在 CSP 参数对象上指定此标志时,将在行 csp.FromXmlString(xmlText); 处抛出类型为“指定的无效标志”的异常;

我真的无法解释。 key 已创建并先前导出为 XML,当然如果 key 先前已导出,则应该可以导入它并允许它再次导出?

我对此做了很多研究,但就是看不到这两个问题的答案。

我尝试将 csp 提供程序类型从 PROV_RSA_FULL 更改为 PROV_RSA_AES,因为我相信这是现在的默认设置,我认为 key 最初可能是使用它而不是 PROV_RSA_FULL 创建的,但这没有任何区别。

最佳答案

当导入 key 参数(从 XML 或从 RSAParameters)时,如果提供了公共(public)参数,RSACryptoServiceProvider 将与当前 key 分离;如果导入私有(private)参数,它只会替换 key 容器中 key 的内容。

http://referencesource.microsoft.com/#mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs,b027f6909aa0a6d1

ImportCspBlob 采用了不同的路径,但最终得出了相同的结论:如果正在导入一个仅供公开的 blob,它会分离到一个临时 key 。 http://referencesource.microsoft.com/#mscorlib/system/security/cryptography/utils.cs,754f1f4055bba611

似乎底层的 Windows 加密 API 不允许存储公钥(除了它们与私钥一起存储时)。

位于 https://msdn.microsoft.com/en-us/library/windows/desktop/bb427412(v=vs.85).aspx 的 CNG 文档说

For BCryptExportKey to create a persisted key pair, the input key BLOB must contain a private key. Public keys are not persisted.

人们假设他们指的是 BCryptImportKey,但“公钥不持久化”感觉很权威。

对于 CAPI,我找不到任何如此简单的东西。

我能找到的最好的是“ key 容器”(https://msdn.microsoft.com/en-us/library/windows/desktop/ms721590(v=vs.85).aspx#_security_key_container_gly)的 CAPI 定义:

key container

A part of the key database that contains all the key pairs (exchange and signature key pairs) belonging to a specific user. Each container has a unique name that is used when calling the CryptAcquireContext function to get a handle to the container.

此定义仅引用“ key 对”,表明“公钥”可能会被存储层拒绝。考虑到 RSACryptoServiceProvider 的行为,这似乎很有可能。

关于c# - 使用 RSACryptoServiceProvider 从 XML 导入 RSA 公钥将属性 PublicOnly 设置为 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27743714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com