首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >证书存储中的证书私钥-不可读

证书存储中的证书私钥-不可读
EN

Stack Overflow用户
提问于 2012-11-05 12:11:27
回答 1查看 13K关注 0票数 11

我想我也有同样的问题,就像这家伙,但我没有他/她那么幸运,因为提供的解决方案对我不起作用。

所提供的解决方案查找C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys (子目录中的not)和C:\Users\[Username]\AppData\Roaming\Microsoft\Crypto\RSA (和子目录)上的文件,但是由于我希望安装程序能够将应用程序安装到所有用户,因此自定义操作在SYSTEM-User下运行,这将导致实际在C:\ProgramData\Application Data\Microsoft\Crypto\RSA\S-1-5-18中创建的文件。

当运行“正常”应用程序作为管理员(右键单击->运行为Admin)执行完全相同的代码时,将在C:\Users\[Username]\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-1154405193-2177794320-4133247715-1000创建一个文件。

使用WIX自定义操作生成的证书似乎没有私钥(“密钥集不存在”),而由“普通”应用程序生成的证书似乎没有私钥。

当查看文件的权限时,它们似乎没有问题,即使它们不同(工作的文件确实包括SYSTEM用户),即使将SYSTEM的权限添加到(“不工作的”)文件中,我也无法读取私钥,这里也有相同的错误。

然后,我使用了FindPrivateKey,使用了查找相应的文件,但是我得到的只有"Unable to obtain private key file name"

好的,这里的一个怎么样?SYSTEM用户存储的证书的私钥存储在哪里?也许没有创建任何私钥文件?为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-08 12:23:43

我用谷歌搜索了几乎所有的东西.据我所知,有一些事情要做:

  1. 生成一个X509Certificate2
  2. 确保私钥容器是持久的(不是临时的)
  3. 确保有经过身份验证的用户的访问规则。,这样他们就能看到私钥

因此,最后的a代码如下:

代码语言:javascript
运行
复制
X509Certificate2 nonPersistentCert = CreateACertSomehow();

// this is only required since there's no constructor for X509Certificate2 that uses X509KeyStorageFlags but a password
// so we create a tmp password, which is not reqired to be secure since it's only used in memory
// and the private key will be included (plain) in the final cert anyway
const string TMP_PFX_PASSWORD = "password";

// create a pfx in memory ...
byte[] nonPersistentCertPfxBytes = nonPersistentCert.Export(X509ContentType.Pfx, TMP_PFX_PASSWORD);

// ... to get an X509Certificate2 object with the X509KeyStorageFlags.PersistKeySet flag set
X509Certificate2 serverCert = new X509Certificate2(nonPersistentCertPfxBytes, TMP_PFX_PASSWORD,
    X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable); // use X509KeyStorageFlags.Exportable only if you want the private key to tbe exportable

// get the private key, which currently only the SYSTEM-User has access to
RSACryptoServiceProvider systemUserOnlyReadablePrivateKey = serverCert.PrivateKey as RSACryptoServiceProvider;

// create cspParameters
CspParameters cspParameters = new CspParameters(systemUserOnlyReadablePrivateKey.CspKeyContainerInfo.ProviderType, 
    systemUserOnlyReadablePrivateKey.CspKeyContainerInfo.ProviderName, 
    systemUserOnlyReadablePrivateKey.CspKeyContainerInfo.KeyContainerName)
{
    // CspProviderFlags.UseArchivableKey means the key is exportable, if you don't want that use CspProviderFlags.UseExistingKey instead
    Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseArchivableKey,
    CryptoKeySecurity = systemUserOnlyReadablePrivateKey.CspKeyContainerInfo.CryptoKeySecurity
};

// add the access rules
cspParameters.CryptoKeySecurity.AddAccessRule(new CryptoKeyAccessRule(new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), CryptoKeyRights.GenericRead, AccessControlType.Allow));

// create a new RSACryptoServiceProvider from the cspParameters and assign that as the private key
RSACryptoServiceProvider allUsersReadablePrivateKey = new RSACryptoServiceProvider(cspParameters);
serverCert.PrivateKey = allUsersReadablePrivateKey;

// finally place it into the cert store
X509Store rootStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
rootStore.Open(OpenFlags.ReadWrite);
rootStore.Add(serverCert);
rootStore.Close();

// :)
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13231858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档