chinapay 兼容 php5.2-5.5

http://www.zhaoyuanma.com/

<?php
define ( "DES_KEY", "SCUBEPGW" );
define ( "HASH_PAD", "0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414" );
bcscale ( 0 );
$private_key = array ();
// 兼容 php5.4+
if (! function_exists ( 'hex2bin' )) {
	function hex2bin($hexdata) {
		$bindata = '';
		if (strlen ( $hexdata ) % 2 == 1) {
			$hexdata = '0' . $hexdata;
		}
		for($i = 0; $i < strlen ( $hexdata ); $i += 2) {
			$bindata .= chr ( hexdec ( substr ( $hexdata, $i, 2 ) ) );
		}
		return $bindata;
	}
}
function padstr($src, $len = 256, $chr = '0', $d = 'L') {
	$ret = trim ( $src );
	$padlen = $len - strlen ( $ret );
	if ($padlen > 0) {
		$pad = str_repeat ( $chr, $padlen );
		if (strtoupper ( $d ) == 'L') {
			$ret = $pad . $ret;
		} else {
			$ret = $ret . $pad;
		}
	}
	return $ret;
}
function bin2int($bindata) {
	$hexdata = bin2hex ( $bindata );
	return bchexdec ( $hexdata );
}
function bchexdec($hexdata) {
	$ret = '0';
	$len = strlen ( $hexdata );
	for($i = 0; $i < $len; $i ++) {
		$hex = substr ( $hexdata, $i, 1 );
		$dec = hexdec ( $hex );
		$exp = $len - $i - 1;
		$pow = bcpow ( '16', $exp );
		$tmp = bcmul ( $dec, $pow );
		$ret = bcadd ( $ret, $tmp );
	}
	return $ret;
}
function bcdechex($decdata) {
	$s = $decdata;
	$ret = '';
	while ( $s != '0' ) {
		$m = bcmod ( $s, '16' );
		$s = bcdiv ( $s, '16' );
		$hex = dechex ( $m );
		$ret = $hex . $ret;
	}
	return $ret;
}
function sha1_128($string) {
	$hash = sha1 ( $string );
	$sha_bin = hex2bin ( $hash );
	$sha_pad = hex2bin ( HASH_PAD );
	return $sha_pad . $sha_bin;
}
function mybcpowmod($num, $pow, $mod) {
	if (function_exists ( 'bcpowmod' )) {
		return bcpowmod ( $num, $pow, $mod );
	}
	return emubcpowmod ( $num, $pow, $mod );
}
function emubcpowmod($num, $pow, $mod) {
	$result = '1';
	do {
		if (! bccomp ( bcmod ( $pow, '2' ), '1' )) {
			$result = bcmod ( bcmul ( $result, $num ), $mod );
		}
		$num = bcmod ( bcpow ( $num, '2' ), $mod );
		$pow = bcdiv ( $pow, '2' );
	} while ( bccomp ( $pow, '0' ) );
	return $result;
}
function rsa_encrypt($private_key, $input) {
	$p = bin2int ( $private_key ["prime1"] );
	$q = bin2int ( $private_key ["prime2"] );
	$u = bin2int ( $private_key ["coefficient"] );
	$dP = bin2int ( $private_key ["prime_exponent1"] );
	$dQ = bin2int ( $private_key ["prime_exponent2"] );
	$c = bin2int ( $input );
	$cp = bcmod ( $c, $p );
	$cq = bcmod ( $c, $q );
	$a = mybcpowmod ( $cp, $dP, $p );
	$b = mybcpowmod ( $cq, $dQ, $q );
	if (bccomp ( $a, $b ) >= 0) {
		$result = bcsub ( $a, $b );
	} else {
		$result = bcsub ( $b, $a );
		$result = bcsub ( $p, $result );
	}
	$result = bcmod ( $result, $p );
	$result = bcmul ( $result, $u );
	$result = bcmod ( $result, $p );
	$result = bcmul ( $result, $q );
	$result = bcadd ( $result, $b );
	$ret = bcdechex ( $result );
	$ret = strtoupper ( padstr ( $ret ) );
	return (strlen ( $ret ) == 256) ? $ret : false;
}
function rsa_decrypt($input) {
	global $private_key;
	$check = bchexdec ( $input );
	$modulus = bin2int ( $private_key ["modulus"] );
	$exponent = bchexdec ( "010001" );
	$result = bcpowmod ( $check, $exponent, $modulus );
	$rb = bcdechex ( $result );
	return strtoupper ( padstr ( $rb ) );
}
function buildKey($key) {
	global $private_key;
	if (count ( $private_key ) > 0) {
		foreach ( $private_key as $name => $value ) {
			unset ( $private_key [$name] );
		}
	}
	$ret = false;
	$key_file = parse_ini_file ( $key );
	if (! $key_file) {
		return $ret;
	}
	$hex = "";
	if (array_key_exists ( "MERID", $key_file )) {
		$ret = $key_file ["MERID"];
		$private_key ["MERID"] = $ret;
		$hex = substr ( $key_file ["prikeyS"], 80 );
	} else if (array_key_exists ( "PGID", $key_file )) {
		$ret = $key_file ["PGID"];
		$private_key ["PGID"] = $ret;
		$hex = substr ( $key_file ["pubkeyS"], 48 );
	} else {
		return $ret;
	}
	$bin = hex2bin ( $hex );
	$private_key ["modulus"] = substr ( $bin, 0, 128 );
	$cipher = MCRYPT_DES;
	$iv = str_repeat ( "x00", 8 );
	$prime1 = substr ( $bin, 384, 64 );
	// 兼容 php5.5+
	// $enc = mcrypt_cbc ( $cipher, DES_KEY, $prime1, MCRYPT_DECRYPT, $iv );
	$enc = mcrypt_decrypt ( $cipher, DES_KEY, $prime1, 'cbc', $iv );
	$private_key ["prime1"] = $enc;
	$prime2 = substr ( $bin, 448, 64 );

	// $enc = mcrypt_cbc ( $cipher, DES_KEY, $prime2, MCRYPT_DECRYPT, $iv );
	$enc = mcrypt_decrypt ( $cipher, DES_KEY, $prime2, 'cbc', $iv );
	$private_key ["prime2"] = $enc;
	$prime_exponent1 = substr ( $bin, 512, 64 );
	// $enc = mcrypt_cbc ( $cipher, DES_KEY, $prime_exponent1, MCRYPT_DECRYPT,
	// $iv );
	$enc = mcrypt_decrypt ( $cipher, DES_KEY, $prime_exponent1, 'cbc', $iv );
	$private_key ["prime_exponent1"] = $enc;
	$prime_exponent2 = substr ( $bin, 576, 64 );
	// $enc = mcrypt_cbc ( $cipher, DES_KEY, $prime_exponent2, MCRYPT_DECRYPT,
	// $iv );
	$enc = mcrypt_decrypt ( $cipher, DES_KEY, $prime_exponent2, 'cbc', $iv );
	$private_key ["prime_exponent2"] = $enc;
	$coefficient = substr ( $bin, 640, 64 );
	// $enc = mcrypt_cbc ( $cipher, DES_KEY, $coefficient, MCRYPT_DECRYPT, $iv
	// );
	$enc = mcrypt_decrypt ( $cipher, DES_KEY, $coefficient, 'cbc', $iv );
	$private_key ["coefficient"] = $enc;
	return $ret;
}
function sign($msg) {
	global $private_key;
	if (! array_key_exists ( "MERID", $private_key )) {
		return false;
	}
	$hb = sha1_128 ( $msg );
	return rsa_encrypt ( $private_key, $hb );
}
function signOrder($merid, $ordno, $amount, $curyid, $transdate, $transtype) {
	if (strlen ( $merid ) != 15)
		return false;
	if (strlen ( $ordno ) != 16)
		return false;
	if (strlen ( $amount ) != 12)
		return false;
	if (strlen ( $curyid ) != 3)
		return false;
	if (strlen ( $transdate ) != 8)
		return false;
	if (strlen ( $transtype ) != 4)
		return false;
	$plain = $merid . $ordno . $amount . $curyid . $transdate . $transtype;
	return sign ( $plain );
}
function verify($plain, $check) {
	global $private_key;
	if (! array_key_exists ( "PGID", $private_key )) {
		return false;
	}
	if (strlen ( $check ) != 256) {
		return false;
	}
	$hb = sha1_128 ( $plain );
	$hbhex = strtoupper ( bin2hex ( $hb ) );
	$rbhex = rsa_decrypt ( $check );
	return $hbhex == $rbhex ? true : false;
}
function verifyTransResponse($merid, $ordno, $amount, $curyid, $transdate, $transtype, $ordstatus, $check) {
	if (strlen ( $merid ) != 15)
		return false;
	if (strlen ( $ordno ) != 16)
		return false;
	if (strlen ( $amount ) != 12)
		return false;
	if (strlen ( $curyid ) != 3)
		return false;
	if (strlen ( $transdate ) != 8)
		return false;
	if (strlen ( $transtype ) != 4)
		return false;
	if (strlen ( $ordstatus ) != 4)
		return false;
	if (strlen ( $check ) != 256)
		return false;
	$plain = $merid . $ordno . $amount . $curyid . $transdate . $transtype . $ordstatus;
	return verify ( $plain, $check );
}

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注