PHP DES/ECB/pkcs5padding加密,與java互通

環境:php5.6

最近遇到需要跟java系統實現des加密互通,網上找了很多,加密都不對,自己整理了一個des ecb加密類

java版代碼如下:

	// 密鑰,是加密解密的憑據,長度爲8的倍數
	private static final String PASSWORD_CRYPT_KEY = "密鑰";
	//加密方式是des
	private final static String DES = "DES";

	public static void main(String args[]) {
        String basestr = "panpan";
        String str1 = encrypt(basestr);

        System.out.println("原始值: " + basestr);
        System.out.println("加密後: " + str1);
        System.out.println("解密後: " + decrypt(str1));
        System.out.println("爲空時 is : " + decrypt(encrypt("")));
    }

	/**
     * 加密
     * @param src 數據源
     * @param key 密鑰,長度必須是8的倍數
     * @return 返回加密後的數據
     * @throws Exception
     */
    public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
 
        // DES算法要求有一個可信任的隨機數源
        SecureRandom sr = new SecureRandom();
 
        // 從原始密匙數據創建DESKeySpec對象
        DESKeySpec dks = new DESKeySpec(key);
 
        // 創建一個密匙工廠,然後用它把DESKeySpec轉換成
        // 一個SecretKey對象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
 
        SecretKey securekey = keyFactory.generateSecret(dks);
 
        // Cipher對象實際完成加密操作
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
 
        // 用密匙初始化Cipher對象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
 
        // 現在,獲取數據並加密
        // 正式執行加密操作
        return cipher.doFinal(src);
 
    }
 
    /**
     * 解密
     * @param src 數據源
     * @param key 密鑰,長度必須是8的倍數
     * @return 返回解密後的原始數據
     * @throws Exception
     */
    public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
 
        // DES算法要求有一個可信任的隨機數源
        SecureRandom sr = new SecureRandom();
        // 從原始密匙數據創建一個DESKeySpec對象
        DESKeySpec dks = new DESKeySpec(key);
 
        // 創建一個密匙工廠,然後用它把DESKeySpec對象轉換成
        // 一個SecretKey對象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
 
        SecretKey securekey = keyFactory.generateSecret(dks);
 
        // Cipher對象實際完成解密操作
        Cipher cipher = Cipher.getInstance(DES);
 
        // 用密匙初始化Cipher對象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
 
        // 現在,獲取數據並解密
        // 正式執行解密操作
        return cipher.doFinal(src);
 
    }
 
    /**
     * 密碼解密
     * @param data
     * @return
     * @throws Exception
     */
    public final static String decrypt(String data) {
 
        try {
            String result = new String(decrypt(hex2byte(data.getBytes()), PASSWORD_CRYPT_KEY.getBytes()));
            System.out.println(result);
            return result;
        } catch (Exception e) {
            System.out.println(e);
            return data;
        }
//        return null;
    }
 
    /**
     * 密碼加密
     * @param password
     * @return
     * @throws Exception
     */
    public final static String encrypt(String password) {
        try {
            return byte2hex(encrypt(password.getBytes(), PASSWORD_CRYPT_KEY.getBytes()));
        } catch (Exception e) {
 
        }
        return null;
    }
 
    /**
     * 二行制轉字符串
     * @param b
     * @return
     */
    public static String byte2hex(byte[] b) {
 
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1)
                hs = hs + "0" + stmp;
            else
                hs = hs + stmp;
        }
        return hs.toUpperCase();
    }
 
    public static byte[] hex2byte(byte[] b) {
 
        if ((b.length % 2) != 0)
            throw new IllegalArgumentException("長度不是偶數");
        byte[] b2 = new byte[b.length / 2];
        for (int n = 0; n < b.length; n += 2) {
            String item = new String(b, n, 2);
            b2[n / 2] = (byte) Integer.parseInt(item, 16);
        }
        return b2;
    }

php代碼如下(加密可與java互通)

<?php

/**
 * DES加密類
*
* 本類用於實現des算法的加密及解密
*
* 調用方法
* 加密爲hex格式:DES::encryptDesEcbPkcs5('待加密原文', '密鑰',DES::DATA_FORMAT_HEX)
* 解密hex格式的:數據 DES::decryptDesEcbPkcs5('密文hex', '密鑰',DES::DATA_FORMAT_HEX)
* 加密爲base64格式:DES::encryptDesEcbPkcs5('待加密原文', '密鑰',DES::DATA_FORMAT_BASE64)
* 解密base64格式的數據:DES::decryptDesEcbPkcs5('密文base64', '密鑰',DES::DATA_FORMAT_BASE64)
*/
class DES {
	
	const PADDING_MODE_NO = 0;
	const PADDING_MODE_PKCS5 = 1;
	const PADDING_MODE_PKCS7 = 2;
	
	const DATA_FORMAT_BIN = 0;//加密後的二進制數據
	const DATA_FORMAT_HEX = 1;//將加密後的二進制數據轉爲hex
	const DATA_FORMAT_BASE64 = 2;//將加密後的二進制數據轉爲base64
	
	/**
	 * 加密函數
	 * 算法:des
	 * 加密模式:ecb
	 * 補齊方法:PKCS5
	 * @param string $input 待加密字符串
	 * @param string $key 密鑰
	 * @param int $binFormat 返回加密二進制數據的格式,可返回二進制原數據、hex、base64格式
	 */ 
	public static  function encryptDesEcbPkcs5($input,$key,$dataFormat=self::DATA_FORMAT_HEX)
	{
		$size = mcrypt_get_block_size(MCRYPT_DES,'ecb');
		$input = self::pkcs5_pad($input, $size);
		$td = mcrypt_module_open('des', '', 'ecb', '');
	
		$iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
			
		@mcrypt_generic_init($td, $key, $iv);
		$data = mcrypt_generic($td, $input);
		mcrypt_generic_deinit($td);
		mcrypt_module_close($td);
		if ($dataFormat == self::DATA_FORMAT_HEX) {
			$data = strtoupper(bin2hex($data));
		}
		else if ($dataFormat == self::DATA_FORMAT_BASE64) {
			$data = base64_encode($data);
		}
		
		return $data;
	}
	/**
	 * 解密函數
	 * 算法:des
	 * 加密模式:ecb
	 * 補齊方法:PKCS5
	 * @param string $input 待加密字符串
	 * @param string $key 密鑰
	 * @param int $binFormat 加密數據的格式,可爲二進制數據、hex、base64格式
	 */
	public static  function decryptDESEcbPkcs5($input,$key,$dataFormat=self::DATA_FORMAT_HEX)
	{
		if ($dataFormat == self::DATA_FORMAT_HEX) {
			$input = hex2bin($input);
		}
		else if ($dataFormat == self::DATA_FORMAT_BASE64) {
			$input = base64_decode($input);
		}
		$size = mcrypt_get_block_size(MCRYPT_DES,'ecb');
		$td = mcrypt_module_open(MCRYPT_DES, '', 'ecb', '');
		$iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
		@mcrypt_generic_init($td, $key, $iv);
		$data = mdecrypt_generic($td, $input);
		mcrypt_generic_deinit($td);
		mcrypt_module_close($td);
		$data = self::pkcs5_unpad($data, $size);
		return $data;
	}
	
	function pkcs5_pad($text, $blocksize) {
		$pad = $blocksize - (strlen ( $text ) % $blocksize);
		return $text . str_repeat ( chr ( $pad ), $pad );
	}
	
	function pkcs5_unpad($text) {
		$pad = ord ( $text {strlen ( $text ) - 1} );
		if ($pad > strlen ( $text )) {
			return false;
		}
		if (strspn ( $text, chr ( $pad ), strlen ( $text ) - $pad ) != $pad) {
			return false;
		}
		return substr ( $text, 0, - 1 * $pad );
	}
}

?>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章