覆盖 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 提示行为,因此您坚持使用此类键观察到的行为。
我正在尝试使用智能卡设备同时执行 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();
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 提示行为,因此您坚持使用此类键观察到的行为。