PHP兼容C#和java的DES端对端加密方式

1,562 阅读2分钟

导读:

DES端对端的加密方式,安全性高,本文的三个语言版本的DES加解密结果都是一样的,大家直接复制粘贴即可使用。

php

<?php
ini_set("error_reporting","E_ALL & ~E_NOTICE");
header('Content-Type:application/json; charset=utf-8');
if (!function_exists('openssl_encrypt')){
	exit('请开启php.ini的openssl扩展');
}
$input="123456";   //要加密的字符串
$deskey='QDHPJKOS';//算法密钥 
$des = new Des();
$encode=$des->encrypt($input,$deskey);
echo "DES加密结果:".$encode;
$decode=$des->decrypt($encode,$deskey);
echo "\r\nDES解密结果:".$decode;

/**
 * DES加解密类
 */
class Des{
   
    /**
     *
     * 加密函数
     * 算法:des
     * 加密模式:ecb
     * 补齐方法:PKCS5
     *
     * @param unknown_type $input
     */
    public function encrypt($input, $key)
    {
		//由于php7.1废弃了mcrypt_* 一系列函数,所以采用openssl版本
		$str = $this->pkcsPadding($input, 8);
		$key = str_pad($key, 8, '0'); //3DES加密将8改为24
		$sign = @openssl_encrypt($str, 'DES-ECB', $key,OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
		//转为base64,可以有效解决乱码等问题
		$sign = base64_encode($sign);
		return $sign;
    }
    
    /**
     * 解密函数
     * 算法:des
     * 加密模式:ecb
     * 补齐方法:PKCS5
     * @param unknown_type $input
     */
    public function decrypt($input, $key)
    {
		//由于php7.1废弃了mcrypt_* 一系列函数 所以采用openssl版本
		$encrypted = base64_decode($input);
		$key = str_pad($key, 8, '0'); //3DES加密将8改为24
		$sign = @openssl_decrypt($encrypted, 'DES-ECB', $key,OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
		$sign = $this->unPkcsPadding($sign);
		$sign = rtrim($sign);
		return $sign;
    }
	/**
     * 填充
     *
     * @param $text
     * @param $blocksize
     * @return string
     */
    private function pkcsPadding($text, $blocksize)
    {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }
 
     /**
     * 去填充
     * 
     * @param $text
     * @return string
     */
    private function unPkcsPadding($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);
    }
    
}

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace demo
{
    class Program
    {
        static void Main(string[] args)
        {
            string message = "123456";//要加密的字符串
            string key = "QDHPJKOS";  //算法密钥
            string encode = encrypt(message, key);
            Console.Write("DES加密结果:" + encode);
            string decode = decrypt(encode, key);
            Console.Write("\r\nDES解密结果:" + decode);
            Console.Read();
        }
        /// DES算法,加密
        /// param message  待加密字符串
        /// param key      解密私钥
        /// return         加密后的Base64编码字符串
        public static string encrypt(string message, string key)
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] inputByteArray = Encoding.UTF8.GetBytes(message);
                des.Key = UTF8Encoding.UTF8.GetBytes(key);
                des.IV = UTF8Encoding.UTF8.GetBytes(key);
                des.Mode = System.Security.Cryptography.CipherMode.ECB;
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Convert.ToBase64String(ms.ToArray());
                ms.Close();
                return str;
            }
        }
        /// DES算法,解密
        /// param message  待解密字符串
        /// param key      解密私钥
        /// return         解密后的字符串
        public static string decrypt(string message, string key)
        {
            byte[] inputByteArray = Convert.FromBase64String(message);
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = UTF8Encoding.UTF8.GetBytes(key);
                des.IV = UTF8Encoding.UTF8.GetBytes(key);
                des.Mode = System.Security.Cryptography.CipherMode.ECB;
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                return str;
            }
        }
    }
}

java

package demoSys;

import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String input = "123456";
		String deskey = "QDHPJKOS";
		String encode = encrypt(input, deskey);
		System.out.println("DES加密结果:" + encode);
		String decode = decrypt(encode, deskey);
		System.out.println("DES解密结果:" + decode);
	}

	public static String encrypt(String souce, String key) {
		try {
			// DES算法要求有一个可信任的随机数源
			SecureRandom sr = new SecureRandom();
			// 从原始密匙数据创建DESKeySpec对象
			DESKeySpec dks = new DESKeySpec(key.getBytes("UTF-8"));
			// 创建一个密匙工厂,然后用它把DESKeySpec转换成 一个SecretKey对象
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey secretkey = keyFactory.generateSecret(dks);
			// Cipher对象实际完成加密操作
			Cipher cipher = Cipher.getInstance("DES");
			// 用密匙初始化Cipher对象
			cipher.init(Cipher.ENCRYPT_MODE, secretkey, sr);
			// 获取数据并加密
			byte encryptedData[] = cipher.doFinal(souce.getBytes("UTF-8"));
			// JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoder
			// Android平台可以使用android.util.Base64
			return new String(Base64.getEncoder().encode(encryptedData));
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return souce;
		}

	}

	public static String decrypt(String souce, String key) {
		try {
			// DES算法要求有一个可信任的随机数源
			SecureRandom sr = new SecureRandom();
			// 从原始密匙数据创建DESKeySpec对象
			DESKeySpec dks = new DESKeySpec(key.getBytes());
			// 创建一个密匙工厂,然后用它把DESKeySpec转换成 一个SecretKey对象
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey secretkey = keyFactory.generateSecret(dks);
			// Cipher对象实际完成加密操作
			Cipher cipher = Cipher.getInstance("DES");
			// 用密匙初始化Cipher对象
			cipher.init(Cipher.DECRYPT_MODE, secretkey, sr);
			// 将加密报文用BASE64算法转化为字节数组
			byte[] encryptedData = Base64.getDecoder().decode(souce);
			// 用DES算法解密报文
			byte decryptedData[] = cipher.doFinal(encryptedData);
			return new String(decryptedData, "UTF-8");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return souce;
		}

	}

}