首页 > 代码库 > C# Java 3DES加密解密 扩展及修正\0 问题

C# Java 3DES加密解密 扩展及修正\0 问题

 

注: C#已亲测及做扩展, Java 部分未做验证

/// <summary>
/// 3DES加密解密
/// -----------------------------------------------------------
/// 说明:
/// 转载自网上http://bbs.csdn.net/topics/350158619
/// 并加以扩展
/// 修正:
/// 1. 修改正解密后出现 ‘\0‘
/// 注: 1. 向量不能小于8位
/// 2. 明文末尾如果是带‘\0‘字符,则会一起去掉
/// -----------------------------------------------------------
/// 扩展人:Wuyf    11222337#qq.com
/// 日 期:2014-11-29
/// </summary>

 

C# 代码 

  1 using System;  2 using System.Collections.Generic;  3 using System.IO;  4 using System.Linq;  5 using System.Security.Cryptography;  6 using System.Text;  7 using System.Web;  8   9 namespace WuFrame.Tool 10 { 11  12     /// <summary> 13     /// 3DES加密解密 14     /// ----------------------------------------------------------- 15     /// 说明: 16     ///     转载自网上http://bbs.csdn.net/topics/350158619 17     ///     并加以扩展 18     /// 修正: 19     ///     1. 修改正解密后出现 ‘\0‘ 20     /// 注: 1. 向量不能小于8位 21     ///     2. 明文末尾如果是带‘\0‘字符,则会一起去掉 22     /// ----------------------------------------------------------- 23     /// 扩展人:Wuyf 11222337#qq.com 24     /// 日  期:2014-11-29 25     /// </summary> 26     public class Des3Tool 27     { 28         #region CBC模式** 29  30         #region 扩展方法 31          32         /// <summary> 33         /// 3DES 加密(字符串参数和返回值) 34         /// </summary> 35         /// <param name="key">密钥</param> 36         /// <param name="iv">向量</param> 37         /// <param name="data">明文</param> 38         /// <param name="isRetBase64">true:返回base64,false:返回Utf8</param> 39         /// <returns></returns> 40         public static string Des3EncodeCBC(string key, string iv, string data) 41         { 42             string rtnResult = string.Empty; 43             byte[] rtnValue = http://www.mamicode.com/null; 44             byte[] keyArr = Encoding.UTF8.GetBytes(key); 45             byte[] ivArr = Encoding.UTF8.GetBytes(iv); 46             byte[] dataArr = Encoding.UTF8.GetBytes(data); 47  48             rtnValue =http://www.mamicode.com/ Des3EncodeCBC(keyArr, ivArr, dataArr); 49  50             rtnResult = Convert.ToBase64String(rtnValue); 51  52             return rtnResult; 53         } 54  55         /// <summary> 56         /// 3DES 解密(字符串参数和返回值) 57         /// </summary> 58         /// <param name="key">密钥</param> 59         /// <param name="iv">向量</param> 60         /// <param name="data">明文</param> 61         /// <returns></returns> 62         public static string Des3DecodeCBC(string key, string iv, string dataEnBase64) 63         { 64             string rtnResult = string.Empty; 65             byte[] rtnValue = http://www.mamicode.com/null; 66             byte[] keyArr = Encoding.UTF8.GetBytes(key); 67             byte[] ivArr = Encoding.UTF8.GetBytes(iv); 68             byte[] dataArr = Convert.FromBase64String(dataEnBase64); 69  70             rtnValue =http://www.mamicode.com/ Des3DecodeCBC(keyArr, ivArr, dataArr); 71  72             rtnResult = Encoding.UTF8.GetString(rtnValue).TrimEnd(\0);    // 去除多余空字符 73  74             return rtnResult; 75         } 76  77         /// <summary> 78         /// 3DES 解密(字符串参数和返回值) 79         /// </summary> 80         /// <param name="key">密钥</param> 81         /// <param name="iv">向量</param> 82         /// <param name="data">明文</param> 83         /// <returns></returns> 84         public static string Des3DecodeCBC(string key, string iv, byte[] dataArr) 85         { 86             string rtnResult = string.Empty; 87             byte[] rtnValue = http://www.mamicode.com/null; 88             byte[] keyArr = Encoding.UTF8.GetBytes(key); 89             byte[] ivArr = Encoding.UTF8.GetBytes(iv); 90  91             rtnValue =http://www.mamicode.com/ Des3DecodeCBC(keyArr, ivArr, dataArr); 92  93             rtnResult = Encoding.UTF8.GetString(rtnValue).TrimEnd(\0);    // 去除多余空字符 94  95             return rtnResult; 96         } 97  98         #endregion 99 100         #region 原加解密方法101         102 103         /// <summary>104         /// DES3 CBC模式加密105         /// </summary>106         /// <param name="key">密钥</param>107         /// <param name="iv">IV</param>108         /// <param name="data">明文的byte数组</param>109         /// <returns>密文的byte数组</returns>110         public static byte[] Des3EncodeCBC(byte[] key, byte[] iv, byte[] data)111         {112             //复制于MSDN113 114             try115             {116                 // Create a MemoryStream.117                 MemoryStream mStream = new MemoryStream();118 119                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();120                 tdsp.Mode = CipherMode.CBC;             //默认值121                 tdsp.Padding = PaddingMode.PKCS7;       //默认值122 123                 // Create a CryptoStream using the MemoryStream 124                 // and the passed key and initialization vector (IV).125                 CryptoStream cStream = new CryptoStream(mStream,126                     tdsp.CreateEncryptor(key, iv),127                     CryptoStreamMode.Write);128 129                 // Write the byte array to the crypto stream and flush it.130                 cStream.Write(data, 0, data.Length);131                 cStream.FlushFinalBlock();132 133                 // Get an array of bytes from the 134                 // MemoryStream that holds the 135                 // encrypted data.136                 byte[] ret = mStream.ToArray();137 138                 // Close the streams.139                 cStream.Close();140                 mStream.Close();141 142                 // Return the encrypted buffer.143                 return ret;144             }145             catch (CryptographicException e)146             {147                 Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);148                 return null;149             }150         }151 152         /// <summary>153         /// DES3 CBC模式解密154         /// </summary>155         /// <param name="key">密钥</param>156         /// <param name="iv">IV</param>157         /// <param name="data">密文的byte数组</param>158         /// <returns>明文的byte数组</returns>159         public static byte[] Des3DecodeCBC(byte[] key, byte[] iv, byte[] data)160         {161             try162             {163                 // Create a new MemoryStream using the passed 164                 // array of encrypted data.165                 MemoryStream msDecrypt = new MemoryStream(data);166 167                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();168                 tdsp.Mode = CipherMode.CBC;169                 tdsp.Padding = PaddingMode.PKCS7;170 171                 // Create a CryptoStream using the MemoryStream 172                 // and the passed key and initialization vector (IV).173                 CryptoStream csDecrypt = new CryptoStream(msDecrypt,174                     tdsp.CreateDecryptor(key, iv),175                     CryptoStreamMode.Read);176 177                 // Create buffer to hold the decrypted data.178                 byte[] fromEncrypt = new byte[data.Length];179 180                 // Read the decrypted data out of the crypto stream181                 // and place it into the temporary buffer.182                 csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);183 184                 //Convert the buffer into a string and return it.185                 return fromEncrypt;186             }187             catch (CryptographicException e)188             {189                 Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);190                 return null;191             }192         }193 194         #endregion195 196         #endregion197 198         #region ECB模式199 200         #region 不提供Iv(扩展方法)201 202         private static string ivDefault = "12345678";203 204         /// <summary>205         /// 3DES 加密(字符串参数和返回值)206         /// </summary>207         /// <param name="key">密钥</param>208         /// <param name="iv">向量</param>209         /// <param name="data">明文</param>210         /// <param name="isRetBase64">true:返回base64,false:返回Utf8</param>211         /// <returns></returns>212         public static string Des3EncodeECB(string key, string data)213         {214             string rtnResult = string.Empty;215             byte[] rtnValue = http://www.mamicode.com/null;216             byte[] keyArr = Encoding.UTF8.GetBytes(key);217             byte[] ivArr = Encoding.UTF8.GetBytes(ivDefault);218             byte[] dataArr = Encoding.UTF8.GetBytes(data);219 220             rtnValue =http://www.mamicode.com/ Des3EncodeCBC(keyArr, ivArr, dataArr);221 222             rtnResult = Convert.ToBase64String(rtnValue);223 224             return rtnResult;225         }226 227         /// <summary>228         /// 3DES 解密(字符串参数和返回值)229         /// </summary>230         /// <param name="key">密钥</param>231         /// <param name="iv">向量</param>232         /// <param name="data">明文</param>233         /// <returns></returns>234         public static string Des3DecodeECB(string key, string dataEnBase64)235         {236             string rtnResult = string.Empty;237             byte[] rtnValue = http://www.mamicode.com/null;238             byte[] keyArr = Encoding.UTF8.GetBytes(key);239             byte[] ivArr = Encoding.UTF8.GetBytes(ivDefault);240             byte[] dataArr = Convert.FromBase64String(dataEnBase64);241 242             rtnValue =http://www.mamicode.com/ Des3DecodeCBC(keyArr, ivArr, dataArr);243 244             rtnResult = Encoding.UTF8.GetString(rtnValue).TrimEnd(\0);    // 去除多余空字符245 246             return rtnResult;247         }248 249         /// <summary>250         /// 3DES 解密(字符串参数和返回值)251         /// </summary>252         /// <param name="key">密钥</param>253         /// <param name="iv">向量</param>254         /// <param name="data">明文</param>255         /// <returns></returns>256         public static string Des3DecodeECB(string key, byte[] dataArr)257         {258             string rtnResult = string.Empty;259             byte[] rtnValue = http://www.mamicode.com/null;260             byte[] keyArr = Encoding.UTF8.GetBytes(key);261             byte[] ivArr = Encoding.UTF8.GetBytes(ivDefault);262 263             rtnValue =http://www.mamicode.com/ Des3DecodeECB(keyArr, ivArr, dataArr);264 265             rtnResult = Encoding.UTF8.GetString(rtnValue).TrimEnd(\0);    // 去除多余空字符266 267             return rtnResult;268         }269         #endregion270 271         #region 提供Iv(扩展方法)272 273 274         /// <summary>275         /// 3DES 加密(字符串参数和返回值)276         /// </summary>277         /// <param name="key">密钥</param>278         /// <param name="iv">向量</param>279         /// <param name="data">明文</param>280         /// <param name="isRetBase64">true:返回base64,false:返回Utf8</param>281         /// <returns></returns>282         public static string Des3EncodeECB(string key, string iv, string data)283         {284             string rtnResult = string.Empty;285             byte[] rtnValue = http://www.mamicode.com/null;286             byte[] keyArr = Encoding.UTF8.GetBytes(key);287             byte[] ivArr = Encoding.UTF8.GetBytes(iv);288             byte[] dataArr = Encoding.UTF8.GetBytes(data);289 290             rtnValue =http://www.mamicode.com/ Des3EncodeCBC(keyArr, ivArr, dataArr);291 292             rtnResult = Convert.ToBase64String(rtnValue);293 294             return rtnResult;295         }296 297         /// <summary>298         /// 3DES 解密(字符串参数和返回值)299         /// </summary>300         /// <param name="key">密钥</param>301         /// <param name="iv">向量</param>302         /// <param name="data">明文</param>303         /// <returns></returns>304         public static string Des3DecodeECB(string key, string iv, string dataEnBase64)305         {306             string rtnResult = string.Empty;307             byte[] rtnValue = http://www.mamicode.com/null;308             byte[] keyArr = Encoding.UTF8.GetBytes(key);309             byte[] ivArr = Encoding.UTF8.GetBytes(iv);310             byte[] dataArr = Convert.FromBase64String(dataEnBase64);311 312             rtnValue =http://www.mamicode.com/ Des3DecodeCBC(keyArr, ivArr, dataArr);313 314             rtnResult = Encoding.UTF8.GetString(rtnValue).TrimEnd(\0);    // 去除多余空字符315 316             return rtnResult;317         }318 319         /// <summary>320         /// 3DES 解密(字符串参数和返回值)321         /// </summary>322         /// <param name="key">密钥</param>323         /// <param name="iv">向量</param>324         /// <param name="data">明文</param>325         /// <returns></returns>326         public static string Des3DecodeECB(string key, string iv, byte[] dataArr)327         {328             string rtnResult = string.Empty;329             byte[] rtnValue = http://www.mamicode.com/null;330             byte[] keyArr = Encoding.UTF8.GetBytes(key);331             byte[] ivArr = Encoding.UTF8.GetBytes(iv);332 333             rtnValue =http://www.mamicode.com/ Des3DecodeECB(keyArr, ivArr, dataArr);334 335             rtnResult = Encoding.UTF8.GetString(rtnValue).TrimEnd(\0);    // 去除多余空字符336 337             return rtnResult;338         }339 340         #endregion341 342         #region 原加解密方法343         344 345         /// <summary>346         /// DES3 ECB模式加密347         /// </summary>348         /// <param name="key">密钥</param>349         /// <param name="iv">IV(当模式为ECB时,IV无用)</param>350         /// <param name="str">明文的byte数组</param>351         /// <returns>密文的byte数组</returns>352         public static byte[] Des3EncodeECB(byte[] key, byte[] iv, byte[] data)353         {354             try355             {356                 // Create a MemoryStream.357                 MemoryStream mStream = new MemoryStream();358 359                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();360                 tdsp.Mode = CipherMode.ECB;361                 tdsp.Padding = PaddingMode.PKCS7;362                 // Create a CryptoStream using the MemoryStream 363                 // and the passed key and initialization vector (IV).364                 CryptoStream cStream = new CryptoStream(mStream,365                     tdsp.CreateEncryptor(key, iv),366                     CryptoStreamMode.Write);367 368                 // Write the byte array to the crypto stream and flush it.369                 cStream.Write(data, 0, data.Length);370                 cStream.FlushFinalBlock();371 372                 // Get an array of bytes from the 373                 // MemoryStream that holds the 374                 // encrypted data.375                 byte[] ret = mStream.ToArray();376 377                 // Close the streams.378                 cStream.Close();379                 mStream.Close();380 381                 // Return the encrypted buffer.382                 return ret;383             }384             catch (CryptographicException e)385             {386                 Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);387                 return null;388             }389 390         }391 392         /// <summary>393         /// DES3 ECB模式解密394         /// </summary>395         /// <param name="key">密钥</param>396         /// <param name="iv">IV(当模式为ECB时,IV无用)</param>397         /// <param name="str">密文的byte数组</param>398         /// <returns>明文的byte数组</returns>399         public static byte[] Des3DecodeECB(byte[] key, byte[] iv, byte[] data)400         {401             try402             {403                 // Create a new MemoryStream using the passed 404                 // array of encrypted data.405                 MemoryStream msDecrypt = new MemoryStream(data);406 407                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();408                 tdsp.Mode = CipherMode.ECB;409                 tdsp.Padding = PaddingMode.PKCS7;410 411                 // Create a CryptoStream using the MemoryStream 412                 // and the passed key and initialization vector (IV).413                 CryptoStream csDecrypt = new CryptoStream(msDecrypt,414                     tdsp.CreateDecryptor(key, iv),415                     CryptoStreamMode.Read);416 417                 // Create buffer to hold the decrypted data.418                 byte[] fromEncrypt = new byte[data.Length];419 420                 // Read the decrypted data out of the crypto stream421                 // and place it into the temporary buffer.422                 csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);423 424                 //Convert the buffer into a string and return it.425                 return fromEncrypt;426             }427             catch (CryptographicException e)428             {429                 Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);430                 return null;431             }432         }433 434         #endregion435 436         #endregion437 438         /// <summary>439         /// 类测试440         /// </summary>441         public static void Test()442         {443             System.Text.Encoding utf8 = System.Text.Encoding.UTF8;444 445             // 扩展方法测试446             string keyExt = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4";447             string ivExt = "12345678";448             string dataExt = "吴@#@\0\n";449 450             // CBC 模式451             string tmpEnCBC = Des3Tool.Des3EncodeCBC(keyExt, ivExt, dataExt);       // 返回 base64452             string tmpDeCBC = Des3Tool.Des3DecodeCBC(keyExt, ivExt, tmpEnCBC);       // 返回 utf8格式字符串453 454             System.Console.WriteLine(tmpEnCBC);455             System.Console.WriteLine(tmpDeCBC);456 457             System.Console.WriteLine();458 459             // ECB 带 iv460             string tmpEnECB = Des3Tool.Des3DecodeECB(keyExt, ivExt, dataExt);       // 返回 base64461             string tmpDeECB = Des3Tool.Des3DecodeECB(keyExt, ivExt, tmpEnECB);       // 返回 utf8格式字符串462 463             System.Console.WriteLine(tmpEnECB);464             System.Console.WriteLine(tmpDeECB);465 466             System.Console.WriteLine();467 468             // ECB 不带 iv469             string tmpEnECBNoIv = Des3Tool.Des3DecodeECB(keyExt, dataExt);       // 返回 base64470             string tmpDeECBNoIv = Des3Tool.Des3DecodeECB(keyExt, tmpEnECBNoIv);       // 返回 utf8格式字符串471 472             System.Console.WriteLine(tmpEnECBNoIv);473             System.Console.WriteLine(tmpDeECBNoIv);474 475             System.Console.WriteLine();476 477 478 479             //key为abcdefghijklmnopqrstuvwx的Base64编码480             byte[] key = Convert.FromBase64String("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");481             byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };      //当模式为ECB时,IV无用482             byte[] data = http://www.mamicode.com/utf8.GetBytes("中国ABCabc123");483 484             System.Console.WriteLine("ECB模式:");485             byte[] str1 = Des3Tool.Des3EncodeECB(key, iv, data);486             byte[] str2 = Des3Tool.Des3DecodeECB(key, iv, str1);487             System.Console.WriteLine(Convert.ToBase64String(str1));488             System.Console.WriteLine(System.Text.Encoding.UTF8.GetString(str2));489 490             System.Console.WriteLine();491 492             System.Console.WriteLine("CBC模式:");493             byte[] str3 = Des3Tool.Des3EncodeCBC(key, iv, data);494             byte[] str4 = Des3Tool.Des3DecodeCBC(key, iv, str3);495             System.Console.WriteLine(Convert.ToBase64String(str3));496             System.Console.WriteLine(utf8.GetString(str4));497 498             System.Console.WriteLine();499 500         }501 502     }503 504 }

 

Java 代码

import java.security.Key;import javax.crypto.Cipher;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESedeKeySpec;import javax.crypto.spec.IvParameterSpec;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class Des3 {    public static void main(String[] args) throws Exception {        byte[] key=new BASE64Decoder().decodeBuffer("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");        byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };        byte[] data="http://www.mamicode.com/中国ABCabc123".getBytes("UTF-8");                System.out.println("ECB加密解密");        byte[] str3 = des3EncodeECB(key,data );        byte[] str4 = ees3DecodeECB(key, str3);        System.out.println(new BASE64Encoder().encode(str3));        System.out.println(new String(str4, "UTF-8"));        System.out.println();        System.out.println("CBC加密解密");        byte[] str5 = des3EncodeCBC(key, keyiv, data);        byte[] str6 = des3DecodeCBC(key, keyiv, str5);        System.out.println(new BASE64Encoder().encode(str5));        System.out.println(new String(str6, "UTF-8"));    }    /**     * ECB加密,不要IV     * @param key 密钥     * @param data 明文     * @return Base64编码的密文     * @throws Exception     */    public static byte[] des3EncodeECB(byte[] key, byte[] data)            throws Exception {        Key deskey = null;        DESedeKeySpec spec = new DESedeKeySpec(key);        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");        deskey = keyfactory.generateSecret(spec);        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");        cipher.init(Cipher.ENCRYPT_MODE, deskey);        byte[] bOut = cipher.doFinal(data);        return bOut;    }    /**     * ECB解密,不要IV     * @param key 密钥     * @param data Base64编码的密文     * @return 明文     * @throws Exception     */    public static byte[] ees3DecodeECB(byte[] key, byte[] data)            throws Exception {        Key deskey = null;        DESedeKeySpec spec = new DESedeKeySpec(key);        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");        deskey = keyfactory.generateSecret(spec);        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");        cipher.init(Cipher.DECRYPT_MODE, deskey);        byte[] bOut = cipher.doFinal(data);        return bOut;    }    /**     * CBC加密     * @param key 密钥     * @param keyiv IV     * @param data 明文     * @return Base64编码的密文     * @throws Exception     */    public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data)            throws Exception {        Key deskey = null;        DESedeKeySpec spec = new DESedeKeySpec(key);        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");        deskey = keyfactory.generateSecret(spec);        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");        IvParameterSpec ips = new IvParameterSpec(keyiv);        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);        byte[] bOut = cipher.doFinal(data);        return bOut;    }    /**     * CBC解密     * @param key 密钥     * @param keyiv IV     * @param data Base64编码的密文     * @return 明文     * @throws Exception     */    public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)            throws Exception {        Key deskey = null;        DESedeKeySpec spec = new DESedeKeySpec(key);        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");        deskey = keyfactory.generateSecret(spec);        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");        IvParameterSpec ips = new IvParameterSpec(keyiv);        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);        byte[] bOut = cipher.doFinal(data);        return bOut;    }}

 

C# Java 3DES加密解密 扩展及修正\0 问题