Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It seems to me you should import the key in a little other way. See <a href="http://support.microsoft.com/kb/950090" rel="noreferrer">http://support.microsoft.com/kb/950090</a> for an example.</p> <p>Moreover I find not good to save private key in <code>UseMachineKeyStore</code>. In the most cases you need import certificate with the private key in My store of some user and import in Root only certificate without private key.</p> <p>It you do need save private key on Machine key store, that you should at least protect the key for reading only for some selected users and not from Everyone. The key container is just a file in the file system (see files in the diriectory "%ALLUSERSPROFILE%\Microsoft\Crypto\Keys") which has security descriptors like other files in NTFS. To change security descriptors of the files you can use <code>CspKeyContainerInfo.CryptoKeySecurity</code> property and <code>AddAccessRule</code>, <code>RemoveAccessRule</code> and so on.</p> <p><strong>UPDATED</strong>: First of all sorry for the long answer.</p> <p>I could divide <a href="http://testportal.curit.nl/Help/ConsoleApplication2.zip" rel="noreferrer">your program code</a> in two parts. In the first part you generate a self-signed certificate which can be used as a CA certificates and you save it as <em>rootcert.pfx</em> file. In the second part you import the certificate, but use <code>RSACryptoServiceProvider</code> filled with properties of previous created key instead of using <em>rootcert.pfx</em>.</p> <p><strong>I suggest to replace the second part of your code to more standard and simple code: import certificate with the private key from <em>rootcert.pfx</em> like it described in <a href="http://support.microsoft.com/kb/950090" rel="noreferrer">http://support.microsoft.com/kb/950090</a>. It works very well.</strong></p> <p>I don't use myself the BouncyCastle, so I could not comment the first part of your code, but in general what you do in the code you could do also with respect of <a href="http://msdn.microsoft.com/en-us/library/bfsktky3.aspx1.1." rel="noreferrer">MakeCert.exe</a> utility from the Windows SDK. You can do like following</p> <pre><code>MakeCert.exe -pe -ss MY -a sha1 -cy authority -len 2048 -m 120 -r -# 1 -n "CN=Some Root CA, C=NL, OU=BleedingEdge, ST=Somewhere, L=Somelane" </code></pre> <p>Then you can export certificate with or without private key with respect of Certificate Snap-In (for mmc.exe). In the example above I don't restrict CA for some special EKU, so you can use it without any restriction, but if you do need the restrictions you can just add additional parameters to <a href="http://msdn.microsoft.com/en-us/library/bfsktky3.aspx1.1." rel="noreferrer">MakeCert.exe</a>. You can also use MakeCert.exe to create other certificate which are signed with the CA certificate. So you are able to make small PKI with respect of MakeCert.exe only.</p> <p>It seems to me that creating of the certificate is really a separate part of your code. Your main problem is in the second part.</p> <p>If you want import CA certificate you should take in consideration some important things:</p> <ul> <li>You should import it in <code>Root</code> or <code>AuthRoot</code> in <code>localMachine</code> on every (or many) computer of your organization, but you should import the certificate <strong>without the private key</strong>. You can do this with respect of following</li> </ul> <p>CertMgr.exe -add -c CA.cer -s -r localMachine AuthRoot</p> <ul> <li>You should import CA certificate <strong>with private key</strong> on the computer on <strong>one</strong> computer and <strong>only for the user who will issue other certificates</strong> (who will sign new certificates with the private key of CA). One use to import the certificate in the <strong>My</strong> certificate store of <strong>CurrentUser</strong>. So the code on the computer could looks like </li> </ul> <p>following:</p> <pre><code>// import PFX X509Certificate2 cert = new X509Certificate2 (@"c:\Oleg\rootcert.pfx", "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); // save certificate and private key X509Store storeMy = new X509Store (StoreName.My, StoreLocation.CurrentUser); storeMy.Open (OpenFlags.ReadWrite); storeMy.Add (cert); // get certificate without private key // one can import certificate from rootcert.cer instead byte[] certBlobWithoutPrivateKey = cert.Export (X509ContentType.Cert); // save pure certificate in Root of the local machine X509Certificate2 certWithoutPrivateKey = new X509Certificate2 (certBlobWithoutPrivateKey); X509Store storeRoot = new X509Store (StoreName.Root, StoreLocation.LocalMachine); storeRoot.Open (OpenFlags.ReadWrite); storeRoot.Add (certWithoutPrivateKey); </code></pre> <p>The code will work if you do will change <code>StoreName.My</code> and <code>StoreLocation.CurrentUser</code> to another values, but I don't recommend you to do this.</p> <p>In general importing of certificates in .NET code look like a little strange and not shows what will be done under the hood. Windows knows only <a href="http://msdn.microsoft.com/en-us/library/ms867086.aspx" rel="noreferrer">Key Containers</a> where private keys (to be exactly the key pair) will be saved with respect of CSP and <a href="http://msdn.microsoft.com/en-us/library/aa386971.aspx" rel="noreferrer">Certificate Stores</a> where certificates will be saved (see <a href="http://msdn.microsoft.com/en-us/library/bb204781.aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/bb204781.aspx</a> about location of the store). To be able to save information about the key container in the certificate store Microsoft introduced so named <a href="http://msdn.microsoft.com/en-us/library/aa376523.aspx" rel="noreferrer">Certificate Extended Properties</a>. If you use in .NET properties of <code>X509Certificate2</code> like <code>Thumbprint</code>, <code>FriendlyName</code>, <code>HasPrivateKey</code>, <code>Archived</code> and so on you work with the Extended Properties of the certificate. So I recommend you to import CA certificate twice. One in <code>Root</code> or <code>AuthRoot</code> <strong>without</strong> setting <code>CERT_KEY_PROV_INFO_PROP_ID</code> <a href="http://msdn.microsoft.com/en-us/library/aa376523.aspx" rel="noreferrer">Certificate Extended Properties</a> and one more time in <code>My</code> store <strong>with</strong> the setting of information about the place of Key Container with the private key (<code>CERT_KEY_PROV_INFO_PROP_ID</code>). Moreover you can consider to remove private key directly after the usage, import it only if you really need to use it and <strong>not hold it permanently</strong>. All this is important to have better security.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload