CAPICOM vs P/Invoke
I开发者_如何学Go 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.
Which is best? CAPICOM.dll or P/Invoke
[DllImport("crypt32.dll", ...)]
Will "crypt32.dll" always be present on any machine?
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.
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
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);
}
精彩评论