我正在尝试使用智能卡设备一次执行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());
}
提前致谢。
答案 0 :(得分:0)
Pin prompt behavior is a provider specific implementation detail. In other words, one cryptographic service provider / key storage provider will behave one way while another will behave another.
To reduce chances of pin prompting you will want to use one session for all operations, it sounds like you are doing that though so were back to the provider-specific behavior.
In the case of RSACryptoServiceProvider a key can be generated and stored in such a way it enforces an on-use pin prompt policy. This is really the only pin prompt behavior it exposes, as such your stuck with the observed behavior with such keys.