des加密解密——java加密,php解密

最近在作項目中,遇到des加密解密的問題。php

場景是安卓app端用des加密,php這邊須要解密。以前沒有接觸過des這種加密解密算法,但想着確定會有demo。所以百度,搜了代碼來用。網上代碼也是魚龍混雜,好不容易測試在php這邊測試加密和解密成功了。爲確保安卓app端提交過來的加密參數可以解密出來,給定安卓人員一個字符串,讓他們把des加密後的字符串給我,在php這邊解密。結果一看,加密出來的字符串跟我這邊加密出來的結果不一致,天然是解密不出來。java

 

要來java的des算法代碼,研究加密的過程,其中各類調試測試,外加各類百度,必應。發現可以正確解密的規則,其中很是重要的三點就是,加密解密過程,雙方的key、加密模式(例如ECB、CBC等),以及iv(有些地方叫它偏移量,有些地方叫它向量,沒有深刻研究)須要一致。須要着重說明的是這個iv,在ECB加密模式(java默認的加密模式)時,是不須要這個iv的,即便寫了,也不會影響加密的結果;而當加密模式爲CBC時,則須要iv這個參數,不然會隨機生成該參數,這樣每次加密的結果會變。而關鍵在於,java端定義了iv,那麼php這邊也須要跟java端保持一致,這樣纔可以正確解密出來。算法

 

後面就膠着在這個iv上面。查看java端代碼,iv是一個byte[],即字節數組,想都沒有想就去網上找php將字符串轉化爲byte[]類型的,也試過強制轉換,解密失敗。最後纔想起來去看php的數據類型,呃呃呃,壓根就沒有type類型的。真是基礎不牢,又想固然,以爲java有該數據類型,php也會有。。。慣性思惟真的害人啊。這怎麼辦呢?既須要byte[]去解密,又沒有該數據數據類型,已經感受無解了。數組

 

一般這個時候,須要休息,休息一下子。後面忽然念頭閃過,php中有函數能夠des解密,該函數確定不會用php沒有的數據類型去解密,因此我試着將java加密中轉換成byte[]類型前的字符串做爲php的iv,測試,終於解密成功。app

 附上java端加密代碼,採用CBC模式:函數

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

public class DES {

    //加密數據入口
    public static String encryptString(String message, String key)
            throws Exception {
        byte[] bytes = encrypt(message, key);
        return toHexString(bytes).toUpperCase();
    }

  public static byte[] encrypt(String message, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

        return cipher.doFinal(message.getBytes("UTF-8"));
    }
}

 

附上對應的php端解密代碼:測試

class DES
{
    public static function decrypt($str, $key)
    {
        $midstr = hex2bin(strtolower($str));
     //第二個參數$key就是三個重點中的$key,而最後一個參數$key是iv,只是java加密時採用了與第二個參數相同的字符串,根據具體狀況來定就好
     $str = mcrypt_decrypt(MCRYPT_DES, $key, $midstr, MCRYPT_MODE_CBC, $key); 
     $pad = ord($str[($len = strlen($str)) - 1]);      return substr($str, 0, strlen($str) - $pad);   } }

其中hex2bin是將十六進制轉換成二進制,php自帶該函數,不須要再另行定義(網上看到不少該函數的代碼)。解密能夠看做是加密的逆操做,因此java端將加密後字符串轉成十六進制,並大寫,解密時天然須要轉換回來。加密

  

能夠看看下面這個連接,寫得不錯:url

http://zhidao.baidu.com/link?url=vKbwbKxibbLc8K7oo40cJ17aYz2i2MdfZlaytdj6GLsqBwrPoc_OwHhsi7IjdaFId9fZb52SkhdDBG_U502CKNyCQDPE3ZSKr-adXB46CEOspa

相關文章
相關標籤/搜索