微软提供的CAPICOM.dll可以操作数字证书进行签名,但是MSDN中对他的描述是使用.NET的对应类库替代。结果试了很多次,两个API的结果不同。
以下是COM方式(引用CAPICOM.dll 2.1 COM组件)ICertificate2 certificate = null;Store myStore = new StoreClass();
myStore.Open(CAPICOM_STORE_LOCATION.CAPICOM_CURRENT_USER_STORE,
    "My", CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_READ_WRITE);
ICertificates myStoreCerts = myStore.Certificates;
for (int i = 1; i <= myStoreCerts.Count; i++)
{
    ICertificate2 cert = myStoreCerts[i] as ICertificate2;
    if (cert.SerialNumber.IndexOf("AF") > 0)
    {
        certificate = cert;
        break;
    }
}
Console.WriteLine(certificate.SubjectName);// 开始签名
if (certificate.HasPrivateKey() == false)
{
    Console.WriteLine("没有私钥");
    return;
}ISignedData signedData = new SignedDataClass();
signedData.Content = "hello";
var signer = new SignerClass();
signer.Certificate = certificate;
string signedResult = signedData.Sign(signer, false, CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64);
string certificateBase64 = certificate.Export(CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64);
Console.WriteLine(signedResult.Replace("\r", "").Replace("\n", ""));以下是对应的.NET方式:X509Certificate2 dotNetCertificate = null;
X509Store dotNetStore = new X509Store(StoreLocation.CurrentUser);
dotNetStore.Open(OpenFlags.ReadWrite);
for (int i = 0; i < dotNetStore.Certificates.Count; i++)
{
    if (dotNetStore.Certificates[i].SerialNumber.IndexOf("AF") > 0)
    {
        dotNetCertificate = dotNetStore.Certificates[i];
    }
}if (dotNetCertificate.HasPrivateKey == false)
{
    Console.WriteLine("没有私钥");
    return;
}SignedCms dotNetSignedData = new SignedCms(new ContentInfo(Encoding.ASCII.GetBytes("hello")), false);
CmsSigner dotNetSigner = new CmsSigner(dotNetCertificate);
dotNetSignedData.ComputeSignature(dotNetSigner);
Console.WriteLine(Convert.ToBase64String(dotNetSignedData.Encode()));结果是两个签名结果不同…………折腾了一天了
求救。