在研究Discuz 的时候,发现Discuz有一套相当完美的加密算法(相对而言)。这个算法可以将数据加密后,储存起来,到需要用的时候,用之前加密的秘钥将之还原。
除了这个之外,还有AES这个算法能够将数据很好的加密起来,在传输过程中不容易被破解。
在PHP中,我们必须先安装好mcrypt这个模块,并且添加相应版本的扩展到php中,详情可以看 不重新编译PHP安装Mcrypt扩展
AES加密模式和填充方式有以下之中,但不是全部
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
AES/CBC/NoPadding 16 不支持
AES/CBC/PKCS5Padding 32 16
AES/CBC/ISO10126Padding 32 16
AES/CFB/NoPadding 16 原始数据长度
AES/CFB/PKCS5Padding 32 16
AES/CFB/ISO10126Padding 32 16
AES/ECB/NoPadding 16 不支持
AES/ECB/PKCS5Padding 32 16
AES/ECB/ISO10126Padding 32 16
AES/OFB/NoPadding 16 原始数据长度
AES/OFB/PKCS5Padding 32 16
AES/OFB/ISO10126Padding 32 16
AES/PCBC/NoPadding 16 不支持
AES/PCBC/PKCS5Padding 32 16
AES/PCBC/ISO10126Padding 32 16
|
下面就是在PHP中使用AES对数据加密
AES-CBC 加密方案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
$privateKey = "1234567812345678" ;
$iv = "1234567812345678" ;
$data = "Test String" ;
//加密
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey , $data , MCRYPT_MODE_CBC, $iv );
echo ( base64_encode ( $encrypted ));
echo '<br/>' ;
//解密
$encryptedData = base64_decode ( "2fbwW9+8vPId2/foafZq6Q==" );
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey , $encryptedData , MCRYPT_MODE_CBC, $iv );
echo ( $decrypted );
?>
|
AES-ECB加密方案
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
|
<?php
//加密
$key = '1234567890123456' ;
$content = 'hello' ;
$padkey = pad2Length( $key ,16);
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '' , MCRYPT_MODE_ECB, '' );
$iv_size = mcrypt_enc_get_iv_size( $cipher );
$iv = mcrypt_create_iv( $iv_size , MCRYPT_RAND); #IV自动生成?
echo '自动生成iv的长度:' . strlen ( $iv ). '位:' .bin2hex( $iv ). '<br>' ;
if (mcrypt_generic_init( $cipher , pad2Length( $key ,16), $iv ) != -1)
{
// PHP pads with NULL bytes if $content is not a multiple of the block size..
$cipherText = mcrypt_generic( $cipher ,pad2Length( $content ,16) );
mcrypt_generic_deinit( $cipher );
mcrypt_module_close( $cipher );
// Display the result in hex.
printf( "128-bit encrypted result:n%snn" ,bin2hex( $cipherText ));
print ( "<br />" );
}
//解密
$mw = bin2hex( $cipherText );
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '' , MCRYPT_MODE_ECB, '' );
if (mcrypt_generic_init( $td , $padkey , $iv ) != -1)
{
$p_t = mdecrypt_generic( $td , hexToStr( $mw ));
mcrypt_generic_deinit( $td );
mcrypt_module_close( $td );
$p_t = trimEnd( $p_t );
echo '解密:' ;
print ( $p_t );
print ( "<br />" );
print (bin2hex( $p_t ));
echo '<br><br>' ;
}
//将$text补足$padlen倍数的长度
function pad2Length( $text , $padlen ){
$len = strlen ( $text )% $padlen ;
$res = $text ;
$span = $padlen - $len ;
for ( $i =0; $i < $span ; $i ++){
$res .= chr ( $span );
}
return $res ;
}
//将解密后多余的长度去掉(因为在加密的时候 补充长度满足block_size的长度)
function trimEnd( $text ){
$len = strlen ( $text );
$c = $text [ $len -1];
if (ord( $c ) < $len ){
for ( $i = $len -ord( $c ); $i < $len ; $i ++){
if ( $text [ $i ] != $c ){
return $text ;
}
}
return substr ( $text , 0, $len -ord( $c ));
}
return $text ;
}
//16进制的转为2进制字符串
function hexToStr( $hex )
{
$bin = "" ;
for ( $i =0; $i < strlen ( $hex )-1; $i +=2)
{
$bin .= chr (hexdec( $hex [ $i ]. $hex [ $i +1]));
}
return $bin ;
}
|
AES-ECB加密方案
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php
$key = '1234567890123456' ;
$key = pad2Length( $key ,16);
$iv = 'asdff' ;
$content = 'hello' ;
$content = pad2Length( $content ,16);
$AESed = bin2hex( mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key , $content ,MCRYPT_MODE_ECB, $iv ) ); #加密
echo "128-bit encrypted result:" . $AESed . '<br>' ;
$jiemi = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key ,hexToStr( $AESed ),MCRYPT_MODE_ECB, $iv ); #解密
echo '解密:' ;
echo trimEnd( $jiemi );
?>
|
以上只是我列出的简单的3种加密方法,事实上还有很多中方法,需要我们不断的学习。密码学的道路还任重而道远。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.shiniv.com/2013/11/use-aes-encryption-algorithm-to-encrypt-data-in-php/