当前位置: 代码迷 >> C# >> 每日一段代码-C# 3DES加密
  详细解决方案

每日一段代码-C# 3DES加密

热度:15   发布时间:2016-05-05 03:35:20.0
每天一段代码-C# 3DES加密

  最近一个项目中,因为服务端是用的java开发的,客户端是用的C#,由于通信部分采用到了3DES加密,所以做个记录,以备以后需要的时候直接用。

  这是对方(java)的加密算法,和网上流传的代码也差不多(主密钥直接写死了,方便测试)

  1 package org.zwork.market.mina.msg;  2   3 import java.security.spec.KeySpec;  4   5 import javax.crypto.Cipher;  6 import javax.crypto.SecretKey;  7 import javax.crypto.SecretKeyFactory;  8 import javax.crypto.spec.DESKeySpec;  9 import javax.crypto.spec.DESedeKeySpec; 10  11 import org.slf4j.Logger; 12 import org.slf4j.LoggerFactory; 13 import org.zwork.market.MktContants; 14  15 public class ThreeEncryptDecrypt { 16  17     private static final Logger LOGGER = LoggerFactory.getLogger(ThreeEncryptDecrypt.class); 18  19     // 定义 加密算法,可用 DES,DESede,Blowfish 20     public static final String Algorithm = "DESede"; 21     public static String DES = "DES/ECB/NoPadding"; 22     public static String TriDes = "DESede/ECB/NoPadding"; 23  24     // des加密 25     public static byte[] des_crypt(byte key[], byte data[]) { 26         try { 27             KeySpec ks = new DESKeySpec(key); 28             SecretKeyFactory kf = SecretKeyFactory.getInstance("DES"); 29             SecretKey ky = kf.generateSecret(ks); 30  31             Cipher c = Cipher.getInstance(DES); 32             c.init(Cipher.ENCRYPT_MODE, ky); 33             return c.doFinal(data); 34         } catch (Exception e) { 35             LOGGER.error("des_crypt error:", e); 36             return null; 37         } 38     } 39  40     // des解密 41     public static byte[] des_decrypt(byte key[], byte data[]) { 42  43         try { 44             KeySpec ks = new DESKeySpec(key); 45             SecretKeyFactory kf = SecretKeyFactory.getInstance("DES"); 46             SecretKey ky = kf.generateSecret(ks); 47  48             Cipher c = Cipher.getInstance(DES); 49             c.init(Cipher.DECRYPT_MODE, ky); 50             return c.doFinal(data); 51         } catch (Exception e) { 52             LOGGER.error("des_decrypt error:", e); 53             return null; 54         } 55     } 56  57     // 3DES加密 58     public static byte[] trides_crypt(byte key[], byte data[]) { 59         try { 60             byte[] k = new byte[24]; 61  62             int len = data.length; 63             if (data.length % 8 != 0) { 64                 len = data.length - data.length % 8 + 8; 65             } 66             byte[] needData = null; 67             if (len != 0) 68                 needData = new byte[len]; 69  70             for (int i = 0; i < len; i++) { 71                 needData[i] = 0x00; 72             } 73  74             System.arraycopy(data, 0, needData, 0, data.length); 75  76             if (key.length == 16) { 77                 System.arraycopy(key, 0, k, 0, key.length); 78                 System.arraycopy(key, 0, k, 16, 8); 79             } else { 80                 System.arraycopy(key, 0, k, 0, 24); 81             } 82  83             KeySpec ks = new DESedeKeySpec(k); 84             SecretKeyFactory kf = SecretKeyFactory.getInstance("DESede"); 85             SecretKey ky = kf.generateSecret(ks); 86  87             Cipher c = Cipher.getInstance(TriDes); 88             c.init(Cipher.ENCRYPT_MODE, ky); 89             return c.doFinal(needData); 90         } catch (Exception e) { 91             LOGGER.error("trides_crypt error:", e); 92             return null; 93         } 94  95     } 96  97     // 3DES解密 98     public static byte[] trides_decrypt(byte key[], byte data[]) { 99         try {100             byte[] k = new byte[24];101 102             int len = data.length;103             if (data.length % 8 != 0) {104                 len = data.length - data.length % 8 + 8;105             }106             byte[] needData = null;107             if (len != 0)108                 needData = new byte[len];109 110             for (int i = 0; i < len; i++) {111                 needData[i] = 0x00;112             }113 114             System.arraycopy(data, 0, needData, 0, data.length);115 116             if (key.length == 16) {117                 System.arraycopy(key, 0, k, 0, key.length);118                 System.arraycopy(key, 0, k, 16, 8);119             } else {120                 System.arraycopy(key, 0, k, 0, 24);121             }122             KeySpec ks = new DESedeKeySpec(k);123             SecretKeyFactory kf = SecretKeyFactory.getInstance("DESede");124             SecretKey ky = kf.generateSecret(ks);125 126             Cipher c = Cipher.getInstance(TriDes);127             c.init(Cipher.DECRYPT_MODE, ky);128             return c.doFinal(needData);129         } catch (Exception e) {130             LOGGER.error("trides_decrypt error:", e);131             return null;132         }133     }134 135     public static String getPass(String source) {136         byte[] data= hexToBytes(source);137         byte[] key ="111111111111111111111111111a1.1.".getBytes();138         String result = byte2hex(trides_decrypt(key, data)).toUpperCase();139         return result.substring(2, 8);140     }141 142     public static String byte2hex(byte[] data) {143         StringBuffer sb = new StringBuffer();144         for (int i = 0; i < data.length; i++) {145             String temp = Integer.toHexString(((int) data[i]) & 0xFF);146             for (int t = temp.length(); t < 2; t++) {147                 sb.append("0");148             }149             sb.append(temp);150         }151         return sb.toString();152     }153 154     public static byte[] hexToBytes(String str) {155         if (str == null) {156             return null;157         } else if (str.length() < 2) {158             return null;159         } else {160             int len = str.length() / 2;161             byte[] buffer = new byte[len];162             for (int i = 0; i < len; i++) {163                 buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);164             }165             return buffer;166         }167     }168 }

  因为客户端只负责数据加密,所以我这里只写了加密的部分。由于java和C#语言很相似,所以我就仿这他们给的java代码改成C#的,当然也在网上参考了一些代码,不过中间还是出现了些问题,比如C#不支持弱密钥(把密钥弄复杂点),因为没注意大小写造成加密结果不一致等等。编程这东西一个点都能让整个系统崩溃,所以小细节很重要!!!

 1     public class DESHelper 2     { 3         /// <summary> 4         /// 将密码转成直接数组 5         /// </summary> 6         /// <param name="str"></param> 7         /// <returns></returns> 8         public static byte[] HexToBytes(String str) 9         {10             if (str == null)11             {12                 return null;13             }14             else if (str.Length < 2)15             {16                 return null;17             }18             else19             {20                 int len = str.Length / 2;21                 byte[] buffer = new byte[len];22                 for (int i = 0; i < len; i++)23                 {24                     var temp = str.Substring(i * 2, 2);25                     buffer[i] = (byte)Convert.ToInt32(temp, 16);26                 }27                 return buffer;28             }29         }30         /// <summary>31         /// 3DES加密32         /// </summary>33         /// <param name="key"></param>34         /// <param name="data"></param>35         /// <returns></returns>36         public static byte[] GetDes3EncryptedText(byte[] key, byte[] data)37         {38             byte[] k = new byte[24];39             int len = data.Length;40             if (data.Length % 8 != 0)41             {42                 len = data.Length - data.Length % 8 + 8;43             }44             byte[] needData = null;45             if (len != 0)46                 needData = new byte[len];47 48             for (int i = 0; i < len; i++)49             {50                 needData[i] = 0x00;51             }52 53             Buffer.BlockCopy(data, 0, needData, 0, data.Length);54 55             if (key.Length == 16)56             {57                 Buffer.BlockCopy(key, 0, k, 0, key.Length);58                 Buffer.BlockCopy(key, 0, k, 16, 8);59             }60             else61             {62                 Buffer.BlockCopy(key, 0, k, 0, 24);63             }64 65             var des3 = new TripleDESCryptoServiceProvider();66             des3.Key = k;67             des3.Mode = CipherMode.ECB;68             des3.Padding = PaddingMode.Zeros;69 70             using (MemoryStream ms = new MemoryStream())71             using (CryptoStream cs = new CryptoStream(ms, des3.CreateEncryptor(), CryptoStreamMode.Write))72             {73                 cs.Write(data, 0, data.Length);74                 cs.FlushFinalBlock();75                 return ms.ToArray();76             }77         }78 79         /// <summary>80         /// 将加密结果转成字符串81         /// </summary>82         /// <param name="data"></param>83         /// <returns></returns>84         public static String GetByte2Hex(byte[] data)85         {86             StringBuilder sb = new StringBuilder();87             for (int i = 0; i < data.Length; i++)88             {89                 String temp = string.Format("{0:X}", ((int)data[i]) & 0xFF);90                 for (int t = temp.Length; t < 2; t++)91                 {92                     sb.Append("0");93                 }94                 sb.Append(temp);95             }96             return sb.ToString();97         }98     }