title: How to create a self-signed Certificate using CLR Security to use with EnvelopedCms?
body: <p>I am trying to create a self-signed Certificate using the CLR-Security library Security.Cryptography.dll (their homepage: <a href="http://clrsecurity.codeplex.com" rel="nofollow">http://clrsecurity.codeplex.com</a>)</p>
  
  <p>I am able to create the certificate and even to Encrypt with it,
  but Decrypt fails with the following error "Invalid provider type specified."</p>
  
  <p>Here is the certificate creation code:</p>
  
  <pre><code>public static bool generateCertificate(string distinguishedName)
  {
          // Generate Key
          CngKeyCreationParameters keyParams = new CngKeyCreationParameters();
          keyParams.KeyCreationOptions = CngKeyCreationOptions.MachineKey | CngKeyCreationOptions.OverwriteExistingKey;
          keyParams.KeyUsage = CngKeyUsages.AllUsages; //CngKeyUsages.Decryption | CngKeyUsages.Signing;
          keyParams.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider;
          keyParams.ExportPolicy = CngExportPolicies.AllowExport;
          CngKey newKey = CngKey.Create(CngAlgorithm2.Rsa, Guid.NewGuid().ToString(), keyParams);
  
          // Init certificate
          X509CertificateCreationParameters certParams = new X509CertificateCreationParameters(new X500DistinguishedName(distinguishedName));
          certParams.SignatureAlgorithm = X509CertificateSignatureAlgorithm.RsaSha1;
          certParams.StartTime = DateTime.Now;
          certParams.EndTime = DateTime.Now.AddYears(10);
  
          // Create cert
          X509Certificate2 newCert = newKey.CreateSelfSignedCertificate(certParams);
  
          // Save to store
          X509Store lmStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
          lmStore.Open(OpenFlags.ReadWrite);
          lmStore.Add(newCert);
          lmStore.Close();
  
          return true;
  }
  </code></pre>
  
  <p>Here is the Encrypt method:</p>
  
  <pre><code>public static byte[] encryptStringPKCS7(string toEncrypt, List&lt;byte[]&gt; recipients)
      {
          // get bytes from encrypt text
          UnicodeEncoding unicode = new UnicodeEncoding();
          byte[] msgBytes = unicode.GetBytes(toEncrypt);
  
          // Create the certificate collection of the intended recipients
          X509Certificate2Collection recipientsCollection = new X509Certificate2Collection();
          foreach (byte[] currCertificate in recipients)
          {
              recipientsCollection.Add(new X509Certificate2(currCertificate));
          }
  
          //  Place message in a ContentInfo object.
          ContentInfo contentInfo = new ContentInfo(msgBytes);
          EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);
  
          //  Formulate a CmsRecipientCollection object that
          //  represents information about the set of recipients 
          //  to encrypt the message for.
          CmsRecipientCollection cmsRecipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, recipientsCollection);
  
          //  Encrypt the message for the collection of recipients.
          envelopedCms.Encrypt(cmsRecipients);            
          return envelopedCms.Encode();
      }
  </code></pre>
  
  <p>Here is the Decrypt method:</p>
  
  <pre><code>public static string decryptStringPKCS7(byte[] toDecrypt)
      {
          // Place message in a ContentInfo object.
          // This is required to build an EnvelopedCms object.
          EnvelopedCms envelopedCms = new EnvelopedCms();            
  
          // Decrypt the message
          envelopedCms.Decode(toDecrypt);
          envelopedCms.Decrypt();
          byte[] msgDecrypted = envelopedCms.ContentInfo.Content;
  
          // Decode
          string msgClearText = Encoding.Unicode.GetString(msgDecrypted);
          return msgClearText;
      }
  </code></pre>
  
  <p>When I use exactly the same code with a certificate I created with makecert.exe - it works well.
  The makecert command line I use is: <code>makecert.exe -sr LocalMachine -ss My -n CN=[SomeDN] -sk [SomeRandomGUID] -sky exchange</code></p>
  
  <p>Do I need to specify some extra parameters in the creation of the CngKey or the Certificate?
  Or maybe pass in some extra info during Encrypt?</p>
  
  <p>Thanks in advance for any help!</p>