zoukankan      html  css  js  c++  java
  • NET中各种加密解密方法

            /// <summary>
            /// AES对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB),这三种的区别,主要来自于密钥的长度,16位密钥=128位,24位密钥=192位,32位密钥=256位
            /// 检验密钥是否有效长度【16|24|32】
            /// </summary>
            /// <param name="key">密钥</param>
            /// <returns>bool</returns>
            private static bool AesCheckKey(string key)
            {
                if (string.IsNullOrWhiteSpace(key))
                    return false;
                if (16.Equals(key.Length) || 24.Equals(key.Length) || 32.Equals(key.Length))
                    return true;
                else
                    return false;
            }
                
            #region 参数是string类型的
            /// <summary>
            ///  AES加密 参数:string
            /// </summary>
            /// <param name="source">源字符串</param>
            /// <param name="key">密钥</param>    
            /// <param name="base64">是否转64进制</param>
            /// <param name="model">运算模式</param>
            /// <param name="padding">填充模式</param>
            /// <param name="encoding">编码类型</param>
            /// <returns>加密后的字符串</returns>
            public static string AesEncrypt(string source, string key, bool base64 = false, CipherMode model = CipherMode.ECB, PaddingMode padding = PaddingMode.PKCS7, Encoding encoding = null)
            {
                if (string.IsNullOrWhiteSpace(source)) return null;
                if (!AesCheckKey(key)) return source;
                if (encoding == null) encoding = Encoding.UTF8;
                using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
                {
                    aesProvider.Key = encoding.GetBytes(key);
                    aesProvider.Mode = model;
                    aesProvider.Padding = padding;
                    //aesProvider.KeySize = 128;
                    //aesProvider.BlockSize = 128;               
                    using (ICryptoTransform cryptoTransform = aesProvider.CreateEncryptor())
                    {
                        byte[] toEncryptArray = encoding.GetBytes(source);               
                        byte[] resultArray = cryptoTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                        aesProvider.Clear();
                        //return Convert.ToBase64String(resultArray, 0, resultArray.Length);
                        return base64 ? Convert.ToBase64String(resultArray) : byteToHexString(resultArray);
                    }             
                }
    
                //RijndaelManaged rijndaelCipher = new RijndaelManaged();
                //rijndaelCipher.Mode = CipherMode.ECB;
                //rijndaelCipher.Padding = PaddingMode.PKCS7;
                //rijndaelCipher.KeySize = 128;
                //rijndaelCipher.BlockSize = 128;
                //byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(key);
                //byte[] keyBytes = new byte[16];
                //int len = pwdBytes.Length;
                //if (len > keyBytes.Length) len = keyBytes.Length;
                //System.Array.Copy(pwdBytes, keyBytes, len);
                //rijndaelCipher.Key = keyBytes;
                ////加密初始化向量
                //string iv = "  ";
                //byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);
                //rijndaelCipher.IV = new byte[16];
                //ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
                //byte[] plainText = System.Text.Encoding.UTF8.GetBytes(source);
                //byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
                //return byteToHexString(cipherBytes);// Convert.ToBase64String(cipherBytes);          
            }
                  
            /// <summary>
            ///  AES解密 参数:string
            /// </summary>
            /// <param name="source">源字符串</param>
            /// <param name="key">密钥</param>     
            /// <param name="base64">是否转64进制</param>
            /// <param name="model">运算模式</param>
            /// <param name="padding">填充模式</param>
            /// <param name="encoding">编码类型</param>
            /// <returns>解密后的字符串</returns>
            public static string AesDecrypt(string source, string key, bool base64 = false, CipherMode model = CipherMode.ECB, PaddingMode padding = PaddingMode.PKCS7, Encoding encoding = null)
            {
                if (string.IsNullOrWhiteSpace(source)) return null;
                if (!AesCheckKey(key)) return source;
                if (encoding == null) encoding = Encoding.UTF8;
                using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
                {
                    aesProvider.Key = encoding.GetBytes(key);
                    aesProvider.Mode = model;
                    aesProvider.Padding = padding;
                    //aesProvider.KeySize = 128;
                    //aesProvider.BlockSize = 128;      
                    using (ICryptoTransform cryptoTransform = aesProvider.CreateDecryptor())
                    {
                        byte[] toEncryptArray = base64 == true ? Convert.FromBase64String(source) : stringToHexByte(source);                
                        byte[] resultArray = cryptoTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                        aesProvider.Clear();
                        return encoding.GetString(resultArray);
                    }
                }     
            }
            #endregion
    
            /// <summary>
            /// 字节数组转16进制字符串
            /// </summary>
            /// <param name="bytes"></param>
            /// <returns></returns>
            public static string byteToHexString(byte[] bytes)
            {
                string returnStr = "";
                if (bytes != null)
                {
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        returnStr += bytes[i].ToString("X2");
                    }
                }
                return returnStr;
            }
    
            /// <summary>
            /// 将16进制字符串转换为字节数组     
            /// </summary>
            /// <param name="hexString"></param>
            /// <returns></returns>
            private static byte[] stringToHexByte(string hexString)
            {
                hexString = hexString.Replace(" ", "");
                if ((hexString.Length % 2) != 0)
                    hexString += " ";
                byte[] returnBytes = new byte[hexString.Length / 2];
                for (int i = 0; i < returnBytes.Length; i++)
                    returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                return returnBytes;
            }
            
            #region 参数是byte[]类型的
            /// <summary>  
            /// AES加密 参数:byte[] 
            /// </summary>  
            /// <param name="source">源字符字节组</param>
            /// <param name="key">密钥</param>     
            /// <param name="model">运算模式</param>
            /// <param name="padding">填充模式</param>
            /// <param name="encoding">编码类型</param>
            /// <returns>加密后的字符字节组</returns>  
            public static byte[] AesEncrypt(byte[] source, string key, CipherMode model = CipherMode.ECB, PaddingMode padding = PaddingMode.PKCS7, Encoding encoding = null)
            {
                if (source == null) return null;
                if (!AesCheckKey(key)) return source;
                if (encoding == null) encoding = Encoding.UTF8;
                byte[] bKey = encoding.GetBytes(key);       
                byte[] cryptograph = null; //加密后的密文  
                Rijndael Aes = Rijndael.Create();
                Aes.Key = bKey;          
                //开辟一块内存流  
                using (MemoryStream Memory = new MemoryStream())
                {
                    //把内存流对象包装成加密流对象  
                    using (CryptoStream Encryptor = new CryptoStream(Memory, Aes.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        //明文数据写入加密流  
                        Encryptor.Write(source, 0, source.Length);
                        Encryptor.FlushFinalBlock();
                        cryptograph = Memory.ToArray();
                    }
                }
                return cryptograph;
            }
    
            /// <summary>  
            /// AES解密 参数:byte[] 
            /// </summary>  
            /// <param name="source">源字符字节组</param>
            /// <param name="key">密钥</param>     
            /// <param name="model">运算模式</param>
            /// <param name="padding">填充模式</param>
            /// <param name="encoding">编码类型</param>
            /// <returns>解密后的字符字节组</returns>  
            public static byte[] AesDecrypt(byte[] source, string key, CipherMode model = CipherMode.ECB, PaddingMode padding = PaddingMode.PKCS7, Encoding encoding = null)
            {
                if (source == null) return null;
                if (!AesCheckKey(key)) return source;
                if (encoding == null) encoding = Encoding.UTF8;
                byte[] bKey = encoding.GetBytes(key);      
                byte[] original = null; //解密后的明文  
                Rijndael Aes = Rijndael.Create();
                //开辟一块内存流,存储密文  
                using (MemoryStream Memory = new MemoryStream(source))
                {
                    //把内存流对象包装成加密流对象  
                    using (CryptoStream Decryptor = new CryptoStream(Memory, Aes.CreateDecryptor(bKey, null), CryptoStreamMode.Read))
                    {
                        //明文存储区  
                        using (MemoryStream originalMemory = new MemoryStream())
                        {
                            byte[] Buffer = new byte[1024];
                            int readBytes = 0;
                            while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)
                            {
                                originalMemory.Write(Buffer, 0, readBytes);
                            }
                            original = originalMemory.ToArray();
                        }
                    }
                }
                return original;
            }
            #endregion        
    
            /// <summary>
            /// 对字符串SHA1加密
            /// </summary>
            /// <param name="source">源字符串</param>
            /// <param name="encoding">编码类型</param>
            /// <returns>加密后的十六进制字符串</returns>
            public static string Sha1Encrypt(string source, Encoding encoding = null)
            {
                if (encoding == null) encoding = Encoding.UTF8;
    
                // 第一种方式
                byte[] byteArray = encoding.GetBytes(source);
                using (HashAlgorithm hashAlgorithm = new SHA1CryptoServiceProvider())
                {
                    byteArray = hashAlgorithm.ComputeHash(byteArray);
                    StringBuilder stringBuilder = new StringBuilder(256);
                    foreach (byte item in byteArray)
                    {
                        stringBuilder.AppendFormat("{0:x2}", item);
                    }
                    hashAlgorithm.Clear();
                    return stringBuilder.ToString();
                }
    
                //// 第二种方式
                //using (SHA1 sha1 = SHA1.Create())
                //{
                //    byte[] hash = sha1.ComputeHash(encoding.GetBytes(source));
                //    StringBuilder stringBuilder = new StringBuilder();
                //    for (int index = 0; index < hash.Length; ++index)
                //        stringBuilder.Append(hash[index].ToString("x2"));
                //    sha1.Clear();
                //    return stringBuilder.ToString();
                //}
            }
    
            /// <summary>
            /// 对字符串MD5加密
            /// </summary>
            /// <param name="source">源字符串</param>
            /// <param name="encoding">编码类型</param>
            /// <returns>加密后的十六进制字符串</returns>
            public static string Md5Encrypt(string source, Encoding encoding = null)
            {
                if (encoding == null) encoding = Encoding.UTF8;
    
                byte[] byteArray = encoding.GetBytes(source);
                using (HashAlgorithm hashAlgorithm = new MD5CryptoServiceProvider())
                {
                    byteArray = hashAlgorithm.ComputeHash(byteArray);
                    StringBuilder stringBuilder = new StringBuilder();
                    foreach (byte item in byteArray)
                    {
                        stringBuilder.AppendFormat("{0:x2}", item);
                    }
                    hashAlgorithm.Clear();
                    return stringBuilder.ToString();
                }
            }

    AES加密方式中关于PKCS5Padding与PKCS7Padding的区别

    在PKCS5Padding中,明确定义Block的大小是8位,而在PKCS7Padding定义中,对于块的大小是不确定的,可以在1-255之间(块长度超出255的尚待研究),填充值的算法都是一样的:

    value=k - (l mod k) ,K=块大小,l=数据长度,如果l=8, 则需要填充额外的8个byte的8

    在.net中,例如TripleDESCryptoServiceProvider ,默认BlockSize=64bits=8bytes,所以在这种情况下在PKCS5Padding=PKCS7Padding。

    如果在C#中自己定义了一个不是64bits的加密块大小,同时使用PKCS7Padding,那么在java中使用JDK标准的PKCS5Padding就不能解密了。

  • 相关阅读:
    抽象工厂模式
    工厂方法模式
    assert断言
    非日志警告
    requests获取所有状态码
    在线工具、资料
    重定向、feed输出:控制台输出的内容存放到文件
    正则表达式python
    python提取相对路径
    logger类
  • 原文地址:https://www.cnblogs.com/li150dan/p/10863673.html
Copyright © 2011-2022 走看看