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

跨平台 3DES 加密解密實現:PHP、Java/Android、iOS 完整互通方案

     編輯:PHP 綜合知識

前言

在多端協同開發中,數據加密傳輸是基礎需求。本文提供一套經過驗證的 3DES (Triple DES) 加解密方案,涵蓋 PHP 服務端、Java/Android 客戶端與 iOS 客戶端,確保各平台加密數據能夠無縫互通。核心參數統一為:CBC 模式、PKCS5/7 填充、Base64 編碼輸出,密鑰與向量(IV)在各端保持一致。

核心參數約定

  • 算法:DESede / 3DES
  • 模式:CBC
  • 填充:PKCS5Padding (Java) / PKCS7Padding (iOS) / pkcs5_pad (PHP)
  • 編碼:UTF-8
  • 輸出:Base64
  • 密鑰:my.oschina.net/penngo?#@(不足 24 字節以 0 補齊)
  • 向量:01234567(8 字節)

PHP 實現(基於 mcrypt,適用於 PHP < 7.2)

<?php
class DES3 {
    private $key = "my.oschina.net/penngo?#@";
    private $iv  = "01234567";

    public function encrypt($input) {
        $size = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_CBC);
        $input = $this->pkcs5_pad($input, $size);
        $key = str_pad($this->key, 24, '0');
        $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
        $iv = $this->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);
        return base64_encode($data);
    }

    public function decrypt($encrypted) {
        $encrypted = base64_decode($encrypted);
        $key = str_pad($this->key, 24, '0');
        $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
        $iv = $this->iv ?: mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, $key, $iv);
        $decrypted = mdecrypt_generic($td, $encrypted);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $this->pkcs5_unpad($decrypted);
    }

    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);
    }
}

// 測試
$des = new DES3();
$plain = "來自https://jb51.net的博客";
$encrypted = $des->encrypt($plain);
echo "加密: $encrypted\n";
echo "解密: " . $des->decrypt($encrypted) . "\n";
?>

Java / Android 實現

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
import java.security.Key;

public class DES3 {
    private static final String SECRET_KEY = "my.oschina.net/penngo?#@";
    private static final String IV = "01234567";
    private static final String ENCODING = "utf-8";
    private static final String TRANSFORMATION = "desede/CBC/PKCS5Padding";

    public static String encode(String plainText) throws Exception {
        Key deskey = SecretKeyFactory.getInstance("desede")
            .generateSecret(new DESedeKeySpec(SECRET_KEY.getBytes()));
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, deskey, new IvParameterSpec(IV.getBytes()));
        byte[] encryptData = cipher.doFinal(plainText.getBytes(ENCODING));
        return Base64.encode(encryptData); // 使用自帶或第三方 Base64
    }

    public static String decode(String encryptText) throws Exception {
        Key deskey = SecretKeyFactory.getInstance("desede")
            .generateSecret(new DESedeKeySpec(SECRET_KEY.getBytes()));
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, deskey, new IvParameterSpec(IV.getBytes()));
        byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
        return new String(decryptData, ENCODING);
    }

    // 內建 Base64 工具類(略,建議使用 android.util.Base64 或 Java 8+ java.util.Base64)
    public static class Base64 { /* ... 完整實現見原文 ... */ }
}

iOS (Objective-C) 實現

依賴 CommonCrypto 與 GTMBase64(Google Toolbox for Mac)。

// DES3Util.h
#import <Foundation/Foundation.h>
@interface DES3Util : NSObject
+ (NSString*)encrypt:(NSString*)plainText;
+ (NSString*)decrypt:(NSString*)encryptText;
@end

// DES3Util.m
#import "DES3Util.h"
#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h"

#define kKey @"my.oschina.net/penngo?#@"
#define kIV  @"01234567"

@implementation DES3Util

+ (NSString*)encrypt:(NSString*)plainText {
    NSData *data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    size_t bufferSize = data.length + kCCBlockSize3DES;
    void *buffer = malloc(bufferSize);
    size_t movedBytes = 0;

    CCCryptorStatus status = CCCrypt(kCCEncrypt, kCCAlgorithm3DES, kCCOptionPKCS7Padding,
        [kKey UTF8String], kCCKeySize3DES,
        [kIV UTF8String],
        [data bytes], data.length,
        buffer, bufferSize, &movedBytes);

    NSData *encryptedData = [NSData dataWithBytes:buffer length:movedBytes];
    free(buffer);
    return [GTMBase64 stringByEncodingData:encryptedData];
}

+ (NSString*)decrypt:(NSString*)encryptText {
    NSData *encryptedData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
    size_t bufferSize = encryptedData.length + kCCBlockSize3DES;
    void *buffer = malloc(bufferSize);
    size_t movedBytes = 0;

    CCCryptorStatus status = CCCrypt(kCCDecrypt, kCCAlgorithm3DES, kCCOptionPKCS7Padding,
        [kKey UTF8String], kCCKeySize3DES,
        [kIV UTF8String],
        [encryptedData bytes], encryptedData.length,
        buffer, bufferSize, &movedBytes);

    NSData *decryptedData = [NSData dataWithBytes:buffer length:movedBytes];
    free(buffer);
    return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
}
@end

驗證與注意事項

  1. 密鑰長度:3DES 需 24 字節密鑰,PHP 以 0 補齊,Java/iOS 直接取字節陣列前 24 位,確保一致。
  2. 填充差異:Java 用 PKCS5Padding,iOS 用 kCCOptionPKCS7Padding,兩者對 8 字節塊大小等效。
  3. Base64 換行:Java 手寫 Base64 每 76 字元換行,互通時需去除換行符或統一用標準庫。
  4. PHP 7.2+:mcrypt 已移除,建議改用 openssl_encrypt / openssl_decrypt,參數對應 OPENSSL_RAW_DATA + base64_encode。

總結

統一算法、模式、填充、編碼、密鑰與 IV,即可實現 PHP、Java/Android、iOS 三端 3DES 數據的無縫加解密互通。實際項目中建議優先考慮 AES-GCM 等更現代的認證加密方案,但若受限於歷史系統,本方案經過實測可靠可用。

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