导航
导航

制作自己独特的BASE64 加密算法 (APP接口实战)

最近在做一个APP的接口,以前没接触过类似的项目所以遇到了一些问题,今天就来说说接口传递安全问题。

因为使用的是用php写的一个API,所有数据通过POST,GET来传递,这样一来如果是进行密码登陆这样的操作,那么密码很容易就被别人截取到然后XXOO,反正就很危险,加密是必须的,但是考虑各种成本最后我打算用运用最广的base64来加密。

什么是base64?

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一。
Base64编码可用于在HTTP环境下传递较长的标识信息。

为什么要使用Base64?

在设计这个编码的时候,我想设计人员最主要考虑了3个问题:
1.是否加密?
2.加密算法复杂程度和效率
3.如何处理传输?

  加密是肯定的,但是加密的目的不是让用户发送非常安全的Email。这种加密方式主要就是“防君子不防小人”。即达到一眼望去完全看不出内容即可。
基于这个目的加密算法的复杂程度和效率也就不能太大和太低。和上一个理由类似,MIME协议等用于发送Email的协议解决的是如何收发Email,而并不是如何安全的收发Email。因此算法的复杂程度要小,效率要高,否则因为发送Email而大量占用资源,路就有点走歪了。

  但是,如果是基于以上两点,那么我们使用最简单的恺撒法即可,为什么Base64看起来要比恺撒法复杂呢?这是因为在Email的传送过程中,由于历史原因,Email只被允许传送ASCII字符,即一个8位字节的低7位。因此,如果您发送了一封带有非ASCII字符(即字节的最高位是1)的Email通过有“历史问题”的网关时就可能会出现问题。网关可能会把最高位置为0!很明显,问题就这样产生了!因此,为了能够正常的传送Email,这个问题就必须考虑!所以,单单靠改变字母的位置的恺撒之类的方案也就不行了。关于这一点可以参考RFC2046。
基于以上的一些主要原因产生了Base64编码。

以上摘自百度百科,有兴趣的可以去看看《base64_百度百科》。

实现过程:

1.将字符串中的每个字符转换成8位的2进制数(位数不够在高位加0,如a的2进制数为‘1100001’,这是个7位字符,那就在高位加个0,变为‘01100001’),将每个字符的2进制数连在一起就得到一个一长串的0,1。

2.再在这一个串中6位6位的取数将其转化为10进制数,就可以在如下表中对应找到字符,这样就得到了加密后的字符串。

3.在处理最后一个6位时可能碰到,2进制字符串就剩2位或4位的情况,就在最后加4个0或2个0凑足6位,加4个0时就要在最后得到的加密后的字符串加2个’=’号,2个就加一个‘=’号

解密就时相反过程,就不详细叙述了,直接上代码。

加密函数代码如下:

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
function encode_base64($str){
//字符长度
$strlen = strlen($str);
/*将字符串中的每个字符转换成8位的2进制数(位数不够在高位加0,如a的2进制数为‘1100001’,这是7位字符,那就在高位加个0,变为‘01100001’),将每个字 符的连在一起就得到一个一长串的2进制数*/
for($i = 0; $i < $strlen; ++$i){
$asc = sprintf("%b", ord($str[$i]));
// 补0
$as_len = 8 - strlen($asc);

for($j = 0; $j < $as_len; ++$j) $asc ='0' . $asc;

$tmp1 .= $asc;
}
$tmp1;
//二进制的字数
$len1 = $strlen * 8;
/*在处理最后一个6位时可能碰到,2进制字符串就剩2位或4位的情况,就在最后加4个0或2个0凑足6位,加4个0时就要在最后得到的加密后的字符串加2个'='号,2 个就加一个‘=’号*/
$residue = $len1 % 6;
if($residue)
$len2 = 6 - $len1 % 6;
else
$len2 = 0;
$len2;
$len3 = ($len1 + $len2) / 6;
if($len2) $tmp1 .= $len2 > 2 ?'0000' :'00';
/*6位6位的取数将其转化为10进制数,对应下表中找到字符*/
$base64_alphabet = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/','=');
for($i = 0; $i < $len3; ++$i) $decode_str .= $base64_alphabet[bindec(substr($tmp1, $i * 6, 6))];
if($len2){
$decode_str .= $len2 > 2 ?'==' :'=';
}
return $decode_str;
}

解密函数代码如下:

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
function decode_base64($str){

$base64_alphabet = array('A' => 0,'B' => 1,'C' => 2,'D' => 3,'E' => 4,'F' => 5,'G' => 6,'H' => 7,
'I' => 8,'J' => 9,'K' => 10,'L' => 11,'M' => 12,'N' => 13,'O' => 14,'P' => 15,
'Q' => 16,'R' => 17,'S' => 18,'T' => 19,'U' => 20,'V' => 21,'W' => 22,'X' => 23,
'Y' => 24,'Z' => 25,'a' => 26,'b' => 27,'c' => 28,'d' => 29,'e' => 30,'f' => 31,
'g' => 32,'h' => 33,'i' => 34,'j' => 35,'k' => 36,'l' => 37,'m' => 38,'n' => 39,
'o' => 40,'p' => 41,'q' => 42,'r' => 43,'s' => 44,'t' => 45,'u' => 46,'v' => 47,
'w' => 48,'x' => 49,'y' => 50,'z' => 51,'0' => 52,'1' => 53,'2' => 54,'3' => 55,
'4' => 56,'5' => 57,'6' => 58,'7' => 59,'8' => 60,'9' => 61,'+' => 62,'/' => 63,'=' => 64);
$strlen = strlen($str);

for($i = 0; $i < $strlen; ++$i){
if($str[$i] =='=') break;
else{
if(!isset($base64_alphabet[$str[$i]]))
{
//遇到没有对应的字符直接输出
echo '你想干嘛啊?';
exit();
}

$tmpstr = $base64_alphabet[$str[$i]];
$asc = sprintf("%b", $tmpstr);
}

$as_len = 6 - strlen($asc);

for($j = 0; $j < $as_len; ++$j) $asc ='0'.$asc;

$tmp1 .= $asc;
}

$len = ceil(strlen($tmp1) / 8);

for($i = 0; $i < $len; ++$i){
$decode_str .= chr(bindec(substr($tmp1, $i * 8, 8)));
}

return $decode_str;
}

使用例子:

1
2
3
echo encode_base64('我是影浅的小屋:http://blog.73zls.com')."<br>";

echo decode_base64('5oiR5piv5b2x5rWF55qE5bCP5bGL77yaaHR0cDovL2Jsb2cuNzN6bHMuY29t')."<br>";

最后总结:项目中使用把$base64_alphabet数组打乱并且引入新的符号,就可以得到自己特有的加密算法了,这样就给别人破解带来一定程度的困难,要更秘密可以用嵌套加密,而且每次加密的$base64_alphabet数组都不一样。

ps. 这是5年前写的一篇博文,最近翻到就重新发出来一下了。

支持一下
扫一扫,支持一下