项目中用到的异或加密算法(PHP)

对接交易所接口,用到了异或加密算法,心想这么大的交易所,居然用异或加密,不怕给破解了么,不管了,先记录一下吧;

异或:异或(xor)是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。

  • 其运算法则为:a⊕b = (¬a ∧ b) ∨ (a ∧¬b)

如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

二进制中:

  • 1 XOR 0 = 1
  • 0 XOR 1 = 1
  • 1 XOR 1 = 0
  • 0 XOR 0 = 0

可以看出若两个数相同取0,不同取1
例:运算11001 ^ 01011 = 10010
如果用其他进制进行运算时,先将他们转化成二进制,再做运算(不足的位在前边填0补齐)
例:6 ^ 3 = 110 ^ 011 = 101

加解密过程:

参数说明

ciphertext:是将身份数据加密后产生的,其由以下数据组成
(1)调用者ip
(2)特定随机字符串:在express中抽取的部分片段
(3)请求时间:请求时间的字符串,格式为”yyyyMMddHHmmss”,
如201705161452 每个部分之间用字符”-”隔开。
如:192.168.0.1-T3Qfh-20170608113839

  • express:是用来解析ciphertext的随机字符串express,其由以下两个部分组成:
    2.1 随机字符串:随机的20位字符串,在其中抽取出成为ciphertext特定随机字符串的部分。
    2.2 随机数:1-16的随机数。

加密过程

  • 随机生成一个 20 位的随机字符串和一个 1-16 的随机数,拼装成为 express。
  • 根据随机数在随机字符串中抽取相应位置为起始位置的 5 位随机数作为 ciphertext 中的随 机段。
  • 将 ip、随机段、调用时间以字符”-”进行分割并按照所述顺序拼合成为明文。
  • 将明文变为 ascii 码,并且每段 ascii 码都和第一步生成的随机数进行异或操作,并且以字 符”-”进行分割。

解密说明

  • 得到 ciphertext 密文和 express 时,首先解析 express 获得随机数和随机字符段;
  • 然后将 ciphertext 密文中 ascii 码分开并与随机数进行异或运算后,解析为明文获得 ip、随机字 符段和调用时间,并判断 ip 是否为事先定好的 ip 值、随机字段是否与 express 中解析的一致

示例说明

  • 随机字符串:FNQQFT3QfhgKRcMThpk
  • 随机数:6
  • express 值:FNQQFT3QfhgKRcMThpkF6
  • ip 地址:192.168.0.1
  • 时间:20170608113839
  • 截选的字符串:T3Qfh
  • 明文字符串:192.168.0.1-T3Qfh-20170608113839
  • getByte 后:495750464954564648464945845181102104455048495548544856494951565157
  • 密文:33-34-35-62-37-39-62-33-40-32-62-37-36-61-70-40-101-34-117-61-34-32-33-39-32-38-35-32-33-38-34-34-32-38-

C代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdio.h>
main()
{
char a[]="Password"; //要加密的密码
char b[]="encryption"; //密钥
int i;

//加密代码
for(i=0;a[i];i++)
a[i]=a[i]^b[i];
printf("Your Password is encrypted: %s\n",a);

/*解密代码*/
for(i=0;a[i];i++)
a[i]=a[i]^b[i];
printf("You Password: %s\n",a);
}

PHP实例代码

$express = 'U9rmosZvZcStF5wV8u2e16';
$ciphertext = '33-34-35-62-37-39-62-33-40-32-62-37-36-61-70-40-101-34-117-61-34-32-33-39-32-38-35-32-33-38-34-34-32-38-';

function verifyDecrypt($express, $ciphertext)
{
$xorObj = new XOR();
$newString = (string) $xorObj->decrypt($express, $ciphertext);

print_r($newString);
exit;
list($ipAddress, $randString, $date) = explode('-', $newString);
if ($ipAddress != '123.57.180.54') {
$this->errorMsg('ERROR : IP NOT EXIST');
return false;
}
return true;
}
调用得到:123.57.180.54-V8u2e-20170630162206

具体解密代码:
class XOR {
public function xordecrypt($str, $key)
{
$slen = strlen($str);
$klen = strlen($key);
for ($i=0; $i < $slen; $i = $i + $klen) {
$string = substr($str, $i, $klen );
$xorString .= $key ^ $string;
}
return $xorString ? $xorString : '';
}

public function decrypt($express, $ciphertext)
{
$express = str_replace("'", "", $express);
$expressNum = substr($express, 20, 2);

$ciphertext = str_replace("'", "", $ciphertext);
$ciphertextArr = explode('-', $ciphertext);
foreach ($ciphertextArr as $cipher) {
if (!$cipher) {
break;
}
//异或运算
$xordecryptString = $this->xordecrypt($expressNum, intval($cipher));
//ASCII转字符串
$newString .= chr($xordecryptString);
}
return $newString;
}
}
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!