title: Read Private Key from PFX-file
body: <p>I know, there are <em>many</em> posts about this, but still I cannot find a solution to get this to work. I have generated a <em>PFX</em>-file with <strong>openssl</strong> on my machine like this:</p>
  
  <pre><code>openssl x509 -req -days 365 -in "myReqest.csr" -signkey "myPrivateKey.pem" -out "myCertificate.crt"
  openssl pkcs12 -export -out "myCertificate.pfx" -inkey "myPrivateKey.pem" -in "myCertificate.crt" -certfile "myCertificate.crt"
  </code></pre>
  
  <p>In my C# app, I access the private key like this:</p>
  
  <pre><code>var cert = new X509Certificate2("myCertificate.pfx", "myPassword");
  cert.HasPrivateKey; // This is always true!
  cert.PrivateKey; // Works on my machine (only)
  </code></pre>
  
  <p>This works perfectly fine (on <em>my</em> machine), but when I run the same code on <em>another</em> machine, it throws: <strong><em>"Key set not found"</em></strong>, even though <code>HasPrivateKey</code> returns <code>true</code>! Shouldn't the private key be included in the *.pfx-file? Can you tell me:</p>
  
  <ol>
  <li><p>Was the certificate/private key somehow automatically installed on my machine by <em>openssl</em> when I created it?</p></li>
  <li><p>How can I read the private key from the *.PFX-file (or alternatively from the *.PEM-file)?</p></li>
  </ol>
  
  <p>StackTrace of Exception:</p>
  
  <pre><code>at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContaier)
  at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContaier, Int32 dwKeySize, SafeProvHandle&amp; safeProvHandle, SafeKeyHandle&amp; safeKeyHandle)
  at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
  at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
  at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameter)
  at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
  </code></pre>
  
  <p><strong><em>Update:</em></strong></p>
  
  <p>I've found out, that the following does work:</p>
  
  <pre><code>// on my machine
  // read certificate from file (exportable!)
  X509Certificate2 cert = new X509Certificate2("filename.pfx", "password", X509KeyStorageFlags.Exportable)
  // sign data etc.
  ((RSACryptoServiceProvider)cert.PrivateKey).SignData(...
  // export private key to XML-file
  File.WriteAllText("filename.xml", cert.PrivateKey.ToXmlString(true));
  
  // on the other machine
  // create new RSA object
  RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
  // import private key from xml
  rsa.FromXmlString(File.ReadAllText("filename.xml"));
  // verify data etc.
  rsa.VerifyData(...
  </code></pre>
  
  <p>However, to me, this is only a workaround, I would like to do it an a more conventional/standard compliant way!</p>