title: Bouncy Castle Smart Card Certificate
body: <p>I work on win 7 professional and c#(VS2010).I need to sign a file and create a PKCS envelope.<br>
  The certificate to use for sign is on a USB smart card (I installed the crypto service provider CSP provided with the smart card).<br>
  This is the code that I wrote using bouncy Castle</p>
  
  <pre><code>private byte[] SignData(byte[] DataTosign)
  {
      X509Certificate2 card = GetCertificate();
      Org.BouncyCastle.X509.X509Certificate cert = DotNetUtilities.FromX509Certificate(card);
  
      Org.BouncyCastle.Crypto.AsymmetricKeyParameter K = DotNetUtilities.GetKeyPair(card.PrivateKey).Private;
  
      CmsSignedDataGenerator generator = new CmsSignedDataGenerator();
      generator.AddSigner(K, cert, CmsSignedDataGenerator.EncryptionRsa, CmsSignedDataGenerator.DigestSha1);
  
      ArrayList certList = new ArrayList();
      certList.Add(cert);
  
      Org.BouncyCastle.X509.Store.X509CollectionStoreParameters PP = new Org.BouncyCastle.X509.Store.X509CollectionStoreParameters(certList);
      Org.BouncyCastle.X509.Store.IX509Store st1 = Org.BouncyCastle.X509.Store.X509StoreFactory.Create("CERTIFICATE/COLLECTION", PP);
  
      generator.AddCertificates(st1);
  
      CmsSignedData signedData = generator.Generate("1.2.840.113549.1.7.1", new CmsProcessableByteArray(DataTosign), true);  // &lt;- here is the flag
  
      return signedData.GetEncoded();
  }
  
  
  public static X509Certificate2 GetCertificate()
  {
      X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
      st.Open(OpenFlags.ReadOnly);
      X509Certificate2Collection col = st.Certificates;
      X509Certificate2 card = null;
      X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(col, "Certificates", "Select one to sign", X509SelectionFlag.SingleSelection);
      if (sel.Count &gt; 0)
      {
          X509Certificate2Enumerator en = sel.GetEnumerator();
          en.MoveNext();
          card = en.Current;
      }
      st.Close();
      return card;
  }
  </code></pre>
  
  <p>The problem is in <code>Org.BouncyCastle.Crypto.AsymmetricKeyParameter K = DotNetUtilities.GetKeyPair(card.PrivateKey).Private;</code>
  where I get an</p>
  
  <blockquote>
    <p>System.Security.Cryptography.CryptographicException(Message Specified type is not valid)</p>
  </blockquote>
  
  <p>It seems the problem is that the privatekey is on the smart card, but to use generator.AddSigner, I must pass the privatekey. Can someone help me on how to sign with a certificate on a smart card?</p>
  
  <p>Many thanks!</p>