1. 程式人生 > >C#DES加密,JavaDES解密,另轉C#和Java實現Des完整程式碼

C#DES加密,JavaDES解密,另轉C#和Java實現Des完整程式碼

<span style="font-family: Arial, Helvetica, sans-serif;">今天,由於開發需要C#做DES加密,Java做DES解密,在實現時有這樣一個問題:C#做DES有加密向量IV,Java常見方式是沒有的。在解密時需要使用</span>
Cipher cipher = Cipher.getInstance ( "DES/CBC/PKCS5Padding" );       
       cipher.init(Cipher. DECRYPT_MODE , SecretKey mySecretKey , IvParameterSpec myIV);

而不是
Cipher cipher = Cipher.getInstance ( "DES" );
       cipher.init(Cipher. DECRYPT_MODE , Key key );

1、Java實現DES加解密(相容C#DES加解密)

package decryption;
 


import java.io.FileInputStream;  
import java.io.FileOutputStream; 
import java.io.InputStream;  
import java.io.OutputStream;  
import java.security.Key; 

import javax.crypto.Cipher;  
import javax.crypto.CipherInputStream;  
import javax.crypto.CipherOutputStream; 

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;



public class Decryption {
	 
    Key key ;
    SecretKey mySecretKey;
    IvParameterSpec myIV;
 
    public Decryption() {
 
    }
 
    public Decryption(String str) {
       setKey(str); // 生成密匙
    }
 
    public Key getKey() {
       return key ;
    }
 
    public void setKey(Key key) {
       this . key = key;
    }
 
    /**
      * 根據引數生成 KEY
      */
    public void setKey(String strKey) {
//       try {
//           KeyGenerator _generator = KeyGenerator.getInstance ( "DES" );
//           _generator.init( new SecureRandom(strKey.getBytes()));
//           this . key = _generator.generateKey();
//           _generator = null ;
//       } catch (Exception e) {
//           throw new RuntimeException(
//                  "Error initializing SqlMap class. Cause: " + e);
//       }
    	try {
      
       DESKeySpec dks = new DESKeySpec(strKey.getBytes("UTF-8"));
       
       SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
       SecretKey securekey = keyFactory.generateSecret(dks);
       this.mySecretKey=securekey;
       
       byte[] Keys =strKey.getBytes();
       IvParameterSpec iv = new IvParameterSpec(Keys);
       this.myIV=iv;
       
    	} catch (Exception e) {
    		throw new RuntimeException(e);
    	}
    }
 

  
  
    /**
      * 檔案 file 進行加密並儲存目標檔案 destFile 中
      *
      * @param file
      *             要加密的檔案 如 c:/test/srcFile.txt
      * @param destFile
      *             加密後存放的檔名 如 c:/ 加密後文件 .txt
      */
    public void encryptFile(String file, String destFile) throws Exception {
       //Cipher cipher = Cipher.getInstance ( "DES" );
       // cipher.init(Cipher.ENCRYPT_MODE, getKey());
      // cipher.init(Cipher. ENCRYPT_MODE , this . key );
       
    	Cipher cipher = Cipher.getInstance ( "DES/CBC/PKCS5Padding" );        
        
        cipher.init(Cipher. ENCRYPT_MODE , mySecretKey ,myIV);
       
       InputStream is = new FileInputStream(file);
       OutputStream out = new FileOutputStream(destFile);
       CipherInputStream cis = new CipherInputStream(is, cipher);
       byte [] buffer = new byte [1024];//原檔案長度和緩衝區大小沒有關係
       int r;
       while ((r = cis.read(buffer)) > 0) {
           out.write(buffer, 0, r);
       }
       cis.close();
       is.close();
       out.close();
    }
 
    /**
      * 檔案採用 DES 演算法解密檔案
      *
      * @param file
      *             已加密的檔案 如 c:/ 加密後文件 .txt *
      * @param destFile
      *             解密後存放的檔名 如 c:/ test/ 解密後文件 .txt
      */
    public void decryptFile(String file, String dest) throws Exception {
      // Cipher cipher = Cipher.getInstance ( "DES" );
      // cipher.init(Cipher. DECRYPT_MODE , this . key );
    	
       Cipher cipher = Cipher.getInstance ( "DES/CBC/PKCS5Padding" );
       
       cipher.init(Cipher. DECRYPT_MODE , mySecretKey ,myIV);
       
       InputStream is = new FileInputStream(file);
       OutputStream out = new FileOutputStream(dest);
       CipherOutputStream cos = new CipherOutputStream(out, cipher);
       byte [] buffer = new byte [1024];//原檔案長度和緩衝區大小沒有關係
       int r;
       while ((r = is.read(buffer)) >= 0) {
           cos.write(buffer, 0, r);
       }
       cos.close();
       out.close();
       is.close();
    }
    
 
    public static void main(String[] args) throws Exception {
       Decryption des = new Decryption( "12345678" );       
       
       //des.encryptFile("C:/Users/user/Desktop/TS1402883420_F1_D16_6_T9_50_20.mp4","C:/Users/user/Desktop/456.mp4");
       //des.decryptFile("C:/Users/user/Desktop/456.mp4","C:/Users/user/Desktop/789.mp4");
       des.decryptFile("C:/Users/user/Desktop/CSharpEncrypt.mp4","C:/Users/user/Desktop/xyz.mp4");
    }
} 

2、C#DES加解密

using System.Security.Cryptography;
using System.IO;
using System.Text;
using System;


namespace DES_CSharp
{
	public class Security
	    {
	
	        //預設金鑰向量
	        private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
	
	        /// <summary>
	        /// DES加密字串
	        /// </summary>
	        /// <param name="encryptString">待加密的字串</param>
	        /// <param name="encryptKey">加密金鑰,要求為8位</param>
	        /// <returns>加密成功返回加密後的字串,失敗返回源串</returns>
	        public static string EncryptDES(string encryptString, string encryptKey)
	        {
	            try
	            {
	                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
	                byte[] rgbIV = Keys;
	                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
	                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
	                MemoryStream mStream = new MemoryStream();
	                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
	                cStream.Write(inputByteArray, 0, inputByteArray.Length);
	                cStream.FlushFinalBlock();
	                return Convert.ToBase64String(mStream.ToArray());
	            }
	            catch
	            {
	                return encryptString;
	            }
	        }
	
	        /// <summary>
	        /// DES解密字串
	        /// </summary>
	        /// <param name="decryptString">待解密的字串</param>
	        /// <param name="decryptKey">解密金鑰,要求為8位,和加密金鑰相同</param>
	        /// <returns>解密成功返回解密後的字串,失敗返源串</returns>
	        public static string DecryptDES(string decryptString, string decryptKey)
	        {
	            try
	            {
	                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
	                byte[] rgbIV = Keys;
	                byte[] inputByteArray = Convert.FromBase64String(decryptString);
	                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
	                MemoryStream mStream = new MemoryStream();
	                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
	                cStream.Write(inputByteArray, 0, inputByteArray.Length);
	                cStream.FlushFinalBlock();
	                return Encoding.UTF8.GetString(mStream.ToArray());
	            }
	            catch
	            {
	                return decryptString;
	            }
	        }
	
	        #region 加密方法 圖片加密
	        /// <summary>
	        /// 圖片加密
	        /// </summary>
	        /// <param name="filePath">原始檔</param>
	        /// <param name="savePath">儲存為檔名稱</param>
	        /// <param name="keyStr">金鑰,要求為8位</param>
	        public static void EncryptFile(string filePath, string savePath, string keyStr)
	        {
	            //通過des加密
	            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
	            //通過流開啟檔案
	            FileStream fs = File.OpenRead(filePath);
	            //獲取檔案二進位制字元
	            byte[] inputByteArray = new byte[fs.Length];
	            //讀流檔案
	            fs.Read(inputByteArray, 0, (int)fs.Length);
	            //關閉流
	            fs.Close();
	            //獲得加密字串二進位制字元
	            byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
	
                ////計算指定位元組組指定區域雜湊值
                //SHA1 ha = new SHA1Managed();
                //byte[] hb = ha.ComputeHash(keyByteArray);
                ////加密金鑰陣列
                //byte[] sKey = new byte[8];
                ////加密變數
                //byte[] sIV = new byte[8];
                //for (int i = 0; i < 8; i++)
                //    sKey[i] = hb[i];
                //for (int i = 8; i < 16; i++)
                //    sIV[i - 8] = hb[i];
                byte[] sKey = keyByteArray;
                byte[] sIV = keyByteArray;
	            //獲取加密金鑰	
	            des.Key = sKey;
	            //設定加密初始化向量
	            des.IV = sIV;
	            MemoryStream ms = new MemoryStream();
	            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
	            cs.Write(inputByteArray, 0, inputByteArray.Length);
	            cs.FlushFinalBlock();
	            fs = File.OpenWrite(savePath);
	            foreach (byte b in ms.ToArray())
	            {
	                fs.WriteByte(b);
	
	            }
	            fs.Close();
	            cs.Close();
	            ms.Close();
	        }
	        #endregion
	
	        #region 解密方法 圖片解密
	        /// <summary>
	        /// 圖片解密
	        /// </summary>
	        /// <param name="filePath">原始檔</param>
	        /// <param name="savePath">儲存檔案</param>
	        /// <param name="keyStr">金鑰,要求為8位</param>
	        public static void DecryptFile(string filePath, string savePath, string keyStr)
	        {
	            //通過des解密
	            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
	
	            //通過流讀取檔案
	            FileStream fs = File.OpenRead(filePath);
	            //獲取檔案二進位制字元
	            byte[] inputByteArray = new byte[fs.Length];
	            //讀取流檔案
	            fs.Read(inputByteArray, 0, (int)fs.Length);
	            //關閉流
	            fs.Close();
	            //金鑰陣列
	            byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
                ////定義雜湊變數
                //SHA1 ha = new SHA1Managed();
                ////計算指定位元組組指定區域雜湊值
                //byte[] hb = ha.ComputeHash(keyByteArray);
                ////加密金鑰陣列
                //byte[] sKey = new byte[8];
                ////加密變數
                //byte[] sIV = new byte[8];
                //for (int i = 0; i < 8; i++)
                //    sKey[i] = hb[i];
                //for (int i = 8; i < 16; i++)
                //    sIV[i - 8] = hb[i];

                byte[] sKey = keyByteArray;
                byte[] sIV = keyByteArray;

	            //獲取加密金鑰
	            des.Key = sKey;
	            //加密變數
	            des.IV = sIV;
	            MemoryStream ms = new MemoryStream();
	            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
	            cs.Write(inputByteArray, 0, inputByteArray.Length);
	            cs.FlushFinalBlock();
	            fs = File.OpenWrite(savePath);
	            foreach (byte b in ms.ToArray())
	            {
	                fs.WriteByte(b);
	            }
	            fs.Close();
	            cs.Close();
	            ms.Close();
	        }
	        #endregion
	
	        #region 加密方法 圖片加密
	        /// <summary>
	        /// 圖片加密
	        /// </summary>
	        /// <param name="filePath">加密檔案位元組陣列</param>
	        /// <param name="savePath">儲存為檔名稱</param>
	        /// <param name="keyStr">金鑰,要求為8位</param>
	        public static void EncryptFile(byte[] inputByteArray, string savePath, string keyStr)
	        {
	            try
	            {
	                //通過des加密
	                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
	                //獲得加密字串二進位制字元
	                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
	
	                //計算指定位元組組指定區域雜湊值
	                SHA1 ha = new SHA1Managed();
	                byte[] hb = ha.ComputeHash(keyByteArray);
	                //加密金鑰陣列
	                byte[] sKey = new byte[8];
	                //加密變數
	                byte[] sIV = new byte[8];
	                for (int i = 0; i < 8; i++)
	                    sKey[i] = hb[i];
	                for (int i = 8; i < 16; i++)
	                    sIV[i - 8] = hb[i];
	                //獲取加密金鑰
	
	                des.Key = sKey;
	                //設定加密初始化向量
	                des.IV = sIV;
	                MemoryStream ms = new MemoryStream();
	                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
	                cs.Write(inputByteArray, 0, inputByteArray.Length);
	                cs.FlushFinalBlock();
	                FileStream fs = File.OpenWrite(savePath);
	                foreach (byte b in ms.ToArray())
	                {
	                    fs.WriteByte(b);
	
	                }
	                fs.Close();
	                cs.Close();
	                ms.Close();
	            }
	            catch (Exception ex)
	            {
	                System.Diagnostics.Trace.Write(ex.Message);
	            }
	        }
	        #endregion
	
	        #region 解密方法 圖片解密
	        /// <summary>
	        /// 圖片解密
	        /// </summary>
	        /// <param name="filePath">原始檔</param>
	        /// <param name="savePath">儲存檔案</param>
	        /// <param name="keyStr">金鑰,要求為8位</param>
	        /// <returns>返回解密後的檔案位元組陣列</returns>
	        public static byte[] DecryptFile(string filePath, string keyStr)
	        {
	            try
	            {
	                //通過des解密
	                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
	
	                //通過流讀取檔案
	                FileStream fs = File.OpenRead(filePath);
	                //獲取檔案二進位制字元
	                byte[] inputByteArray = new byte[fs.Length];
	                //讀取流檔案
	                fs.Read(inputByteArray, 0, (int)fs.Length);
	                //關閉流
	                fs.Close();
	                //金鑰陣列
	                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
	                //定義雜湊變數
	                SHA1 ha = new SHA1Managed();
	                //計算指定位元組組指定區域雜湊值
	                byte[] hb = ha.ComputeHash(keyByteArray);
	                //加密金鑰陣列
	                byte[] sKey = new byte[8];
	                //加密變數
	                byte[] sIV = new byte[8];
	                for (int i = 0; i < 8; i++)
	                    sKey[i] = hb[i];
	                for (int i = 8; i < 16; i++)
	                    sIV[i - 8] = hb[i];
	                //獲取加密金鑰
	                des.Key = sKey;
	                //加密變數
	                des.IV = sIV;
	                MemoryStream ms = new MemoryStream();
	                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
	                cs.Write(inputByteArray, 0, inputByteArray.Length);
	                cs.FlushFinalBlock();
	                byte[] b = ms.ToArray();
	                cs.Close();
	                ms.Close();
	                return b;
	            }
	            catch (Exception ex)
	            {
	                System.Diagnostics.Trace.Write(ex.Message);
	                return null;
	            }
	        }
	        #endregion
	    }
}

3、JavaDES加解密

package  test;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.SecureRandom;
 
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
 
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
 
public class DESUtil {
 
    Key key ;
 
    public DESUtil() {
 
    }
 
    public DESUtil(String str) {
       setKey(str); // 生成密匙
    }
 
    public Key getKey() {
       return key ;
    }
 
    public void setKey(Key key) {
       this . key = key;
    }
 
    /**
      * 根據引數生成 KEY
      */
    public void setKey(String strKey) {
       try {
           KeyGenerator _generator = KeyGenerator.getInstance ( "DES" );
           _generator.init( new SecureRandom(strKey.getBytes()));
           this . key = _generator.generateKey();
           _generator = null ;
       } catch (Exception e) {
           throw new RuntimeException(
                  "Error initializing SqlMap class. Cause: " + e);
       }
    }
 
    /**
      * 加密 String 明文輸入 ,String 密文輸出
      */
    public String encryptStr(String strMing) {
       byte [] byteMi = null ;
       byte [] byteMing = null ;
       String strMi = "" ;
       BASE64Encoder base64en = new BASE64Encoder();
       try {
           byteMing = strMing.getBytes( "UTF8" );
           byteMi = this .encryptByte(byteMing);
           strMi = base64en.encode(byteMi);
       } catch (Exception e) {
           throw new RuntimeException(
                  "Error initializing SqlMap class. Cause: " + e);
       } finally {
           base64en = null ;
           byteMing = null ;
           byteMi = null ;
       }
       return strMi;
    }
 
    /**
      * 解密 以 String 密文輸入 ,String 明文輸出
      *
      * @param strMi
      * @return
      */
    public String decryptStr(String strMi) {
       BASE64Decoder base64De = new BASE64Decoder();
       byte [] byteMing = null ;
       byte [] byteMi = null ;
       String strMing = "" ;
       try {
           byteMi = base64De.decodeBuffer(strMi);
           byteMing = this .decryptByte(byteMi);
           strMing = new String(byteMing, "UTF8" );
       } catch (Exception e) {
           throw new RuntimeException(
                  "Error initializing SqlMap class. Cause: " + e);
       } finally {
           base64De = null ;
           byteMing = null ;
           byteMi = null ;
       }
       return strMing;
    }
 
    /**
      * 加密以 byte[] 明文輸入 ,byte[] 密文輸出
      *
      * @param byteS
      * @return
      */
    private byte [] encryptByte( byte [] byteS) {
       byte [] byteFina = null ;
       Cipher cipher;
       try {
           cipher = Cipher.getInstance ( "DES" );
           cipher.init(Cipher. ENCRYPT_MODE , key );
           byteFina = cipher.doFinal(byteS);
       } catch (Exception e) {
           throw new RuntimeException(
                  "Error initializing SqlMap class. Cause: " + e);
       } finally {
           cipher = null ;
       }
       return byteFina;
    }
 
    /**
      * 解密以 byte[] 密文輸入 , 以 byte[] 明文輸出
      *
      * @param byteD
      * @return
      */
    private byte [] decryptByte( byte [] byteD) {
       Cipher cipher;
       byte [] byteFina = null ;
       try {
           cipher = Cipher.getInstance ( "DES" );
           cipher.init(Cipher. DECRYPT_MODE , key );
           byteFina = cipher.doFinal(byteD);
       } catch (Exception e) {
           throw new RuntimeException(
                  "Error initializing SqlMap class. Cause: " + e);
       } finally {
           cipher = null ;
       }
       return byteFina;
    }
 
    /**
      * 檔案 file 進行加密並儲存目標檔案 destFile 中
      *
      * @param file
      *             要加密的檔案 如 c:/test/srcFile.txt
      * @param destFile
      *             加密後存放的檔名 如 c:/ 加密後文件 .txt
      */
    public void encryptFile(String file, String destFile) throws Exception {
       Cipher cipher = Cipher.getInstance ( "DES" );
       // cipher.init(Cipher.ENCRYPT_MODE, getKey());
       cipher.init(Cipher. ENCRYPT_MODE , this . key );
       InputStream is = new FileInputStream(file);
       OutputStream out = new FileOutputStream(destFile);
       CipherInputStream cis = new CipherInputStream(is, cipher);
       byte [] buffer = new byte [1024];
       int r;
       while ((r = cis.read(buffer)) > 0) {
           out.write(buffer, 0, r);
       }
       cis.close();
       is.close();
       out.close();
    }
 
    /**
      * 檔案採用 DES 演算法解密檔案
      *
      * @param file
      *             已加密的檔案 如 c:/ 加密後文件 .txt *
      * @param destFile
      *             解密後存放的檔名 如 c:/ test/ 解密後文件 .txt
      */
    public void decryptFile(String file, String dest) throws Exception {
       Cipher cipher = Cipher.getInstance ( "DES" );
       cipher.init(Cipher. DECRYPT_MODE , this . key );
       InputStream is = new FileInputStream(file);
       OutputStream out = new FileOutputStream(dest);
       CipherOutputStream cos = new CipherOutputStream(out, cipher);
       byte [] buffer = new byte [1024];
       int r;
       while ((r = is.read(buffer)) >= 0) {
           cos.write(buffer, 0, r);
       }
       cos.close();
       out.close();
       is.close();
    }
 
    public static void main(String[] args) throws Exception {
       DESUtil des = new DESUtil( "1234567" );
       // DES 加密檔案
       // des.encryptFile("G:/test.doc", "G:/ 加密 test.doc");
       // DES 解密檔案
       // des.decryptFile("G:/ 加密 test.doc", "G:/ 解密 test.doc");
       String str1 = " 要加密的字串 test" ;
       // DES 加密字串
       String str2 = des.encryptStr(str1);
       // DES 解密字串
       String deStr = des.decryptStr(str2);
       System. out .println( " 加密前: " + str1);
       System. out .println( " 加密後: " + str2);
       System. out .println( " 解密後: " + deStr);
    }
}