比较相同的字符串返回false

时间:2017-01-04 10:12:28

标签: php string encryption comparison string-length

我有2张表商家表和订单表。每个表都有一个我用来比较的密钥来检查安全性。两者都是加密的。我解密它们来验证。问题是在解密后我得到相同的字符串值,但比较它们会返回false。这是代码

如果弦乐有特殊字符,那么这个问题就会发生,并且如果弦乐只有字母和数字那么就会发生这种情况

public function merchant_encrypt($pure_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
    return $encrypted_string;
}

public function merchant_decrypt($encrypted_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $encryption_key, $encrypted_string, MCRYPT_MODE_ECB, $iv);
    return $decrypted_string;
}

public function replace_spechial_charater($value){
    $value = str_replace('+=','plusequal',$value);
    $value = str_replace('=','equalsign',$value);
    $value = str_replace('+','plussign',$value);
    $value = str_replace('/','slashsign',$value);
    $value = str_replace('&','andsign',$value);
    return $value;
}

public function restore_spechial_charater($value){
    $value = str_replace('plusequal','+=',$value);
    $value = str_replace('equalsign','=',$value);
    $value = str_replace('plussign','+',$value);
    $value = str_replace('slashsign','/',$value);
    $value = str_replace('andsign','&',$value);
    return $value;
}

public function strhex($string) { 
    $hexstr = unpack('H*', $string); 
    return array_shift($hexstr); 
}

保存商家密钥

$enc_key = $row['merchant_id'];
$merchant_key = trim($_POST['key']); //e.g: 1234abcd+=&$
$merchant_key = replace_spechial_charater($merchant_key);
$encrypted_key = merchant_encrypt($merchant_key ,$enc_key);
$encrypted_key = base64_encode($encrypted_key);
//save $encrypted_key in the merchant table

解密它

$decrypted_key = base64_decode($row['key']);
$decrypted_key = decrypt($decrypted_key,$row['merchant_id']);
$decrypted_key = restore_spechial_charater($decrypted_key);
// the result is 2d1d54rt5h4th5rh5tr1h%$&^/+=gdgdfgd

相同的非加密密钥在商家网站中加密,但使用另一个enc_key

$enc_key = $row['order_id'];
$merchant_key = $row['key']; // 1234abcd+=&$
$merchant_key = replace_spechial_charater($merchant_key);
$encrypted_key = merchant_encrypt($merchant_key ,$enc_key);
$encrypted_key = base64_encode($encrypted_key);
//send $encrypted_key with other parameters to the payment gateway then returned to the php script

$order_decrypted_key = base64_decode($row['order_id']);
$order_decrypted_key = decrypt($order_decrypted_key ,$row['order_id']);
$order_decrypted_key = restore_spechial_charater($order_decrypted_key );
// the result is 2d1d54rt5h4th5rh5tr1h%$&^/+=gdgdfgd

var_dump(strip_tags($decrypted_key));
var_dump(strip_tags($order_decrypted_key));
$result = strcasecmp( trim($decrypted_key), trim($order_decrypted_key) );
echo $result;
//var_dump(trim()) returns the same result for both values

结果是:

string(39) "2d1d54rt5h4th5rh5tr1h%$&^/+=gdgdfgd" 
string(35) "2d1d54rt5h4th5rh5tr1h%$&^/+=gdgdfgd" 
3

然后:

$order_key = strhex($order_decrypted_key);
$merchant_key = strhex($decrypted_key);

var_dump(trim($decrypted_key));
var_dump(trim($order_decrypted_key));

的字符串(78)

"326431643534727435683474683572683574723168252426616d703b5e2f2b3d67646764666764"

的字符串(70)

"3264316435347274356834746835726835747231682524265e2f2b3d67646764666764"

那么如何解决这个问题并检查它们是否相等

1 个答案:

答案 0 :(得分:1)

你的两个字符串不一样,每个人都聚集在一起。而且恐怕没有神秘的填充物。

你的长字符串为2d1d54rt5h4th5rh5tr1h%$&^/+=gdgdfgd (注意中间的htmlentity,占4个额外的字符)。

(通过在解压缩的数据上运行以下命令找到):

$string = "326431643534727435683474683572683574723168252426616d703b5e2f2b3d67646764666764";
$packed = pack("H*", $string);
var_dump($packed);

响应:

string(39) "2d1d54rt5h4th5rh5tr1h%$&^/+=gdgdfgd"

我只能猜测你是在网上而不是在终端上打印你的比较,并且你正在呈现由浏览器呈现的结果(而不是实际结果),因此没有看到那些额外的四个字符。

在保存数据之前,您应该运行一些东西来解码输入中的html实体。或者你可以在比较之前做到这一点,但更好地保存数据。

$decrypted_key       = htmlspecialchars_decode($decrypted_key);
$order_decrypted_key = htmlspecialchars_decode($order_decrypted_key);