3

I would like to use CryptoAPI in C# to access certificate store and sign message.

This MSDN article "CAPICOM: CryptoAPI Made Easy" shows 2 way to do that: using CAPICOM or P/Invoke.

  1. Which is best? CAPICOM.dll or P/Invoke [DllImport("crypt32.dll", ...)]

  2. Will "crypt32.dll" always be present on any machine?

p.campbell
  • 98,673
  • 67
  • 256
  • 322
Cobaia
  • 1,503
  • 3
  • 22
  • 41
  • Cobaia, welcome to SO. Please rephrase your question into an actual question. This is a high quality Q&A site so I would hate to see your question closed. –  Jul 28 '11 at 14:17
  • I tried to amend the wording. – Cobaia Jul 28 '11 at 14:20

3 Answers3

4

CAPICOM is an old technology that has/is being deprecated by Microsoft. P/Invoke (Platform Invoke) allows managed code to call unmanaged code that are implemented in a DLL.

It is a COM-based wrapper for the CryptoAPI library. The article you posted is from 2003. That was over 8 years ago and technology has moved on.

This article at MSDN here recommends you use the .NET framework for security features in lieu of CAPICOM.

  • thanks, I will use P/Invoke. I found an article mapping out the crypt32 methods to C# http://blogs.msdn.com/b/alejacma/archive/2007/11/23/p-invoking-cryptoapi-in-net-c-version.aspx – Cobaia Jul 28 '11 at 14:40
1

crypt32's availablility shouldn't oppose a problem, while capicom's does.

On the same note though, you should make sure there's no managed wrapper in .Net before heading to p\invoke

sternr
  • 6,216
  • 9
  • 39
  • 63
  • I have to get certificate from certificate store, but I can only use the key if it is exportable. So I will use cryptAPI. Thanks – Cobaia Jul 28 '11 at 14:43
1

Is using CAPICOM a requirement ? It will work but is has a couple of really annoying downside and, if you don't /have/ to use it, you'd be better using System.Security.Cryptography.

Anyway: To use CAPICOM, you must first add a reference to it in your project. Then:

    CAPICOM.SignedData signeddata = new CAPICOM.SignedData();
    FileStream file = File.Open(tbSourceFile.Text, FileMode.Open);
    byte[] Content = new byte[(int)file.Length];

    file.Read(Content, 0, (int)file.Length);
    file.Close();

    StringWriter sw = new StringWriter();
    sw.Write(Content);

    signeddata.Content = sw.ToString();

    IStore store = new CAPICOM.Store();
    store.Open(CAPICOM.CAPICOM_STORE_LOCATION.CAPICOM_CURRENT_USER_STORE, "MY", CAPICOM.CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_READ_ONLY | CAPICOM.CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_EXISTING_ONLY);
    ICertificates2 certificates = (ICertificates2)store.Certificates;

    certificates = certificates.Find(CAPICOM_CERTIFICATE_FIND_TYPE.CAPICOM_CERTIFICATE_FIND_KEY_USAGE, CAPICOM_KEY_USAGE.CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE, true);

    if (certificates.Count > 0)
    {
        certificates = certificates.Select();
    }
    if (certificates.Count > 0)
    {
        ISigner2 signers = new CAPICOM.Signer();
        signers.Certificate = certificates[1];
        tbSignatureBlock.Text = signeddata.Sign(signers, true);
    }
Stephane
  • 3,173
  • 3
  • 29
  • 42