首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 與 Java 互通 DES 加密解密實作(CBC 模式 + PKCS5Padding + Base64)

     編輯:PHP 綜合知識

加密規範統一

項目設定值
演算法DES
模式CBC (Cipher Block Chaining)
填充PKCS5Padding
IV (初始向量)與 Key 相同(8 位元組)
輸出編碼Base64
Key 長度8 位元組 (64 bits)

PHP 實作

<?php
class DES {
    private $key;
    private $iv;

    public function __construct($key, $iv = null) {
        $this->key = $key;
        $this->iv  = $iv ?? $key; // IV 預設等於 Key
    }

    // 加密
    public function encrypt($str) {
        $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
        $str  = $this->pkcs5Pad($str, $size);
        
        // mcrypt 已棄用,建議改用 openssl
        $data = mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv);
        return base64_encode($data);
    }

    // 解密
    public function decrypt($str) {
        $str = base64_decode($str);
        $str = mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_DECRYPT, $this->iv);
        return $this->pkcs5Unpad($str);
    }

    // PKCS5 填充
    private function pkcs5Pad($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    // PKCS5 去填充
    private function pkcs5Unpad($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, -$pad);
    }
}

// 使用範例
$str  = 'abcd';
$key  = 'asdfwef5'; // 8 字元
$des  = new DES($key);
$enc  = $des->encrypt($str);
$dec  = $des->decrypt($enc);

echo "原文: $str\n";
echo "密文: $enc\n";
echo "解密: $dec\n";

Java 實作

package com.test;

import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Base64; // 需 commons-codec 依賴

public class DESUtil {
    private static final String ALGORITHM = "DES/CBC/PKCS5Padding";

    public static String encrypt(String key, String data) throws Exception {
        return encrypt(key, data.getBytes("UTF-8"));
    }

    public static String encrypt(String key, byte[] data) throws Exception {
        DESKeySpec dks = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        Key secretKey = keyFactory.generateSecret(dks);
        
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        
        byte[] encrypted = cipher.doFinal(data);
        return new String(Base64.encodeBase64(encrypted), "UTF-8");
    }

    public static String decrypt(String key, String data) throws Exception {
        byte[] decoded = Base64.decodeBase64(data.getBytes("UTF-8"));
        byte[] decrypted = decrypt(key, decoded);
        return new String(decrypted, "UTF-8");
    }

    public static byte[] decrypt(String key, byte[] data) throws Exception {
        DESKeySpec dks = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        Key secretKey = keyFactory.generateSecret(dks);
        
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        
        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        String key = "asdfwef5";
        String plain = "abcd";
        String encrypted = encrypt(key, plain);
        String decrypted = decrypt(key, encrypted);
        
        System.out.println("明文: " + plain);
        System.out.println("密文: " + encrypted);
        System.out.println("解密: " + decrypted);
    }
}

現代化建議:棄用 DES,改用 AES

DES 已不安全(56-bit 有效金鑰,可暴力破解)。雙方協議允許時,強烈建議遷移至 AES-256-CBC 或 AES-256-GCM。

<?php
// PHP 7.1+ 使用 openssl (取代 mcrypt)
function aesEncrypt($data, $key, $iv) {
    return base64_encode(openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv));
}

function aesDecrypt($data, $key, $iv) {
    return openssl_decrypt(base64_decode($data), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
}

// Key 需 32 字元,IV 需 16 字元
$key = hash('sha256', 'my-secret-key', true);
$iv  = random_bytes(16);

線上工具參考

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved