title: Azure WorkerRole: Certificate Key not valid for use in specified state
body: <blockquote>
    <p>System.Security.Cryptography.CryptographicException: Key not valid for
    use in specified state.</p>
    
    <p>at
    System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32
    hr)    at System.Security.Cryptography.Utils._ExportKey(SafeKeyHandle
    hKey, Int32 blobType, Object cspObject)    at
    System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean
    includePrivateParameters)    at
    System.Security.Cryptography.RSA.ToXmlString(Boolean
    includePrivateParameters)</p>
  </blockquote>
  
  <p>Now, i belive this happens because that when Azure adds the Certificate to my WorkerRole deployment, it do not install the certificate with the option "Mark this Key as Exportable".</p>
  
  <p>I need to add a certificate to my workerrole to beable to decypt a encryptet setting.</p>
  
  <p>Anyone have any ideas about how i can make Azure Mark the certificates private key as exportable. or if it could be another issue.</p>
  
  <p>Onstart:</p>
  
  <pre><code>    try{
  
          var conn = System.Text.UTF8Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(setting), true, cert));
  
      }catch(Exception ex)
      {
          Trace.TraceError(ex.ToString());
  
      }
  </code></pre>
  
  <p>Methods:</p>
  
  <pre><code>        public static X509Certificate2 LoadCertificate(StoreName storeName,
     StoreLocation storeLocation, string tprint)
          {
              X509Store store = new X509Store(storeName, storeLocation);
  
              try
              {
                  store.Open(OpenFlags.ReadOnly);
  
                  X509Certificate2Collection certificateCollection =
                       store.Certificates.Find(X509FindType.FindByThumbprint,
                                              tprint, false);
  
                  if (certificateCollection.Count &gt; 0)
                  {
                      //  We ignore if there is more than one matching cert, 
                      //  we just return the first one.
                      return certificateCollection[0];
                  }
                  else
                  {
                      throw new ArgumentException("Certificate not found");
                  }
              }
              finally
              {
                  store.Close();
              }
          }
      public static byte[] Decrypt(byte[] encryptedData, bool fOAEP,
                             X509Certificate2 certificate)
      {
          if (encryptedData == null)
          {
              throw new ArgumentNullException("encryptedData");
          }
          if (certificate == null)
          {
              throw new ArgumentNullException("certificate");
          }
  
          using (RSACryptoServiceProvider provider = new RSACryptoServiceProvider())
          {
              // Note that we use the private key to decrypt
              provider.FromXmlString(GetXmlKeyPair(certificate));
  
              return provider.Decrypt(encryptedData, fOAEP);
          }
      }
      public static string GetXmlKeyPair(X509Certificate2 certificate)
      {
          if (certificate == null)
          {
              throw new ArgumentNullException("certificate");
          }
  
          if (!certificate.HasPrivateKey)
          {
              throw new ArgumentException("certificate does not have a private key");
          }
          else
          {
              return certificate.PrivateKey.ToXmlString(true);
          }
      }
  </code></pre>