:

PHP 7.2 OpenSSL实现 DES 算法

song100e 发布于:2019-11-7 13:58 分类:PHP  有 170 人浏览,获得评论 0 条 标签: openssl_decrypt openssl_encrypt 

    最近公司在制作一个小程序,需要获取用户的基本信息,由于微信小程序更新了新的版本,需要加密验证,使用的就是openssl 扩展,所以在运行的时候出现了一个致命错误:openssl_decrypt 无法加密解密,我使用的是php7.2  mcrypt被移除了, 换成了openssl_decrypt。

    试了好久,终于找到了解决方案,到吗如下:



<?php
// php 7.2
// hexdec():十六进制转换为十进制
// hex2bin():转换十六进制字符串为二进制字符串
// ord():转换字符串第一个字节为 0-255 之间的值
// chr():返回相对应于 ascii 所指定的单个字符。此函数与 ord() 是互补的
// strspn():计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度

$data = "8612F080DD8A26133C06DC5DA8DC13F282053CC996855EABC2A536A98F6085CE3EB5FAC4DB4EBAC
406ED0BC28D8DA5DDF206C273F5266DE07D9B6FD32D4A99807C84E2B84E38565BE90475C45305D309EF77BDF
5092D4DCEDB592941244A335DB33AFC59D00B260CA3AB03A6A7EBBC2F5E288F7B4D4512B9208CD9A5FFF438B
9DC1938369FE14D66B7FDE006840114EA23E4D76877D008F891C8CCF09366CB23F9ACF6CAECA232AF7AEAD3F
C2DC8E47773E851C6E1B6F1238B82E3BBEB6309484748D04E35B29E265A22281A26824271B18B0AAE1EEBD15
61894DDA94D6ECEC80DE088BF86E9965ADC6445F26FC6FD70FEE50A9C9F2FFC9FA3FE18A401C69E453295A5B
33FBA5B023B1FD398CF00C7942D29F36ECA7B71CD66C5D5F909799C4EC0F8F3DCFFEC24244C910C599E49FD5
0CA3369CAF05D0D7C2837319153923130622181DB4118B9614A6A5A9BB5F8B4BCEDE209BBCF93D216E350618
5F8687739A25905D961909B4F9A1AAEA210250A845D005E9FC0CF5AE9EB63825D65C15CFD1AF7B507F6D289F
D58EF8DA49AE69AF9E98677F5D212889E7915293011C56E1F8948CFD3C1CF918DCDF99383F3F5BFBBC0B21F7
CCAAB84FEB415751DCACF8E949C7A21F97D260E8A743385BA78AB5F80088A36792DA2E51EB42A49E55416C7E
6293C47FFD0251545A67AEF008E1041DA445E0B29F6F4858FFB54AD685A4133CE93160378CD7846357C92A5A
1C0A3C7E1A85FAF1F53C10932963276CDF4E809CDB74ABAFDD936BDA142B58BC9C00F8B430F9C905B0BEAC15
4760B97331CF13BB1F20095AAB7F0DB24F788E1C2E650B3EEF2DD1C67BED7078E106670D38CC2C727A4A9CB2
45F7AB6FDB6D585DB5B7AD55F2FBFEAB4923891ED5D36AAB01635484C7A01F3654BC5546A";

$data = str_replace(' ', '', $data);// 去空格
$c = new CryptDes('f6cbb47b934cb5eb85f1594647e5d017');
$r = $c->decrypt($data);
var_dump($r);
$s = 'song100e';
$r = $c->encrypt($s);
var_dump($r);
$r = $c->decrypt($r);
var_dump($r);

class CryptDes
{
    var $key;
    var $iv; 
	
    function __construct($key, $iv='') {
		//key长度8例如:1234abcd
        $this->key = hex2bin($key);
        $this->iv = $iv;//偏移量
    }

	/**
	 *@desc 加密
	 */
    function encrypt($data) {
        $data = $this->pkcs5Pad($data, 8);
        return bin2hex(openssl_encrypt($data, 'des-ede', $this->key, 
			OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $this->iv));
    }

	/**
	 *@desc 解密
	 */
    function decrypt($data) {
        return $this->pkcs5Unpad(openssl_decrypt(hex2bin($data), 'des-ede', 
			$this->key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $this->iv));
    }

	/**
	 *@desc 转换十六进制字符串为二进制字符串
	 */
    function hex2bin($hexData) {
        $binData = "";
        for($i = 0; $i < strlen ($hexData); $i += 2) {
            $binData .= chr(hexdec(substr($hexData, $i, 2)));
        }
        return $binData;
    }

	/**
	 *@desc 补充长度为8的倍数字符串
	 */
    function pkcs5Pad($text, $blocksize) {
        $pad = $blocksize-(strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

	/**
	 *@desc 校验数据并返回
	 */
    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, -1 * $pad);
    }
}



    解密出来的数据如下:

{
  "account": "621444******0038",
  "amount": "1",
  "batchNo": "000001",
  "currencyCode": "156",
  "dealDate": "2015-02-03",
  "dealStatus": "1",
  "dealTime": "10:08:51",
  "deviceId": "00011003130000579141",
  "liqDate": "0202",
  "merchantId": "898000156911002", 
  "merchantName": "绫致服装*****", 
  "merchantOrderId": "000000000000001",
  "orderId": "642015020326960682", 
  "posSeqId": "468576",
  "refId": "000105063751",
  "subInst": "101600",
  "termId": "00019130"
}



赞助我,共同学习进步!
上一篇:MySql 中 USING 的用法
下一篇:http code