c# aes,des,md5加密等解密算法
一:可逆加密,即是能加密也能解密
- 对称可逆加密:加密后能解密回原文,加密key和解密key是一个
- 加密算法都是公开的,密钥是保密的, 即使拿到密文 你是推算不了密钥 也推算不了原文
- 加密解密的速度快,问题是密钥的安全
1:DES加密解密
1 /// <summary> 2 /// DES AES Blowfish 3 /// 对称加密算法的优点是速度快, 4 /// 缺点是密钥管理不方便,要求共享密钥。 5 /// 可逆对称加密 密钥长度8 6 /// </summary> 7 public class DesEncrypt 8 { 9 private static byte[] _rgbKey = ASCIIEncoding.ASCII.GetBytes("12345678"); 10 private static byte[] _rgbIV = ASCIIEncoding.ASCII.GetBytes("AES00000"); 11 /// <summary> 12 /// DES 加密 13 /// </summary> 14 /// <param name="text">需要加密的值</param> 15 /// <returns>加密后的结果</returns> 16 public static string Encrypt(string text) 17 { 18 DESCryptoServiceProvider dsp = new DESCryptoServiceProvider(); 19 using (MemoryStream memStream = new MemoryStream()) 20 { 21 CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateEncryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write); 22 StreamWriter sWriter = new StreamWriter(crypStream); 23 sWriter.Write(text); 24 sWriter.Flush(); 25 crypStream.FlushFinalBlock(); 26 memStream.Flush(); 27 return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length); 28 } 29 } 30 31 /// <summary> 32 /// DES解密 33 /// </summary> 34 /// <param name="encryptText"></param> 35 /// <returns>解密后的结果</returns> 36 public static string Decrypt(string encryptText) 37 { 38 DESCryptoServiceProvider dsp = new DESCryptoServiceProvider(); 39 byte[] buffer = Convert.FromBase64String(encryptText); 40 41 using (MemoryStream memStream = new MemoryStream()) 42 { 43 CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateDecryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write); 44 crypStream.Write(buffer, 0, buffer.Length); 45 crypStream.FlushFinalBlock(); 46 return ASCIIEncoding.UTF8.GetString(memStream.ToArray()); 47 } 48 } 49 }
2:AES加密解密
c#代码:
1 public class AesEncrypts 2 { 3 /// <summary> 4 /// AES 加密 5 /// </summary> 6 /// <param name="str"></param> 7 /// <param name="key"></param> 8 /// <returns></returns> 9 public static string AesEncrypt(string str, string key) 10 { 11 if (string.IsNullOrEmpty(str)) return null; 12 Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str); 13 byte[] ivs = new byte[16]; 14 RijndaelManaged rm = new RijndaelManaged 15 { 16 Key = Encoding.UTF8.GetBytes(key), 17 Mode = CipherMode.CBC, //位置偏移,如果是ECB则不需要ivs 18 Padding = PaddingMode.PKCS7, 19 IV=ivs 20 }; 21 22 ICryptoTransform cTransform = rm.CreateEncryptor(); 23 Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 24 25 return Convert.ToBase64String(resultArray, 0, resultArray.Length); 26 } 27 28 /// <summary> 29 /// AES 解密 30 /// </summary> 31 /// <param name="str"></param> 32 /// <param name="key"></param> 33 /// <returns></returns> 34 public static string AesDecrypt(string str, string key) 35 { 36 if (string.IsNullOrEmpty(str)) return null; 37 Byte[] toEncryptArray = Convert.FromBase64String(str); 38 byte[] ivs = new byte[16]; 39 RijndaelManaged rm = new RijndaelManaged 40 { 41 Key = Encoding.UTF8.GetBytes(key), 42 Mode =CipherMode.CBC, 43 Padding =PaddingMode.PKCS7, 44 IV=ivs 45 }; 46 47 ICryptoTransform cTransform = rm.CreateDecryptor(); 48 Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 49 50 return Encoding.UTF8.GetString(resultArray); 51 } 52 }
java代码:
1 // 2 // Source code recreated from a .class file by IntelliJ IDEA 3 // (powered by Fernflower decompiler) 4 // 5 6 package com.lvmama.intlflight.api.common.util; 7 8 import javax.crypto.Cipher; 9 import javax.crypto.spec.IvParameterSpec; 10 import javax.crypto.spec.SecretKeySpec; 11 import sun.misc.BASE64Decoder; 12 import sun.misc.BASE64Encoder; 13 14 public class AESUtil { 15 public AESUtil() { 16 } 17 18 public static String encrypt(String sSrc, String sKey) throws Exception { 19 if(sKey == null) { 20 System.out.print("Key为空null"); 21 return null; 22 } else if(sKey.length() != 16) { 23 System.out.print("Key长度不是16位"); 24 return null; 25 } else { 26 byte[] raw = sKey.getBytes(); 27 SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 28 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 29 byte[] ivs = new byte[16]; 30 IvParameterSpec iv = new IvParameterSpec(ivs); 31 cipher.init(1, skeySpec, iv); 32 byte[] encrypted = cipher.doFinal(sSrc.getBytes()); 33 return (new BASE64Encoder()).encode(encrypted); 34 } 35 } 36 37 public static String decrypt(String sSrc, String sKey) throws Exception { 38 try { 39 if(sKey == null) { 40 System.out.print("Key为空null"); 41 return null; 42 } else if(sKey.length() != 16) { 43 System.out.print("Key长度不是16位"); 44 return null; 45 } else { 46 byte[] raw = sKey.getBytes("ASCII"); 47 SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 48 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 49 byte[] ivs = new byte[16]; 50 IvParameterSpec iv = new IvParameterSpec(ivs); 51 cipher.init(2, skeySpec, iv); 52 byte[] encrypted1 = (new BASE64Decoder()).decodeBuffer(sSrc); 53 54 try { 55 byte[] original = cipher.doFinal(encrypted1); 56 String originalString = new String(original); 57 return originalString; 58 } catch (Exception var10) { 59 System.out.println(var10.toString()); 60 return null; 61 } 62 } 63 } catch (Exception var11) { 64 System.out.println(var11.toString()); 65 return null; 66 } 67 } 68 69 public static void main(String[] args) throws Exception { 70 String cKey = "1234567890123456"; 71 String cSrc = "abcdefghigklmnopqrstuvwxyz0123456789"; 72 System.out.println(cSrc); 73 long lStart = System.currentTimeMillis(); 74 String enString = encrypt(cSrc, cKey); 75 System.out.println("加密后的字串是:" + enString); 76 long lUseTime = System.currentTimeMillis() - lStart; 77 System.out.println("加密耗时:" + lUseTime + "毫秒"); 78 lStart = System.currentTimeMillis(); 79 String DeString = decrypt(enString, cKey); 80 System.out.println("解密后的字串是:" + DeString); 81 lUseTime = System.currentTimeMillis() - lStart; 82 System.out.println("解密耗时:" + lUseTime + "毫秒"); 83 } 84 }
二:不可逆加密,即是没有办法解密,其特点为如下几个:
- 相同原文加密的结果是一样的
- 不同长度的内容加密后加过都是32位
- 原文差别很小,结果差别很大
- 不管文件多大,都能产生32位长度摘要
1:MD5加密代码:
1 #region MD5 2 /// <summary> 3 /// MD5加密,和动网上的16/32位MD5加密结果相同, 4 /// 使用的UTF8编码 5 /// </summary> 6 /// <param name="source">待加密字串</param> 7 /// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param> 8 /// <returns>加密后的字串</returns> 9 public static string Encrypt(string source, int length = 32)//默认参数 10 { 11 if (string.IsNullOrEmpty(source)) return string.Empty; 12 HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm; 13 byte[] bytes = Encoding.UTF8.GetBytes(source);//这里需要区别编码的 14 byte[] hashValue = provider.ComputeHash(bytes); 15 StringBuilder sb = new StringBuilder(); 16 switch (length) 17 { 18 case 16://16位密文是32位密文的9到24位字符 19 for (int i = 4; i < 12; i++) 20 { 21 sb.Append(hashValue[i].ToString("x2")); 22 } 23 break; 24 case 32: 25 for (int i = 0; i < 16; i++) 26 { 27 sb.Append(hashValue[i].ToString("x2")); 28 } 29 break; 30 default: 31 for (int i = 0; i < hashValue.Length; i++) 32 { 33 sb.Append(hashValue[i].ToString("x2")); 34 } 35 break; 36 } 37 return sb.ToString(); 38 } 39 #endregion MD5
2:MD5的用途
A:防篡改:
//发个文档,事先给别人一个MD5,是文档的摘要,
//源代码管理器svn--即使电脑断网了,文件有任何改动都能被发现--本地存了一个文件的MD5--文件有更新,就再对比下MD5
//急速秒传--扫描文件的MD5--跟已有的文件MD5比对--吻合表示文件已存在不用再上传
B: 密码保存,防止看到明文
//密码应该只有用户知道----数据库不能存明文---但是又需要验证
//MD5加密下原始密码---数据库存密文---下次登录把密码MD5后再比对
//密文是可见的,所以要求密码不能太简单,加盐(123456+wss)
C 防止抵赖,数字签名
//把一些内容摘要一下,由权威的第三方去保障,将来这个文件就是你做的,不能抵赖
1 #region MD5摘要 2 /// <summary> 3 /// 获取文件的MD5摘要 4 /// </summary> 5 /// <param name="fileName"></param> 6 /// <returns></returns> 7 public static string AbstractFile(string fileName) 8 { 9 using (FileStream file = new FileStream(fileName, FileMode.Open)) 10 { 11 return AbstractFile(file); 12 } 13 } 14 /// <summary> 15 /// 根据stream获取文件摘要 16 /// </summary> 17 /// <param name="stream"></param> 18 /// <returns></returns> 19 public static string AbstractFile(Stream stream) 20 { 21 MD5 md5 = new MD5CryptoServiceProvider(); 22 byte[] retVal = md5.ComputeHash(stream); 23 24 StringBuilder sb = new StringBuilder(); 25 for (int i = 0; i < retVal.Length; i++) 26 { 27 sb.Append(retVal[i].ToString("x2")); 28 } 29 return sb.ToString(); 30 } 31 #endregion
坚持就是胜利!
如有问题,请反馈微信loverwangshan