我正在数字地签署XML文档。这是我的代码:
private void mbSign_Click_1(object sender, EventArgs e)
{
try
{
CadesSignature cs = new CadesSignature(FStrDSCSNo);
cs.DigitalSignatureCertificate = DigitalCertificate.LoadCertificate(false, string.Empty, "Select Certificate", "Select the certificate for digital signature");
RSACryptoServiceProvider rsaEncryptor = (RSACryptoServiceProvider)cs.DigitalSignatureCertificate.PrivateKey;
L_ADSC_ValidTo = cs.DigitalSignatureCertificate.NotAfter.ToShortDateString();
if (DateTime.Now <= DateTime.ParseExact(L_ADSC_ValidTo, "dd/MM/yyyy", null))
{
FObjLog.WriteToLog("Valid DSC");
L_ADSC_CertStatus = "A";
// Sign the XML document.
//DataTable dt_SignXMlAndSignaute = new DataTable();
SignXml(rsaEncryptor);
}
}
catch (CryptographicException)
{
MessageBox.Show("Invalid DSC Selection.Please Choose Correct DSC");
FObjLog.WriteToLog("Invalid DSC Selection.Please Choose Correct DSC");
}
catch (NullReferenceException)
{
MessageBox.Show("Please Attach DSC");
FObjLog.WriteToLog("Please Attach DSC");
}
}
public void SignXml(RSA Key)
{
XmlDocument LXMLDoc = new XmlDocument();
if (File.Exists(LXMLPath))
{
LXMLDoc.Load(LXMLPath);
}
if (LXMLDoc == null)
throw new ArgumentException("LXMLDoc");
if (Key == null)
throw new ArgumentException("Key");
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(LXMLDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Create a reference to be signed.
Reference reference = new Reference();
//reference.Uri = txtfilepath.Text;
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env); // calculating Digest value
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue((RSA)Key));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
string FullSignatureValue = "";
string SignatureValue = "";
XmlElement xmlDigitalSignature = signedXml.GetXml();
FullSignatureValue = xmlDigitalSignature.InnerText;
string[] Sign = FullSignatureValue.Split(new char[] { '=' }, 2);
SignatureValue = Sign[1].ToString();
signedXml = new SignedXml(LXMLDoc);
LXMLDoc.DocumentElement.AppendChild(LXMLDoc.ImportNode(xmlDigitalSignature, true));
}
在这里,我可以签署文档,但是我无法在签名时检查USB令牌。这里发生的事情是,即使未连接USB令牌,证书将弹出以进行选择,因为该证书在本地可用。当您从Internet Explorer中删除所有证书并尝试使用未连接的USB代币签名,则它要求附加DSC卡(USB令牌(。我只想在附加DSC(USB令牌(时才签署文档。我如何确保在签名时附加USB?
cryptoapi和CNG系统接口(和使用这些接口的.NET类(提供高级抽象,这些抽象不允许您检查硬件。如果您使用PKCS#11接口,则可以实现所需的目标。但是,PKCS#11也有缺点。
cryptoapi和cng不揭示卡片状态信息,因为您想要winscard。特别是您要致电scardgetStatuschange。
private void WaitChangeStatus(object sender, DoWorkEventArgs e)
{
while (!e.Cancel)
{
SmartCardErrorCode result;
// Obtain a lock when we use the context pointer, which may be modified in the Dispose() method.
lock (this)
{
if (!this.HasContext)
{
return;
}
// This thread will be executed every 1000ms.
// The thread also blocks for 1000ms, meaning
// that the application may keep on running for
// one extra second after the user has closed the Main Form.
result = (SmartCardErrorCode)UnsafeNativeMethods.GetStatusChange(this.context, 1000, this.states, (uint)this.states.Length);
}
if ((result == SmartCardErrorCode.Timeout))
{
// Time out has passed, but there is no new info. Just go on with the loop
continue;
}
else if (result != SmartCardErrorCode.Succeeed)
{
// TODO OnExceptionRaised
continue;
}
for (int i = 0; i <= this.states.Length - 1; i++)
{
// Check if the state changed from the last time.
if ((this.states[i].EventState & CardState.Changed) == CardState.Changed)
{
// Check what changed.
SmartCardState state = SmartCardState.None;
if ((this.states[i].EventState & CardState.Present) == CardState.Present
&& (this.states[i].CurrentState & CardState.Present) != CardState.Present)
{
// The card was inserted.
state = SmartCardState.Inserted;
}
else if ((this.states[i].EventState & CardState.Empty) == CardState.Empty
&& (this.states[i].CurrentState & CardState.Empty) != CardState.Empty)
{
// The card was ejected.
state = SmartCardState.Ejected;
}
if (state != SmartCardState.None && this.states[i].CurrentState != CardState.Unaware)
{
SmartCardEventArgs args = new SmartCardEventArgs();
args.Manager = this;
switch(state)
{
case SmartCardState.Inserted:
{
// Checa o ATR para monitorar apenas DESFire EV1
if (OnCardInserted != null)
{
// Obtém o ATR
byte[] atr = this.GetAtr(this.states[i].ATRBytes, this.states[i].ATRLength);
// Cria SmartCard object and associa ao EventArgs
SmartCard card = new SmartCard(atr);
args.Card = card;
// Dispara Evento
OnCardInserted(this, args);
}
break;
}
case SmartCardState.Ejected:
{
if (OnCardRemoved != null)
{
OnCardRemoved(this, args);
}
break;
}
default:
{
// TODO Log
// Null to force Garbage Collection
args = null;
break;
}
}
}
//Update the current state for the next time they are checked.
this.states[i].CurrentState = this.states[i].EventState;
}
}
}
}