0

我正在数字签署xml文档。这里是我的代码:如何在签署文档时检查DSC(USB令牌)是否已连接?

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?

回答

0

CryptoAPI和CNG系统接口(以及使用这些接口的.NET类)提供了不允许检查硬件的高级抽象。如果你使用PKCS#11接口,那么你可能能够实现你想要的。但是,PKCS#11也有其缺点。

0

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; 
       } 
      } 
     } 
    }