生成安全的PHP随机数和密码 | generate security strong PHP random

生成安全的PHP随机数和密码(php5.3+)

随机数

一般我们都是使用rand,mt_rand由这些函数来组是不太安全的。

  1. linux附带两个接口的随机数,/dev/random(专家说有阻塞性web哪就不适合用) /dev/urandom合适生成安全的php随机数。使用fopen fread来读取内容。
    1.详见
  2. mcrypt_create_iv() 和 openssl_random_pseudo_bytes()来生成随机数,再用bin2hex把ASCII码转成16进制

密码

1.到现我们可能还在使用md5算法加密方式,在官方文档http://php.net/manual/zh/function.md5.php都明确注释(NOTE)依赖md5算法来对明文加密不够复杂且也不推荐,哪今天介绍几种加密算法

官方说的”盐”,password_hash()或者crypt()来保存”盐”,password_verify()或者crypt()对密码进行验证。官方说明图如下:

1
2
3
4
5
6
7
8
9
10
$pwd = "test123";//原密码
$algorithm = '$2y$'; //基于BlowFish
$algorithmOptionsCost = '10$';
$salt = bin2hex(openssl_random_pseudo_bytes(32));//也可以用上面提到的bin2hex(mcrypt_create_iv())和bin2hex(fread(fopen('/dev/urandom')),32)
$encryption = crypt($pwd, $algorithm . $algorithmOptionsCost . $salt . '$');
if ($encryption === crypt($pwd, substr($encryption,0, 29)))
echo 'yes';
else
echo 'no';
}
1
2
3
4
5
6
7
8
//password_hash()是crypt()的简单封装版
$pwd = "test123";//原密码
$option = ['salt'=>bin2hex(mcrypt_create_iv(32))];
$encryption = password_hash($pwd, PASSWORD_BCRYPT, $option) //加密的密码
if(password_verify($pwd, $encryption))
echo 'yes';
else
echo 'no'

对称加密方式(symmetric encryption) phpversion5.5+

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
function AESEncrypt($text, $key) {
$ivsize = openssl_cipher_iv_length('aes-256-cbc'); //生成iv的长度
$iv = openssl_random_pseudo_bytes($ivsize); //生成字符串
$keys = hash_pbkdf2('sha256', $key, $iv, 80000, 64, true); //生成keys
$encKey = substr($keys, 0, 32); // 分隔encryption的key
$hmacKey = substr($keys, 32); // 分隔hmac的key
$ciphertext = openssl_encrypt(
$text,
'aes-256-cbc',
$encKey,
OPENSSL_RAW_DATA,
$iv
);
$hmac = hash_hmac('sha256', $iv . $ciphertext, $hmacKey);
return $hmac . $iv . $ciphertext;
}
}
function AESDecrypt($text, $key) {
$hmac = substr($text, 0, 64);
$ivsize = openssl_cipher_iv_length('aes-256-cbc');
$iv = substr($text, 64, $ivsize);
$ciphertext = substr($text, $ivsize + 64);
// Generate the encryption and hmac keys
$keys = hash_pbkdf2('sha256', $key, $iv, 80000, 64, true);//生成encryption 和 hmac 的key
$encKey = substr($keys, 0, 32);
$hmacNew = hash_hmac('sha256', $iv . $ciphertext, substr($keys, 32));
if (!hash_equals($hmac, $hmacNew)) {
return false;
}
return openssl_decrypt(
$ciphertext,
'aes-256-cbc',
$encKey,
OPENSSL_RAW_DATA,
$iv
);
}