首頁  >  問答  >  主體

關於PHP與JAVA 3DES 加密問題

我想把java的一個加密類別用PHP來寫,但我看了java的這個寫法讓我非常頭痛。完全不按邏輯出牌。我找到一個完整的類,本來想著參考一下,經過多次實驗,無法將我上傳的加密類翻譯成PHP。代各位幫忙。謝謝。

/**

#public class ThreeDESUtil {

private static final String Algorithm = "DESede"; // 定义 加密算法,可用
                                                    // DES,DESede,Blowfish
private static byte[] keybyte = { 0x11, 0x28, 0x4F, 0x58, (byte) 0x88,
        0x10, 0x40, 0x38, 0x28, 0x25, 0x79, 0x51, (byte) 0xCB, (byte) 0xDD,
        0x55, 0x66, 0x77, 0x29, 0x74, (byte) 0x98, 0x30, 0x40, 0x36,
        (byte) 0xE2 }; // 24字节的密钥

public static String encryptMode(String src) {
    String encrypt = null;
    try {
        byte[] ret = encryptMode(src.getBytes("UTF-8"));
        encrypt = new String(Base64.encode(ret));
        encrypt = encrypt.replaceAll("=", "Q");
    } catch (Exception e) {
        logger.error("ThreeDES Error");
    }
    return encrypt;
}



/**
 * 加密
 * 
 * @param src
 * @return
 */
private static byte[] encryptMode(byte[] src) {
    try {
        // 生成密钥
        SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
        // 加密
        Cipher c1 = Cipher.getInstance(Algorithm);
        c1.init(Cipher.ENCRYPT_MODE, deskey);
        return c1.doFinal(src);
    } catch (Exception e) {
        logger.error("ThreeDES Error");
    }
    return null;
}

// for test
public static void main(String[] args) {

    String szSrc = "12345678";

    String encoded = encryptMode(szSrc);
    System.out.println("加密后的字符串:" + encoded);
    //1xZ9Hssih5z0pegyf7aUcgQQ

}

}

以上是我需要轉換成PHP的java類,

附上以下參考文章
/q/10...

以下是我參考後寫的PHP程式碼。

<?php

$EasyCrypt3Des = new EasyCrypt3Des();
echo $EasyCrypt3Des->encrypt('12345678');
//java 结果 '1xZ9Hssih5z0pegyf7aUcgQQ';
exit;


class EasyCrypt3Des {
    private $_key = array("0x11", "0x28", "0x4F", "0x58", "0x88", "0x10", "0x40", "0x38", "0x28", "0x25", "0x79", "0x51","0xCB", "0xDD", "0x55", "0x66", "0x77", "0x29", "0x74", "0x98", "0x30", "0x40", "0x36", "0xE2");
    private $keyStr = "";
    public function __construct() {
        foreach($this->_key as $keyItem) {
            $this->keyStr .= $this->hexToStr($keyItem);
        }
    }

    public function encrypt($str) {
        $td = $this->gettd();
        $ret = mcrypt_generic($td,$str);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        $result =  base64_encode($ret);
        return str_replace('=','Q',$result);
    }



    private function getiv() {
        return pack('H16','0000000000000000');
    }

    private function gettd() {
        $iv = $this->getiv();
        $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
        mcrypt_generic_init($td, $this->keyStr,$iv);
        return $td;
    }

    private function hexToStr($hex){
        $string='';
        for ($i=0; $i < strlen($hex)-1; $i+=2){
            $string .= chr(hexdec($hex[$i].$hex[$i+1]));
        }
        return $string;
    }
}
给我你的怀抱给我你的怀抱2707 天前888

全部回覆(1)我來回復

  • 怪我咯

    怪我咯2017-06-15 09:23:44

    問題已解決,還是參考先前的文章:
    1、加密後的字元未進行字元轉換,所以無法進行解密,缺少一個步驟。
    2、參考我發的文章鏈接,PHP類完全通用。可忽略我之前發布的程式碼,我會再整理一份對的。

    java

    import java.security.Security;
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;

    public class ThreeDES {

    private static final String Algorithm = "DESede"; //定義 加密演算法,可用 DES,DESede,Blowfish

    
    //keybyte为加密密钥,长度为24字节
    //src为被加密的数据缓冲区(源)
    public static byte[] encryptMode(byte[] keybyte, byte[] src) {
       try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
    
            //加密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }
    
    //keybyte为加密密钥,长度为24字节
    //src为加密后的缓冲区
    public static byte[] decryptMode(byte[] keybyte, byte[] src) {      
    try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
    
            //解密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }
    
    //转换成十六进制字符串
    public static String byte2hex(byte[] b) {
        String hs="";
        String stmp="";
    
        for (int n=0;n<b.length;n++) {
            stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length()==1) hs=hs+"0"+stmp;
            else hs=hs+stmp;
            if (n<b.length-1)  hs=hs+":";
        }
        return hs.toUpperCase();
    }
    
    public static void main(String[] args)
    {
        //添加新安全算法,如果用JCE就要把它添加进去
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
    
        final byte[] keyBytes = {0x11, 0x28, 0x4F, 0x58, (byte)0x88, 0x10, 0x40, 0x38
                               , 0x28, 0x25, 0x79, 0x51, (byte)0xCB, (byte)0xDD, 0x55, 0x66
                               , 0x77, 0x29, 0x74, (byte)0x98, 0x30, 0x40, 0x36, (byte)0xE2};    //24字节的密钥
        String szSrc = "12345678";
        
        System.out.println("加密前的字符串:" + szSrc);
        
        byte[] encoded = encryptMode(keyBytes, szSrc.getBytes());        
        System.out.println("加密后的字符串:" + new String(encoded));
        
        byte[] srcBytes = decryptMode(keyBytes, encoded);
        System.out.println("解密后的字符串:" + (new String(srcBytes)));
    }
    

    }

    以上代碼完全取至 /q/10... 中

    以下是PHP程式碼。

    class EasyCrypt3Des {

    private $_key = "";
    
    public function __construct() {
        $keyItem = array(
            '0x11','0x28','0x4F','0x58','0x88','0x10','0x40','0x38','0x28','0x25','0x79','0x51',
            '0xCB','0xDD','0x55','0x66','0x77','0x29','0x74','0x98','0x30','0x40','0x36','0xE2'
        );
        foreach($keyItem as $kitem) {
            //转换成字符
            $this->_key .= chr($kitem);
        }
    }
    
    public function encrypt($str) {
        $td = $this->gettd();
        $ret = mcrypt_generic($td, $this->pkcs5_pad($str, 8));
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $this->strToHex($ret);
    }
    
    public function decrypt($str) {
        $td = $this->gettd();
        $ret = $this->pkcs5_unpad(mdecrypt_generic($td, $this->hexToStr($str)));
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $ret;
    }
    
    private function pkcs5_pad($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }
    
    private 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);
    }
    
    private function getiv() {
        return pack('H16', '0000000000000000');
    }
    
    private function gettd() {
        $iv = $this->getiv();
        $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
        mcrypt_generic_init($td, $this->_key, $iv);
        return $td;
    }
    
    private function strToHex($string){
        $hex = '';
        for ($i=0; $i<strlen($string); $i++){
            $ord = ord($string[$i]);
            $hexCode = dechex($ord);
            $hex .= substr('0'.$hexCode, -2);
        }
        return strToUpper($hex);
    }
    
    private function hexToStr($hex){
        $string='';
        for ($i=0; $i < strlen($hex)-1; $i+=2){
            $string .= chr(hexdec($hex[$i].$hex[$i+1]));
        }
        return $string;
    }

    }
    $EasyCrypt3Des = new EasyCrypt3Des();
    $code = $EasyCrypt3Des->encrypt('12345678');
    echo $code .'
    ';Dptm/>';
    exit;

    主要在於字元轉換這塊。

    回覆
    0
  • 取消回覆