PHP(5&7)解决JAVA对应的3DES加密&解密算法

kyle 2018-11-01 3028次浏览 0条评论 0 打赏作者 0 0

JAVA代码:

// javac test3.java
// java test3
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
 *
 * @author Administrator
 */
public class STD3Des {
    public static void main(String[] args) throws Exception {
        byte[] key = ("f510b8737344cddbca1c8564").getBytes();
      // byte[] keyiv = {0x66,0x6f,0x61,0x6f,0x63,0x75,0x65,0x6e};
      byte[] keyiv = {'f','o','a','o','c','u','e','n'};
        System.out.println("\r\nkey.length:" + key.length);
        byte[] data = "中国ABCabc1234".getBytes("UTF-8");
        System.out.println("ECB加密解密");
        byte[] str3 = des3EncodeECB(key, data);
        byte[] str4 = ees3DecodeECB(key, str3);
        System.out.println(new BASE64Encoder().encode(str3));
        System.out.println(new String(str4, "UTF-8"));
        System.out.println("<=============>");
       System.out.println("CBC加密解密");
       byte[] str5 = des3EncodeCBC(key, keyiv, data);
       byte[] str6 = des3DecodeCBC(key, keyiv, str5);
       System.out.println(new BASE64Encoder().encode(str5));
       System.out.println(new String(str6, "UTF-8"));
    }
    /**
     * ECB加密,不要IV
     *
     * @param key 密钥
     * @param data 明文
     * @return Base64编码的密文
     * @throws Exception
     */
    public static byte[] des3EncodeECB(byte[] key, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, deskey);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * ECB解密,不要IV
     *
     * @param key 密钥
     * @param data Base64编码的密文
     * @return 明文
     * @throws Exception
     */
    public static byte[] ees3DecodeECB(byte[] key, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, deskey);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * CBC加密
     *
     * @param key 密钥
     * @param keyiv IV
     * @param data 明文
     * @return Base64编码的密文
     * @throws Exception
     */
    public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * CBC解密
     *
     * @param key 密钥
     * @param keyiv IV
     * @param data Base64编码的密文
     * @return 明文
     * @throws Exception
     */
    public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
}


PHP5代码:

<?php
/**
 * 3des对称加密解密,与java c#兼容
 * $iv cbc分组模式的偏移量,没有则使用ecb模式
  $key=bin2hex(md5('gule10'));
  $key = pack('H48',$key);//取48字节24个字符
  // $iv = pack('H16',bin2hex('foaocuen'));
  $iv='foaocuen';
  $msg = '123456';
  // $des = new STD3Des(base64_encode($key));//ecb
  $des = new STD3Des(base64_encode($key),base64_encode($iv));//mode:cbc
  $rs1 = $des->encrypt($msg);
  echo '密钥hex:'.bin2hex($key) . '<br />';
  echo '密钥bin:'.$key . '<br />';
  echo '加密base64:'.($rs1) . '<br />';
  $rs2 = $des->decrypt($rs1);
  echo '解密:'.($rs2) . '<br />';
 */
class STD3Des {
    private $key  = "";
    private $iv   = "";
    private $mode = MCRYPT_MODE_CBC;

    /**
     * 构造,传递二个已经进行base64_encode的KEY与IV
     *
     * @param string $key
     * @param string $iv
     */
    function __construct($key, $iv = null) {
        if (empty($key)) {
            echo 'key is not valid';
            exit();
        }
        if ($iv == null) {
            $iv         = $key;
            $this->mode = MCRYPT_MODE_ECB;
        }
        $this->key = $key;
        $this->iv  = $iv;
    }

    /**
     * 加密
     * @param <type> $value
     * @return <type>
     */
    public function encrypt($value) {
        $td    = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
        $iv    = $this->mode == MCRYPT_MODE_CBC ? base64_decode($this->iv) : mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        $value = $this->PaddingPKCS7($value);
        $key   = base64_decode($this->key);
        mcrypt_generic_init($td, $key, $iv);
        $dec   = mcrypt_generic($td, $value);
        $ret   = base64_encode($dec);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $ret;
    }

    /**
     * 解密
     * @param <type> $value
     * @return <type>
     */
    public function decrypt($value) {
        $td  = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
        $iv  = $this->mode == MCRYPT_MODE_CBC ? base64_decode($this->iv) : mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        $key = base64_decode($this->key);
        mcrypt_generic_init($td, $key, $iv);
        $ret = trim(mdecrypt_generic($td, base64_decode($value)));
        $ret = $this->UnPaddingPKCS7($ret);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $ret;
    }

    private function PaddingPKCS7($data) {
        $block_size   = mcrypt_get_block_size('tripledes', $this->mode);
        $padding_char = $block_size - (strlen($data) % $block_size);
        $data .= str_repeat(chr($padding_char), $padding_char);
        return $data;
    }

    private function UnPaddingPKCS7($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);
    }
}


PHP7代码(待优化):

<?php

/**
 *
 */
class Util3Des
{
    /**
     * 加密 (!!! 加密decrypt不去除\uXXXX的源数据)
     */
   public static function encrypt($data, $key) {
      $key = pack('H48', $key); //取48字节24个字符
      return openssl_encrypt($data, 'DES-EDE3', $key, OPENSSL_ZERO_PADDING);
   }

    /**
     * 解密
     */
   public static function decrypt($data, $key) {
      $key = pack('H48', $key); //取48字节24个字符
      $data = openssl_decrypt($data, 'DES-EDE3', $key, OPENSSL_ZERO_PADDING);
      // 去除\uXXXX         
      return static::unicode_decode($data);
   }

   /**
     * 去除\uXXXX (\u0005\u0005)
     */
   public static function unicode_decode($name)
   {
      // 转换编码,将Unicode编码转换成可以浏览的utf-8编码
      $pattern = '/([\w]+)|(\\\u([\w]{4}))/i';
      preg_match_all($pattern, $name, $matches);
      if (!empty($matches))
      {
         $name = '';
         for ($j = 0; $j < count($matches[0]); $j++)
         {
            $str = $matches[0][$j];
            if (strpos($str, '\\u') === 0)
            {
               $code = base_convert(substr($str, 2, 2), 16, 10);
               $code2 = base_convert(substr($str, 4), 16, 10);
               $c = chr($code).chr($code2);
               $c = iconv('UCS-2', 'UTF-8', $c);
               $name .= $c;
            }
            else
            {
               $name .= $str;
            }
         }
      }
      return $name;
   }
}




0

0 条评论

    没有找到数据。

发表评论

kyle
土豪

kyle

注册时间:2016-10-28
最后登录:16天前
发布
带到手机上看