.Net加密与解密——非对称加密之数字签名

  一,从非对称加密的认证模式说起

由消息的发送方发布公钥,持有私钥。

 

步骤:

1,发送方公布自己的公钥,任何人都可以获得。

2,发送方使用自己的私钥对消息进行加密,然后发送。

3,接收方使用发送方的公钥对消息进行解密。

 

 

缺点:

1,任何截获该消息的第三方都能够使用发送方公钥进行解密;

2,耗时,不适用于大数据

  二,数字签名

      过程:


1,发送方对想要传递的消息进行散列运算,得到原始消息摘要。(摘要可以代表消息本身,相当于指纹)

2,发送方使用自己的私钥只对消息摘要进行加密,该过程也称作签名。将消息和加密后的摘要发送给接收方。由于摘要非常小,因此次采用非对称加密运算速度也很快。

3,接收方使用发送方的公钥对消息摘要进行解密,确认了发送方,并得到原始消息摘要。接收方对收到的消息进行散列运算,得到一个本地消息摘要。

4,接收方对比原始的消息摘要和本地消息摘要。如果相同,说明消息没有被改动过;如果不同,说明消息已经被改动过;

  优点:

          1,解决了非对称加密中认证模式比较耗时间的问题。

       

 缺点:

  1,只对摘要进行了加密,并未对消息进行加密,一旦被截获,即可查看该消息。

三,数字签名Demo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace 数字签名
{
    class Program
    {
        static void Main(string[] args)
        {
            //发送方
            string plainTest = "hello world";
            string privateKey = "<RSAKeyValue><Modulus>qA89WuhLCmvYHJqw+mfjRZ6Ep8xuicvRkVWkuufRHBAmLgXt2lHThSSBsZhFEECHqvwGFF+OybGj1Ki72A3h056tM6yRNppJFaJGGrnsjsWPPNa14E6f+ZBvC/MZRISLGNTDxhbHuvNSMx+hLU+Skz+B75RCMoYuEOuP8GxFEqs=</Modulus><Exponent>AQAB</Exponent><P>7VxYssHAiMZtnVzgK3h3U9llNZSa5MCK4/iLvATQ5h3+yHegT0t+q2Tv844QUxcBPvkkrF+uvSb043Nw65KoTw==</P><Q>tUG739ddGWVrsBxle1ZmuABVBzeUNUiCOsbcGP/LsmbScdnk46rIfjVZ3NGlfptbAv4I7MPatr8Je1O5GL485Q==</Q><DP>ZyFXnJuYhxUILXZcJCccWb88PVKLFlceQb0NIa1KAqIHwJxReAKKT/f0VfNk3mVBclYX/Bk6uA7EGktfRcub+w==</DP><DQ>rLubBiNgBo6/hFJbZ6GcPCec4EbYB7s02DygjXZfsYEJdhQ3a7taW+QN4kEsHK6CmiRrbu7qpJMDvzK3R1wr/Q==</DQ><InverseQ>a0q3ffhjSHdaZW0QrkqZNUNSQ+j5/ltPS9zaJQiVhO2abaYaGwKaVVsbuD7cB+i4EasAw4uQHrk456Vkw/HQnw==</InverseQ><D>DyXIfvAfC2JrCTD8MKW6e2TtSf6IHA1t5y6T+XC5jVD7T/yi0qG7ce23bt1tpChc0hGDLsTqJs3HGXzX6YJez0Frz37UuNNsNyrhh3cAnxQuAwaCZMF7tPYOQbmgXP5OFpgaIjUmhMwysmm9WdrTocE6h39t5QlLy7g6xH9MJ+k=</D></RSAKeyValue>";//这里的key均由provider产生的
            string signedDigest = RSACryptoHelper.SignData(plainTest, privateKey);
            Console.Write(signedDigest);
            Console.WriteLine();

            //接收方
            string publicKey = "<RSAKeyValue><Modulus>qA89WuhLCmvYHJqw+mfjRZ6Ep8xuicvRkVWkuufRHBAmLgXt2lHThSSBsZhFEECHqvwGFF+OybGj1Ki72A3h056tM6yRNppJFaJGGrnsjsWPPNa14E6f+ZBvC/MZRISLGNTDxhbHuvNSMx+hLU+Skz+B75RCMoYuEOuP8GxFEqs=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
            bool isCorrect = RSACryptoHelper.VerifyData(plainTest, signedDigest, publicKey);
            Console.Write(isCorrect);
            Console.ReadKey();

        }
    }

    /// <summary>
    /// Class RSACryptoHelper
    /// </summary>
    /// <remarks>Editor:v-liuhch CreateTime:2015/5/17 19:15:42</remarks>
    public class RSACryptoHelper {

        /*
         RSACryptoServiceProvider

         */
        /// <summary>
        /// 运算摘要,并对摘要进行签名
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="privateKeyXml">私钥.</param>
        /// <returns>System.String.</returns>
        /// <remarks>Editor:v-liuhch CreateTime:2015/5/17 19:11:41</remarks>
        public static string SignData(string plainText, string privateKeyXml) {

            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(privateKeyXml);

            byte[] plainData = Encoding.Default.GetBytes(plainText);

            //设置获取摘要的算法
            HashAlgorithm shal = HashAlgorithm.Create("SHA1");

            //获得签名的过的摘要
            byte[] signedDigest = provider.SignData(plainData, shal);//运算摘要,并对摘要进行签名,并返回签名后的摘要
            return Convert.ToBase64String(signedDigest);

        }

        /// <summary>
        /// Verifies the data.
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="signature">要验证的签名数据.</param>
        /// <param name="publicKeyXml">发送方公钥</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        /// <remarks>Editor:v-liuhch CreateTime:2015/5/17 18:44:36</remarks>
        public static bool VerifyData(string plainText, string signature, string publicKeyXml) {

            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(publicKeyXml);

            byte[] plainData = Encoding.Default.GetBytes(plainText);
            byte[] signedDigest = Convert.FromBase64String(signature);

            HashAlgorithm shal = HashAlgorithm.Create("SHA1");

            /*
                 摘要:
            //     通过将指定的签名数据与为指定数据计算的签名进行比较来验证指定的签名数据。
            //
            // 参数:
            //   buffer:
            //     已签名的数据。
            //
            //   halg:
            //     用于创建数据的哈希值的哈希算法名称。
            //
            //   signature:
            //     要验证的签名数据。
            //
            // 返回结果:
            //     如果签名验证为有效,则为 true;否则,为 false。
             */
            bool isDataIntact = provider.VerifyData(plainData, shal, signedDigest);//用于重新运算消息,得出本地摘要,并解密传递进来的原始摘要,最后对本地摘要和原始摘要进行对比,并返回bool型的结果

            return isDataIntact;

        }

        /// <summary>
        /// Signs the data2.
        /// </summary>
        /// <param name="plainText">The plain text.</param>
        /// <param name="privateKeyXml">The private key XML.</param>
        /// <returns>System.String.</returns>
        /// <remarks>Editor:v-liuhch CreateTime:2015/5/17 19:15:36</remarks>
        public static string SignData2(string plainText, string privateKeyXml) {

            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(privateKeyXml);

            byte[] plainData = Encoding.Default.GetBytes(plainText);

            //设置获取摘要的算法
            HashAlgorithm shal = HashAlgorithm.Create("SHA1");
            //获取原始摘要
            byte[] digestData = shal.ComputeHash(plainData);
            //对原始摘要签名
            byte[] signedDigest = provider.SignHash(digestData, "SHA1");
            return Convert.ToBase64String(signedDigest);

        }

        /// <summary>
        /// Verifies the data2.
        /// </summary>
        /// <param name="plainText">The plain text.</param>
        /// <param name="signedDigest">The signed digest.</param>
        /// <param name="publicKeyXml">The public key XML.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        /// <remarks>Editor:v-liuhch CreateTime:2015/5/17 19:15:33</remarks>
        public static bool VerifyData2(string plainText, string signedDigest, string publicKeyXml) {

            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(publicKeyXml);

            byte[] plainData = Encoding.Default.GetBytes(plainText);
            byte[] signedDigestData = Convert.FromBase64String(signedDigest);

            //获得本地摘要
            HashAlgorithm shal = HashAlgorithm.Create("SHA1");
            byte[] digest = shal.ComputeHash(plainData);

            //解密签名,并判断摘要是否一致
            bool isDataIntact = provider.VerifyHash(digest, "SHA1", signedDigestData);
            return isDataIntact;

        }
    }

}

         

时间: 2024-10-09 06:20:02

.Net加密与解密——非对称加密之数字签名的相关文章

.Net加密与解密——对称加密

   一,思路       对称加密含有一个被称为密钥的东西,在消息发送前使用密钥对消息进行加密,得到密文并发送,接收方收到密文后,使用相同的密钥进行解密,获得原消息.   PS:使用密钥对消息进行加密的过程,由加密算法来完成的,加密算法通常也是公开的. 二,对称加密的流程             1,发送方和接收方持有相同的密钥,并严格保密 2,发送方使用密钥对消息进行加密,然后发送消息 3,接收方收到消息后,使用相同的密钥对消息进行解密 PS:在这一过程中,第三方可能截获消息,但得到的知识一

.NET中的加密类(非对称加密)

using System; using System.IO; using System.Text; using System.Security.Cryptography; namespace APress.ProAspNet.Utility { public static class AsymmetricEncryptionUtility { //生成并保存密钥: public static string GenerateKey(string targetFile) { RSACryptoSer

详解.Net下的加密解密算法(6) 玩转非对称加密

本博文来聊聊怎么玩转非对称加密吧,这里主要介绍.NET算法下的3种非对称加密算法:DSA,RSA,ECDsa.上两篇博文分 别为Hash家族和非对称加密家族找到了lead,现在我们就为非对称加密技术找个合适的lead吧. 首先创建一个接口 :"IEncryptAndDecrypt",然后为上面的3中算法分别创建3个实现类并让这些类实现接口"IEncryptAndDecrypt".它们 的情况如下图: 这下我们把这些哥们都召集起来了,现在我们就给他们找一个lead:&

MySQL字段加密和解密

MySQL字段加密和解密 1.加密:aes_encrypt('admin','key') 解密:aes_decrypt(password,'key') 2.双向加密 通过密钥去加密,解密的时候的只有知道这个密钥的人来解密 加密:encode() 解密:decode() eg:encode('123456' 'adfdgfdhggfh'); decode(password,'adfdgfdhggfh'); 3.PASSWORD('123456') password加密是不可逆转的 4.MD5('1

关于MD5加密与解密

问题描述 在ASP.NET项目如何将已经加密过的密码解密并且实现用户登陆 解决方案 解决方案二:不用解密.把用户输入的密码加密转换后,同数据库里保存的密码(同一用户名)比较就可以了.解决方案三:直接修改你的登录程序的逻辑,不判断密码直接统统判断验证成功就是了.解决方案四:md5是种单向的加密算法,一旦加密就没有办法解密.只能把用户输入的密码再次加密,看一下密文是不是一样的.解决方案五:为何要解密?正确做法是将用户的输入加密后和去数据库匹配.md5加密的结果解密那是科学家的事.解决方案六:网数据库

对称加密(4) .NET对称加密实践

在使用.NET框架提供的加密算法实现类来执行加密任务时,需要准备加密密钥和初始化向量(Initialization Vector,IV).基于对称加密的特点,在加密数据之后一定要保存好密钥和初始化向量,因为解密要用到它们.但是对于不同的数据加密,要使用不同的密钥和初始化向量,理论上每次新的加密过程都应该使用全新的密钥和初始化向量. 通常需要将加密密钥和初始化向量传递给另一个人,这时候需要使用非对称加密算法来加密密钥和初始化向量,然后在网络上传输.本节主要演示如何使用加密实践类,更多的应用内容会在

详解.NET下的加密解密算法(3) 非对称加密

本博文列出了.NET下常用的非对称加密算法,并将它们制作成小DEMO,希望能对大家有所帮助. RSA static string EnRSA(string data,string publickey) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); byte[] cipherbytes; rsa.FromXmlString(publickey); cipherbytes = rsa.Encrypt(Encoding

漫谈iOS RSA非对称加密与解密

前言 最近公司的客户端安全性出现了严重的问题,如今这个出解决方案并自我测试验证可行性的重任落在了我的身上,学习了很多他人的文章,再经过多次讨论,最后才确定最终解决方案.笔者在这里讲讲这一经历中所需要了解的知识. iOS客户端想要加密传输数据以防被窃取,最可靠的方式莫过于使用公钥加密算法加密,使用HTTPS协议在整个传输过程中都使用了这个技术,对于未能使用HTTPS的HTTP接口,我们能否实现RSA加密呢? PHP端实现解密可参考:iOS与PHP端实现RSA非对称加密解密 提示:本篇文章只讲RSA

Java安全之对称加密、非对称加密、数字签名

转贴: http://www.cnblogs.com/duanxz/p/3195098.html Java中加密分为两种方式一个是对称加密,另一个是非对称加密.对称加密是因为加密和解密的钥匙相同,而非对称加密是加密和解密的钥匙不同. 对称加密与非对称加密的区别: 对称加密称为密钥加密,速度快,但加密和解密的钥匙必须相同,只有通信双方才能知道密钥. 非对称加密称为公钥加密,算法更加复杂,速度慢,加密和解密钥匙不相同,任何人都可以知道公钥,只有一个人持有私钥可以解密. 对称加密解密: /* * 对称