对称加密与非对称加密

安全的交流方式需要同时满足下面三个条件:
1.完整性,即消息没有中途篡改过。
2.保密性,第三方无法解密。
3.可认证性,消息的接收方可以确定消息是谁发送的。
 

对称加密:双方使用的同一个密钥,既可以加密又可以解密,这种加密方法称为对称加密,也称为单密钥加密

优点:速度快,对称性加密通常在消息发送方需要加密大量数据时使用,算法公开、计算量小、加密速度快、加密效率高。

缺点:在数据传送前,发送方和接收方必须商定好秘钥,然后 使双方都能保存好秘钥。其次如果一方的秘钥被泄露,那么加密信息也就不安全了。另外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的唯一秘 钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理成为双方的负担。

在对称加密算法中常用的算法有:DES、AES等。

AES:密钥的长度可以为128、192和256位,也就是16个字节、24个字节和32个字节
DES:密钥的长度64位,8个字节。
c#中使用des加密解密:
 /// <summary>
        /// DES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
        public static string EncryptDES(string encryptString, string key)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(key);
                byte[] rgbIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        /// <summary>
        /// DES解密字符串
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="key">解密密钥,要求8位</param>
        /// <returns></returns>
        public static string DecryptDES(string decryptString, string key)
        {
            try
            {
                //默认密钥向量
                byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
                byte[] rgbKey = Encoding.UTF8.GetBytes(key);
                byte[] rgbIV = Keys;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        }

c#中使用AES加密解密:

 /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="str">要加密字符串</param>
        /// <param name="aeskey">密钥的长度可以为128、192和256位,也就是16个字节、24个字节和32个字节</param>
        /// <returns>返回加密后字符串</returns>
        public static String EncryptAES(String str, string aeskey)
        {
            Byte[] keyArray = System.Text.UTF8Encoding.UTF8.GetBytes(aeskey);
            Byte[] toEncryptArray = System.Text.UTF8Encoding.UTF8.GetBytes(str);

            System.Security.Cryptography.RijndaelManaged rDel = new System.Security.Cryptography.RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = System.Security.Cryptography.CipherMode.ECB;
            rDel.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

            System.Security.Cryptography.ICryptoTransform cTransform = rDel.CreateEncryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }


        /// <summary>
        /// AES解密
        /// </summary>
        /// <param name="str">要解密字符串</param>
        /// <param name="aeskey">密钥的长度可以为128、192和256位,也就是16个字节、24个字节和32个字节</param>
        /// <returns>返回解密后字符串</returns>
        public static String DecryptAES(String str, string aeskey)
        {
            Byte[] keyArray = System.Text.UTF8Encoding.UTF8.GetBytes(aeskey);
            Byte[] toEncryptArray = Convert.FromBase64String(str);

            System.Security.Cryptography.RijndaelManaged rDel = new System.Security.Cryptography.RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = System.Security.Cryptography.CipherMode.ECB;
            rDel.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

            System.Security.Cryptography.ICryptoTransform cTransform = rDel.CreateDecryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return System.Text.UTF8Encoding.UTF8.GetString(resultArray);
        }

 

 
非对称加密:一对密钥由公钥和私钥组成(可以使用很多对密钥)。私钥解密公钥加密数据,公钥解密私钥加密数据(私钥公钥可以互相加密解密)。
私钥只能由一方保管,不能外泄。公钥可以交给任何请求方。
在非对称加密算法中常用的算法有: RSA等
缺点:速度较慢
优点:安全
 
c#中使用rsa加密解密:
  /// <summary>
        /// 生成私钥和公钥
        /// </summary>
        public static void CreateKey() {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            string privateKey = provider.ToXmlString(true); // 获得私钥
            string publicKey = provider.ToXmlString(false); // 只获得公钥 
        }
        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="plainText">加密字符串</param>
        /// <returns></returns>
        public static string RSAEncrypt(string publicKey, string plainText)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(publicKey); // 使用公钥初始化对象
            byte[] plainData = Encoding.Default.GetBytes(plainText);
            byte[] encryptedData = provider.Encrypt(plainData, true);
            return Convert.ToBase64String(encryptedData);
        }
        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="privateKey">私钥</param>
        /// <param name="encryptedText">解密字符串</param>
        /// <returns></returns>
        public static string RSADecrypt(string privateKey, string encryptedText)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(privateKey); // 使用公/私钥对初始化对象
            byte[] encryptedData = Convert.FromBase64String(encryptedText);
            byte[] plainData = provider.Decrypt(encryptedData, true);
            string plainText = Encoding.Default.GetString(plainData);
            return plainText;
        }

 

 

 
消息摘要(散列运算,哈希运算):对一段信息(Message)产生信息摘要(加密 Message-Digest),以防止被篡改。多次对同一个字符串加密结果一样,不可逆。
常用算法:md5,sha1
       //md5 32位散列加密
        private static string GetMD5(string str)
        {
            if (string.IsNullOrEmpty(str))
                return str;
            try
            {
                var sb = new StringBuilder(32);
                var md5 = System.Security.Cryptography.MD5.Create();
                var output = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
                for (int i = 0; i < output.Length; i++)
                    sb.Append(output[i].ToString("X").PadLeft(2, '0'));
                return sb.ToString();
            }
            catch (Exception)
            {
                return null;
            }
        }

     

        /// <summary>  
        /// SHA1 加密,返回大写字符串  
        /// </summary>  
        /// <param name="content">需要加密字符串</param>  
        /// <param name="encode">指定加密编码</param>  
        /// <returns>返回40位大写字符串</returns>  
        public static string SHA1(string content, Encoding encode)
        {
            try
            {
                SHA1 sha1 = new SHA1CryptoServiceProvider();
                byte[] bytes_in = encode.GetBytes(content);
                byte[] bytes_out = sha1.ComputeHash(bytes_in);
                sha1.Dispose();
                string result = BitConverter.ToString(bytes_out);
                result = result.Replace("-", "");
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception("SHA1加密出错:" + ex.Message);
            }
        }

 

 

 

数字签名

1.对消息指定值进行md5等摘要运算,得到消息摘要。
2.使用发送方私钥对消息摘要进行加密(并不对消息本身加密)
3.接收方使用发送方公钥进行解密,计算哈希值。来判断消息是否一致。
注意:如果参数被截取到,消息本身还是看到的。
 
混合使用(非对称加密+数字签名):
首先接收方和发送方都有一对秘钥。
发送方:
1.对消息进行md5等摘要运算,得到消息摘要。
2.使用发送方私钥对消息摘要进行加密,该过程也称作签名。(确保了接收方能够确认自己的身份)
3.使用接收方的公钥对消息进行加密(确保了消息只能由期望的接收方解密)
4.发送消息和消息摘要
接收方:
1.使用发送发的公钥对消息摘要进行解密(确认了消息是由谁发送的),获得原始消息摘要
2.使用自己的私钥对消息进行解密(安全的获得了消息内容)
3.将消息进行散列运算,获得本地消息摘要。
4.将原始消息摘要与本地消息摘要对比(验签),确认消息是否被篡改。
 
缺点:比较耗时。
 
 参考:百度百科与《.NET之美》。
 
 
 
posted @ 2017-02-06 10:36  木目相  阅读(754)  评论(0)    收藏  举报