C#实现数字签名
- using System;
- using System.Collections.Generic;
- using System.Windows.Forms;
- using System.Security.Cryptography;
- namespace DSAExample
- {
- public partial class MainForm : Form
- {
- byte[] hashValue;
- byte[] signedHashValue;
- DSAParameters dsaKeyInfo;
- public MainForm()
- {
- InitializeComponent();
- }
- private void buttonOK_Click(object sender, EventArgs e)
- {
- try
- {
- DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
- //随机生成20个Hash值(这里并没有具体实现hash运算功能)
- List<byte> list = new List<byte>();
- Random r = new Random();
- for (int i = 0; i < 20; i++)
- {
- list.Add((byte)r.Next(255));
- }
- hashValue = list.ToArray();//将List对象转换成数组
- //导出公钥和私钥
- dsaKeyInfo = dsa.ExportParameters(true);
- //得到签名的Hash值
- signedHashValue = DSASignHash(hashValue, dsaKeyInfo, "SHA1");
- //此处应该将hashValue、signedHashValue以及公钥发
- //送给接收方。为简化起见,这里仅将Hash和签名的Hash显示出来
- textBoxHashValue.Text = GetHashString(hashValue);
- textBoxVerifyHashValue.Text = GetHashString(signedHashValue);
- }
- catch (ArgumentNullException err)
- {
- MessageBox.Show(err.Message);
- }
- }
- /// <summary>
- /// 根据哈希值拼接字符串
- /// </summary>
- /// <param name="bytes">哈希值</param>
- /// <returns>拼接的字符串</returns>
- private string GetHashString(byte[] bytes)
- {
- string s = "";
- for (int i = 0; i < bytes.Length; i++)
- {
- s += bytes[i].ToString() + ",";
- }
- s = s.TrimEnd(',');//删除最后的“,”
- return s;
- }
- /// <summary>
- /// 使用DSA算法签名哈希值
- /// </summary>
- /// <param name="HashToSign">要被签名的哈希值</param>
- /// <param name="dsaKeyInfo">DSA密钥信息</param>
- /// <param name="HashAlg">指定哈希算法</param>
- /// <returns>签名后的结果</returns>
- private byte[] DSASignHash(byte[] HashToSign, DSAParameters dsaKeyInfo, string HashAlg)
- {
- try
- {
- DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
- dsa.ImportParameters(dsaKeyInfo);
- DSASignatureFormatter DSAFormatter = new DSASignatureFormatter(dsa);//创建格式化数字签名对象
- DSAFormatter.SetHashAlgorithm(HashAlg);//设置hash算法
- return DSAFormatter.CreateSignature(HashToSign);//创建数字签名(即加密后且经过了hash运算的字符串)
- }
- //注意:数据进行hash运算成为了哈希值(简称哈希值一),哈希值再经过密钥加密则变成了数字签名
- //数字签名经过公钥解密后又变回成了哈希值(简称哈希值二)
- //如果哈希值一和哈希值二相等,说明数据签名是完整的,而且可以确定该消息是由持有该数字签名的私钥的人发送的。
- catch (CryptographicException err)
- {
- MessageBox.Show(err.Message);
- return null;
- }
- }
- private void buttonVerify_Click(object sender, EventArgs e)
- {
- //为简化起见,此处假定接收方已经接收到发
- //送方发送的hashValue、signedHashValue以及公钥
- //同时保证接收方和签名方使用相同的哈希算法(均为“SHA1”)
- try
- {
- DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
- dsa.ImportParameters(dsaKeyInfo);
- DSASignatureDeformatter DSADeformatter = new DSASignatureDeformatter(dsa);//生成反格式化(Deformatter)数字签名对象
- DSADeformatter.SetHashAlgorithm("SHA1");
- if (DSADeformatter.VerifySignature(hashValue, signedHashValue))
- {
- textBoxVerifyResult.Text = "验证成功";
- }
- else
- {
- textBoxVerifyResult.Text = "验证失败";
- }
- }
- catch (CryptographicException err)
- {
- MessageBox.Show(err.Message);
- }
- }
- }
- }
界面设置: