覆盖 X509Certificate2 PIN 行为

Override X509Certificate2 PIN behaviour

我正在尝试使用智能卡设备同时执行 3 种类型的数字签名 (SHA256),XML、PDF 和文本。所有签名都运行良好,但问题是,每次签名时都要求输入 PIN,但我只需要询问一次。谁能建议一个更好的方法来实现这个结果?

我要实现的是,

Ask pin -> Sign XML -> Sign PDF -> Sign TEXT

发生的事情是,

Ask pin -> Sign XML -> Ask pin -> Sign PDF -> Ask pin -> Sign TEXT

然后我为 PDF 和 TEXT 签名创建了一个通用 cmssiger 对象。

现在发生的事情是,

Ask pin -> Sign XML -> Ask pin -> Sign PDF -> Sign TEXT

希望大家明白我在说什么

每个签名过程的代码如下, XML

XAdESSignedXml signer = new XAdESSignedXml(toSign);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa = cert.PrivateKey as RSACryptoServiceProvider;
signer.SigningKey = rsa;
/*.......Elements attached......*/
signer.ComputeSignature();

PDF

private byte[] SignMsg(Byte[] msg, bool detached)
{
    ContentInfo contentInfo = new ContentInfo(msg);
    SignedCms signedCms = new SignedCms(contentInfo, detached);
    _cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;//common cmssigner object
    _cmsSigner.DigestAlgorithm.FriendlyName = "SHA256";
    signedCms.ComputeSignature(_cmsSigner, false);
    byte[] bb = signedCms.Encode();
    CmsSignedData sd = new CmsSignedData(bb);
    SignerInformationStore signers = sd.GetSignerInfos();
    byte[] signature = null;
    SignerInformation signer = null;
    foreach (SignerInformation signer_ in signers.GetSigners())
    {
        signer = signer_;
        break;
    }
    signature = signer.GetSignature();
    signer = SignerInformation.ReplaceUnsignedAttributes(signer, null);
    IList signerInfos = new ArrayList();
    signerInfos.Add(signer);
    sd = CmsSignedData.ReplaceSigners(sd, new SignerInformationStore(signerInfos));
    bb = sd.GetEncoded();
    return bb;
}

文本

public static string Sign(string msg, CmsSigner cmsSigner) //common cmssigner object
{
    SHA256Managed crypt = new SHA256Managed();
    string hash = String.Empty;
    byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(msg), 0, Encoding.UTF8.GetByteCount(msg));
    foreach (byte theByte in crypto)
    {
        hash += theByte.ToString("x2");
    }
    ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(hash));
    SignedCms cms = new SignedCms(contentInfo);
    cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
    cmsSigner.DigestAlgorithm.FriendlyName = "SHA256";
    cms.ComputeSignature(cmsSigner, false);
    return Convert.ToBase64String(cms.Encode());
}

提前致谢。

Pin 提示行为是提供商特定的实现细节。换句话说,一个加密服务提供商/密钥存储提供商将以一种方式行事,而另一个将以另一种方式行事。

为了减少 pin 提示的机会,您将希望对所有操作使用一个会话,听起来您正在这样做,但又回到了特定于提供商的行为。

在 RSACryptoServiceProvider 的情况下,可以生成并存储密钥,从而强制执行使用中的 pin 提示策略。这实际上是它公开的唯一 pin 提示行为,因此您坚持使用此类键观察到的行为。