脚踏实地,一步一个脚印,前进......

不抛弃,不放弃

导航

数字签名的简单实现

  static void Main(string[] args)
  {
   //
   // TODO: 在此处添加代码以启动应用程序
   //
   string sFilePath =@"c:\kevin.txt";
   //在c盘下创建一个用于测试的文挡;
   StreamWriter sw = File.CreateText(sFilePath);
   //在新创建的文挡下插入测试数据
   sw.Write("Hi,This is a test Document!");
   //关闭写流
   sw.Close();

   //转换文挡成哈希数组
   byte[] bHash = GetFileHash(sFilePath);

   //生成公钥
   string sPublicKey = GetKeyFromName("测试",false);
   //生成私钥
   string sPrivateKey =GetKeyFromName("测试",true);

   Console.WriteLine("发送方为:A");
   Console.Write("电子文件路径为:");
   Console.WriteLine(sFilePath);

   Console.Write("电子文件转换后的哈希值:");
   Console.WriteLine(TransformByteToString(bHash));

   Console.Write("生成的私钥:");
   Console.WriteLine(sPrivateKey);
   //用私钥生成数字签名
   byte[] bDigiol = EncryptHash(sPrivateKey,bHash);
   Console.Write("生成的数字签名为:");
   Console.WriteLine(GetString(bDigiol));

   Console.WriteLine("接收方接受数据:");
   string sFileCopyPath = @"c:\KevinCopy.txt";
   File.Copy(sFilePath,sFileCopyPath,true);

   Console.WriteLine("是否同意篡改文件?");
   string sChange =string.Empty;
   byte[] bGetHash=null;
   do
   {
    sChange =Console.ReadLine();
   }while(sChange!="Y" && sChange !="N");
   if(sChange =="N")
   {
    Console.WriteLine("接收方开始接收数据.....");
    Console.WriteLine("接收方:B");
    Console.Write("接收文件存放地址:");
    Console.WriteLine(sFileCopyPath);
    bGetHash =GetFileHash(sFileCopyPath);
    Console.Write("转换后的哈希值:");
    Console.WriteLine(GetString(bGetHash));
   }
   else if(sChange=="Y")
   {
    Console.WriteLine("正在篡改文件.....");
    StreamWriter sws = new StreamWriter(sFileCopyPath);
    sws.WriteLine("this documeny have been modified!");
    sws.Close();
    Console.WriteLine("接收方开始接收数据.....");
    Console.WriteLine("接收方:B");
    Console.Write("接收文件存放地址:");
    Console.WriteLine(sFileCopyPath);
    bGetHash =GetFileHash(sFileCopyPath);
    Console.Write("转换后的哈希值:");
    Console.WriteLine(GetString(bGetHash));
   }
   Console.Write("生成的公钥:");
   Console.WriteLine(sPublicKey);
   //使用公钥进行验证
   if(DecryptHash(sPublicKey,bGetHash,bDigiol))
   {
    Console.WriteLine("验证成功,该文件没有被篡改!");
   }
   else
   {
    Console.WriteLine("验证失败,文件已被篡改!");
   }
   Console.ReadLine();


  }

  /// <summary>
  /// 用于把文件用MD5进行加密,返回文件的哈希值
  /// </summary>
  /// <param name="sFilePath">文件的路径</param>
  /// <returns>文件的哈希值</returns>
  public static byte[] GetFileHash(string sFilePath)
  {
   try
   {
    //根据文件路径读取文件,得到一个FileStream流
    FileStream fStream =File.OpenRead(sFilePath); 
    //生成MD5加密器
    System.Security.Cryptography.HashAlgorithm hMD5Th = System.Security.Cryptography.HashAlgorithm.Create("MD5");
    //用MD5加密器加密文件,得到哈希字节数组
    byte[] bFileByte = hMD5Th.ComputeHash(fStream);
    //关闭读取文件流
    fStream.Close();
    //返回哈希数组
    return bFileByte;
   }
    //异常处理
   catch(System.IO.IOException ex)
   {
    Console.WriteLine("When thrasaction has Error: "+ ex.Message);
    return null;
   }
  }
  /// <summary>
  /// 用于把Byte数组转换成string字符串
  /// </summary>
  /// <param name="bByTransform">用于转换的Byte数组</param>
  /// <returns>转换后的字符串</returns>
  public static string TransformByteToString(byte[] bByTransform)
  {
   //用于串联各个字节转成的字符
   System.Text.StringBuilder sbData =new System.Text.StringBuilder();
   if(bByTransform !=null && bByTransform.Length >0)
   {
    foreach(byte b in bByTransform)
    {
     sbData.Append(b.ToString("X"));
    }
   }
   return sbData.ToString();
  }

  /// <summary>
  /// 转化Byte数组
  /// </summary>
  /// <param name="bBytes">用于转换的Byte数组</param>
  /// <returns>转换后的字符串</returns>
  public static string GetString(byte[] bBytes)
  {
   if(bBytes!=null && bBytes.Length>0)
   {
    //转化字节数组
    return BitConverter.ToString(bBytes);
   }
   else
   {
    return "";
   }
  }

  /// <summary>
  /// 生成公钥或者私钥
  /// </summary>
  /// <param name="sName">如果生成的是私钥,则提供私钥的名称</param>
  /// <param name="blKeyType">确定生成私钥或者公钥,True为私钥,False为公钥</param>
  /// <returns>生成的密钥</returns>
  public static string GetKeyFromName(string sName,bool blKeyType)
  {
   //参数容器
   System.Security.Cryptography.CspParameters cp = new System.Security.Cryptography.CspParameters();
   //提供的参数
   cp.KeyContainerName =sName;
   System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(cp);
   return RSA.ToXmlString(blKeyType);
  }

  /// <summary>
  /// 对文件转换后的哈希数组生成数字签名
  /// </summary>
  /// <param name="sPrivateKeyName">提供的私钥名称</param>
  /// <param name="bFileBytes">用于设置的文件哈希数组</param>
  /// <returns>哈希数组生成的数字签名</returns>
  public static byte[] EncryptHash(string sPrivateKeyName,byte[] bFileBytes)
  {
   //实例化加密服务提供程序
   System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
   //通过指定的私钥重构加密服务提供程序
   RSA.FromXmlString(sPrivateKeyName);
   //创建RSAPKCS1.5版的数字签名实例
   System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormater = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA);
   //设置用MD5加密算法进行签名
   RSAFormater.SetHashAlgorithm("MD5");

   return RSAFormater.CreateSignature(bFileBytes);
  }

  /// <summary>
  /// 对数据签名用公钥进行验证
  /// </summary>
  /// <param name="sPublicKey">用于验证的公钥</param>
  /// <param name="bFileBytes">要验证的文件哈希</param>
  /// <param name="electronicSignature">要验证的数据签名</param>
  /// <returns>是否验证成功</returns>
  public static bool DecryptHash(string sPublicKey,byte[] bFileBytes,byte[] electronicSignature)
  {
   //实例化加密服务提供程序
   System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
   //通过指定的公钥重构加密服务提供程序
   RSA.FromXmlString(sPublicKey);
   //验证RSAPKCS1.5版的数字签名实例
   System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter  = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
   ////设置用MD5加密算法进行验证
   RSADeformatter.SetHashAlgorithm("MD5");
   return RSADeformatter.VerifySignature(bFileBytes,electronicSignature);
  }

posted on 2008-08-14 08:43  沉默的人  阅读(598)  评论(1编辑  收藏  举报