【问题标题】:How to check if the DSC (USB token) is attached while signing the document?签署文件时如何检查是否附加了 DSC(USB 令牌)?
【发布时间】:2017-09-13 23:20:07
【问题描述】:

我正在对 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?

【问题讨论】:

    标签: c# cryptography digital-signature signing digital-certificate


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-27
        • 1970-01-01
        • 1970-01-01
        • 2021-10-31
        • 1970-01-01
        • 2018-03-24
        • 2021-06-17
        • 2016-12-02
        相关资源
        最近更新 更多