sign3

/// <summary>
  /// authenticate user's certificate whether is published by Organization ca center
  /// </summary>
  /// <param name="sUserCertName">certificate issue name</param>
  /// <param name="sCertSerialNum">certificate serial number</param>
  /// <returns></returns>
  private static bool Authenticate(string sUserCertName, string sCertSerialNum)
  {
   try
   {
    ESignDMZ.ESignDMZ esign = new ESignDMZ.ESignDMZ();
    esign.Credentials = new System.Net.NetworkCredential(
     "ws_access",
     "access.ws+itec");
    return esign.AuthenticateUserInfoByCertNameAndSerialnumber(sUserCertName, sCertSerialNum);

   }
   catch(System.Exception ex)
   {
    throw ex;
   }
  }

  #region about Cert
  /// <summary>
  /// 下載憑證
  /// </summary>
  /// <param name="sUserNo">用戶帳號(內部)</param>
  /// <param name="sPwd">密碼</param>
  /// <returns>bool</returns>
  internal static bool downCert(string sUserNo, string sPwd)
  {
   bool bDown = false;
   try
   {
    OrganizationCaAuthority.Authority caAuthority = new Com.Organization.Ca.Esign.OrganizationCaAuthority.Authority();

    string enPwd = Encrypt(sPwd, "x10ngmao");
    string strCert = caAuthority.GetCertBodyByUserNoAndPwd(sUserNo, enPwd, "OrganizationCAPaSs");

    byte[] MyData = new byte[0];
    string certPwd = string.Empty;
    string certName = string.Empty;
    if (strCert.Length > 0)
    {
     string[] certData = strCert.Split('^');
     certPwd = Decrypt(certData[0].ToString(), "x10ngmao");
     MyData = Convert.FromBase64String(certData[1]);
     certName = certData[2].ToString();
     bool bInstall = installCertBody(certName, MyData, certPwd);
     if (bInstall)
     { bDown = true;}
    }
   }
   catch (Exception ex)
   {
    string hmi = ex.Message;               
   }
   return bDown;           
  }

  /// <summary>
  /// 安裝憑證,並刪除原憑證
  /// </summary>
  /// <param name="pName">憑證用戶姓名</param>
  /// <param name="CertData">憑證數據</param>
  /// <param name="Pwd">憑證密碼</param>
  /// <returns>bool</returns>
  public static bool installCertBody(string pName, byte[] CertData, string Pwd)
  {
   X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
   st.Open(OpenFlags.MaxAllowed);

   X509Certificate2Collection col = st.Certificates;
   for (int i = 0; i <= (col.Count - 1); i++)
   {
    string certPublisher = col[i].GetNameInfo(X509NameType.SimpleName, true);
    string certName = col[i].GetNameInfo(X509NameType.SimpleName, false);

    if ((certPublisher.ToUpper() == "Organization CA") && (certName == pName))
    {
     st.Remove(col[i]);
    }
   }

   X509Certificate2 cert = new X509Certificate2(CertData, Pwd, X509KeyStorageFlags.Exportable);
   st.Add(cert);
   st.Close();
   return true;
  }

  #endregion

  #region Sign and Verify Msg  
  /// <summary>
  /// Sign Msg
  /// </summary>
  /// <param name="msg">Msg</param>
  /// <returns>encodedSigned Msg(return null, Cert not OrganizationCA cert)</returns>
  internal static byte[] SignMsg(Byte[] msg)
  {
   X509Certificate2 card = GetCertificate();
   if (!Authenticate(card.GetNameInfo(X509NameType.SimpleName, false).ToUpper(), card.GetSerialNumberString()))
   { return null; }
   //  Place message in a ContentInfo object.
   //  This is required to build a SignedCms object.
   ContentInfo contentInfo = new ContentInfo(msg);

   //  Instantiate SignedCms object with the ContentInfo above.
   //  Has default SubjectIdentifierType IssuerAndSerialNumber.
   //  Has default Detached property value false, so message is
   //  included in the encoded SignedCms.
   SignedCms signedCms = new SignedCms(contentInfo);

   //  Formulate a CmsSigner object for the signer.
   CmsSigner cmsSigner = new CmsSigner(card);

   //  Sign the CMS/PKCS #7 message.
   //Console.Write("Computing signature with signer subject " + "name {0} ... ", card.SubjectName.Name);
   signedCms.ComputeSignature(cmsSigner);
   //Console.WriteLine("Done.");

   //  Encode the CMS/PKCS #7 message.
   return signedCms.Encode();

  }
       
  //  Verify the encoded SignedCms message and return a Boolean
  //  value that specifies whether the verification was successful.
  /// <summary>
  /// Verify Msg
  /// </summary>
  /// <param name="encodedSignedCms">encodedSigned Msg</param>
  /// <param name="origMsg">orig Msg</param>
  /// <returns>bool</returns>
  internal static bool VerifyMsg(byte[] encodedSignedCms, out string origMsg)
  {
   //  Prepare an object in which to decode and verify.
   SignedCms signedCms = new SignedCms();

   signedCms.Decode(encodedSignedCms);

   //  Catch a verification exception if you want to
   //  advise the message recipient that
   //  security actions might be appropriate.
   try
   {
    //  Verify signature. Do not validate signer
    //  certificate for the purposes of this example.
    //  Note that in a production environment, validating
    //  the signer certificate chain will probably
    //  be necessary.
    string strPublicKey = string.Empty;
    string strSubjectName = string.Empty;

    signedCms.CheckSignature(true);
    foreach (X509Certificate2 card in signedCms.Certificates)
    {
     strSubjectName = card.SubjectName.Name;
     strPublicKey = card.GetPublicKeyString();
     string strThumbprint = card.Thumbprint;
    }
    origMsg = "MsgHashCode=" + System.Text.Encoding.UTF8.GetString(signedCms.ContentInfo.Content) + ",SubjectName=" + strSubjectName + ",PublicKey=" + strPublicKey;
   }
   catch (System.Security.Cryptography.CryptographicException e)
   {
    //Console.WriteLine("VerifyMsg caught exception:  {0}",
    //    e.Message);
    //Console.WriteLine("Verification of the signed PKCS #7 " +
    //    "failed. The message, signatures, or " +
    //    "countersignatures may have been modified " +
    //    "in transit or storage. The message signers or " +
    //    "countersigners may not be who they claim to be. " +
    //    "The message's authenticity or integrity, " +
    //    "or both, are not guaranteed.");
    origMsg = null;
    return false;
   }
   return true;
  }
  #endregion

posted on 2009-01-05 14:54  ChinaLeo  阅读(222)  评论(0)    收藏  举报

导航