zoukankan      html  css  js  c++  java
  • 33.NET对加密和解密的支持

      散列运算

    mscorlib.dll下的System.Security.Cryptography下:
    抽象类HashAlgorithm
        抽象类MD5
            MD5CryptoServiceProvider
        SHA1
            SHA1CryptoServiceProvider密封类:调用Windows Crypto API
            SHA1Managed普通类:用托管代码写的
        SHA256
            SHA256CryptoServiceProvider
            SHA256Managed
        SHA384
        SHA512

     

    □ 对字节数组或流散列运算

        class Program 
        { 
            static void Main(string[] args) 
            { 
                string str = "Hello World"; 
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create(HashAlgorithmType.SHA1); 
                byte[] data = Encoding.Default.GetBytes(str); 
                byte[] digest = hashAlgorithm.ComputeHash(data); 
                foreach (byte b in digest) 
                { 
                    Console.Write("{0:X}",b); 
                } 
                Console.ReadKey(); 
            } 
        }
     
        public class HashAlgorithmType 
        { 
            public const string SHA1 = "SHA1"; 
            public const string SHA256 = "SHA256"; 
            public const string SHA384 = "SHA384"; 
            public const string SHA512 = "SHA512"; 
            public const string MD5 = "MD5"; 
        }

     

    □ 密匙散列运算       

                string key = "secret key"; 
                byte[] data = Encoding.Default.GetBytes(key); 
                KeyedHashAlgorithm kha = new HMACSHA1(); 
                byte[] digest = kha.ComputeHash(data); 
                foreach (byte b in digest) 
                { 
                    Console.Write("{0:x}",b); 
                }

     

      对称加密和解密

    SymmetricAlgorithm
        DES
            DESCryptoServiceProvider
        TripleDES
            TripleDESCryptoServiceProvider
        Rijndael
            RijindaelManaged
        RC2  
            RC2CryptoServiceProvider

     

    IV:Initialization vector初始化向量:
    -为了解决加密字符串加密后仍然有重复部分,引入IV,加密字符串即使有重复,也会被打乱。
    -IV值可以随意指定,但长度固定,通常为64位byte类型
    -密匙长度也是固定的,通常为128位或196位byte类型

     

    使用Encoding类将字符串转换为byte[]:
    -如果使用UTF8,会变长编码

     

    加密解密方法:
    -加密方法:CreateEncryptor(),返回ICryptoTransform接口类型
    -解密方法:CreateDecryptor(),返回ICrtyptoTransform接口类型

     

    明文流和加密流的转换:

    public CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode)
     
        class Program 
        { 
            static void Main(string[] args) 
            { 
                #region 对称加密和解密
     
                string key = "secret key"; 
                string str = "Hello World";
     
                //加密 
                string encryptedText = SymmetricCryptoHelper.Encrypt(str, key); 
                Console.WriteLine(encryptedText);
     
                //解密 
                string clearText = SymmetricCryptoHelper.Decrypt(encryptedText, key); 
                Console.WriteLine(clearText);
     
                Console.ReadKey();
     
                #endregion 
            } 
        }
     
        //对称加密帮助类 
        public class SymmetricCryptoHelper 
        { 
            private ICryptoTransform encryptor;  //加密器对象 
            private ICryptoTransform decryptor; //解密器对象 
            private const int BufferSize = 1024;
     
            public SymmetricCryptoHelper(string algorithmName, byte[] key) 
            { 
                SymmetricAlgorithm provider = SymmetricAlgorithm.Create(algorithmName); 
                provider.Key = key; 
                provider.IV = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
     
                encryptor = provider.CreateEncryptor(); 
                decryptor = provider.CreateDecryptor(); 
            }
     
            public SymmetricCryptoHelper(byte[] key) : this("TripleDES", key){}
     
            //加密算法 
            public string Encrypt(string clearText) 
            { 
                //创建明文流 
                byte[] clearBuffer = Encoding.UTF8.GetBytes(clearText); 
                //byte[] clearBuffer = Encoding.Default.GetBytes(clearText); 
                MemoryStream clearStream = new MemoryStream(clearBuffer);
     
                //创建空的密文流 
                MemoryStream encryptedStream = new MemoryStream();
     
                //明文流和密文流转换流,准备写到密文流中 
                CryptoStream cryptoStream = new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write); 
               
                int bytesRead = 0; 
                byte[] buffer = new byte[BufferSize]; 
                do 
                { 
                    //读取明文流到buffer中 
                    bytesRead = clearStream.Read(buffer, 0, BufferSize); 
                    //通过CryptoStream将buffer中的明文流字节数组写到明文流中 
                    cryptoStream.Write(buffer, 0, bytesRead); 
                } while (bytesRead > 0);
     
                cryptoStream.FlushFinalBlock();
     
                //获取加密后的字节数组 
                buffer = encryptedStream.ToArray();
     
                //将加密后的字节数组转换成字符串 
                string encryptedText = Convert.ToBase64String(buffer); 
                return encryptedText; 
            }
     
            //解密算法 
            public string Decrypt(string encryptedText) 
            { 
                //把加密字符串转换为加密字节数组 
                byte[] encryptedBuffer = Convert.FromBase64String(encryptedText); 
                //创建密文流 
                Stream encryptedStream = new MemoryStream(encryptedBuffer);
     
                //创建空的明文流 
                MemoryStream clearStream = new MemoryStream();
     
                //创建明文流和密文流的转化流,读取密文流 
                CryptoStream cryptoStream = new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);
     
                int bytesRead = 0; 
                byte[] buffer = new byte[BufferSize];
     
                do 
                { 
                    //通过CryptoStream读取密文流到Buffer 
                    bytesRead = cryptoStream.Read(buffer, 0, BufferSize); 
                    //把Buffer中的密文流写到明文流中 
                    clearStream.Write(buffer, 0, bytesRead); 
                } while (bytesRead > 0);
     
                //将明文流转换成字节数组 
                buffer = clearStream.GetBuffer();
     
                string clearText = Encoding.UTF8.GetString(buffer, 0, (int)clearStream.Length); 
                //string clearText = Encoding.Default.GetString(buffer, 0, (int)clearStream.Length); 
                return clearText; 
            }
     
            //密匙加密 
            public static string Encrypt(string clearText, string key) 
            { 
                byte[] keyData = new byte[16]; //TripleDES密匙固定长度为16个字节
     
                //把密匙字符串转换成字节数组 
                byte[] sourceData = Encoding.Default.GetBytes(key); 
                int copyBytes = 16; 
                if (sourceData.Length < 16) 
                { 
                    copyBytes = sourceData.Length; 
                }
     
                //把密匙数组复制到keyData字节数组中 
                Array.Copy(sourceData,keyData,copyBytes);
     
                SymmetricCryptoHelper helper = new SymmetricCryptoHelper(keyData); 
                return helper.Encrypt(clearText); 
            }
     
            //密匙解密 
            public static string Decrypt(string encryptedText, string key) 
            { 
                byte[] keyData = new byte[16]; 
                byte[] sourceData = Encoding.Default.GetBytes(key); 
                int copyBytes = 16; 
                if (sourceData.Length < 16) 
                { 
                    copyBytes = sourceData.Length; 
                } 
                Array.Copy(sourceData,keyData,copyBytes);
     
                SymmetricCryptoHelper helper = new SymmetricCryptoHelper(keyData); 
                return helper.Decrypt(encryptedText); 
            } 
        }
     

    1

     

      非对称加密

    AsymmetricAlgorithm
        RSA
            RSACryptoServiceProvider
        DSA
            DSACryptoServiceProvider:只能进行认证模式,即数字签名

     

    对称加密中的密匙:
    密匙为由开发者设定的字符串

     

    非对称加密中的密匙:
    ● 通常是自动生成,不同的算法有不同的密匙格式   
    ● 在创建RSACryptoServiceProvider实例时,会自动创建一个公/私密匙对。在实例上调用ToXmlString()方法获得。

                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                string publicPrivate = provider.ToXmlString(true);//获得公/私匙对
                //string publicOnly = provider.ToXmlString(false); //只获得公匙
                Console.Write(publicPrivate);
                Console.ReadKey();

     

    □ 非对称加密帮助类

        //非对称加密帮助类 
        public class RSACryptoHelper 
        { 
            //加密 
            public static string Encrypt(string publicKeyXml, string plainText) 
            { 
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 
                provider.FromXmlString(publicKeyXml); //使用公匙初始化对象 
                byte[] plainData = Encoding.Default.GetBytes(plainText); 
                byte[] encryptedData = provider.Encrypt(plainData, true); 
                return Convert.ToBase64String(encryptedData); 
            }
     
            //解密 
            public static string Decrypt(string privateKeyXml, string encryptedText) 
            { 
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 
                provider.FromXmlString(privateKeyXml); 
                byte[] encryptedData = Convert.FromBase64String(encryptedText); 
                byte[] plainData = provider.Decrypt(encryptedData, true); 
                string plainText = Encoding.Default.GetString(plainData); 
                return plainText; 
            } 
        }

     

      数字签名

    RSACryptoServiceProvider或DSACryptoServiceProvider
    SignData()对摘要进行签名,并返回签名后的摘要。
    VerifyData()得出本地摘要,并解密传递进来的原始摘要,对比返回bool类型结果。

     

    □ 数字签名帮助类

        public class RSACryptoHelper 
        { 
            public static string SignData(string plainText, string privateKeyXml) 
            { 
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 
                provider.FromXmlString(privateKeyXml);
     
                byte[] plainData = Encoding.Default.GetBytes(plainText); 
                //设置获取摘要的算法 
                HashAlgorithm sha1 = HashAlgorithm.Create("SHA1"); 
                //获取签名过的摘要,是使用私匙加密过的摘要 
                byte[] signedDigest = provider.SignData(plainData, sha1); 
                return Convert.ToBase64String(signedDigest); 
            }
     
            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 sha1 = HashAlgorithm.Create("SHA1"); 
                bool isDataIntact = provider.VerifyData(plainData, sha1, signedDigest); 
                return isDataIntact; 
            }
     
            //使用SingnHash 
            public static string SignData2(string plainText, string privateKeyXml) 
            { 
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 
                provider.FromXmlString(privateKeyXml); 
                byte[] plainData = Encoding.Default.GetBytes(plainText);
     
                //设置获取摘要的算法 
                HashAlgorithm sha1 = HashAlgorithm.Create("SHA1"); 
                //获得原始摘要 
                byte[] digestData = sha1.ComputeHash(plainData); 
                //对元素摘要进行签名 
                byte[] signedDigest = provider.SignHash(digestData, "SHA1"); 
                return Convert.ToBase64String(signedDigest); 
            }
     
            //使用VerifyHash 
            public static bool VerifyData2(string plainText, string signedDigest, string publicKeyXml) 
            { 
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 
                provider.FromXmlString(publicKeyXml);
     
                byte[] plainData = Encoding.Default.GetBytes("SHA1"); 
                byte[] signedDigestData = Convert.FromBase64String(signedDigest);
     
                //获得本地摘要 
                HashAlgorithm sha1 = HashAlgorithm.Create("SHA1"); 
                byte[] digest = sha1.ComputeHash(plainData);
     
                //解密签名 
                bool isDataIntact = provider.VerifyHash(digest, "SHA1", signedDigestData); 
                return isDataIntact; 
            } 
        }
     

     

    参考资料:
    《.NET之美》--张子阳,感谢写了这么好的书!   

  • 相关阅读:
    读《构建之法》8、9、10章有感
    评论
    复利计算器(4)——jQuery界面美化、自动补全
    送给搭档的“汉堡”
    MFC之TreeCtrl控件使用经验总结
    MFC绘制图片闪烁详解
    MFC 网络编程中::connect返回-1问题
    C++网络编程之select
    C++关于Condition Variable
    Mutex 和 Lock
  • 原文地址:https://www.cnblogs.com/darrenji/p/3677458.html
Copyright © 2011-2022 走看看