读《PHP安全之道》提纲挈领笔记
六、PHP与密码安全
1、用户密码安全
(1)加密密码
存储用户密码前应该先对密码进行加密(MD5,SHA等算法),然后存储在数据库中。
不建议使用des
和MD5
等若加密算法,散列算法推荐使用SHA256
或SHA512
。
hash("sha256",$password);
(2)密码加盐
使用盐(salt)来混淆加密后的值。
采用随机salt,来加大安全系数。
$salt=rand(1,10000);
$password=sha1($password.$salt);
可以生成较复杂的salt
base64_encode(mcrypt_create_iv(32,MCRYPT_DEV_RANDOM));
使用 password_hash()
函数,指定第二个参数为PASSWORD BCRYPT
$password = password_ hash($password,PASSWORD_ BCRYPT);
(3)定期修改
一个完整的密码安全策略,用户应该周期性地进行密码修改。
2、防止暴力破解
典型的暴力攻击表现为攻击者通过大量的尝试来试图登录系统。在多数情况下,用户名是已知的,而只需要猜测密码。
常见的防御方法有以下几种。
① 使用验证码进行验证登录。
② 使用Token生成form_hash,然后验证。
③ 使用随机数时,要确保用户无法获取随机数生成算法。
④ 身份验证需要用户凭短信、邮件接收验证码时,需要对验证次数进行限制。
⑤ 限制某时间段内验证次数。
⑥ 用户在设置密码时要求用户使用特殊字符和字母数字组合,并限制最小长度。
3、随机数安全
随机数有真随机数和伪随机数之分。
真随机数使用真随机数发生器(True Random Number Generator, TRNG)生成,是利用不可预知的物理方式来产生的随机数,例如掷钱币、骰子,转轮,使用电子元件的噪声、核裂变等。
伪随机数使用伪随机数发生器(PseudoRandomNumber Generator, PRNG)生成, 是计算机利用一定的算法或种子来产生的。
计算机中生成的都是伪随机数,其中伪随机又分为强伪随机数(难以预测的随机数)和弱伪随机数(易于预测的随机数)。项目中通常使用随机数的场景有密码salt生成、验证码生成、Token生成、UUID生成、密钥生成、数字签名生成、加密向量生成、Nonce生成等。
不正确地使用随机数会导致一系列的安全问题 。
① 在研发过程中使用时间戳作为随机数[MD5(时间戳),MD5(用户ID+时间戳)],但是由于时间戳是可以预测的,因此很容易被猜解。
② 生成密码用的slat以及找回密码的Token,需要一个随机数,如果直接根据用户ID成Token,很容易被攻击者猜解。
③ OAuth 2.0中需要第三方传递一个state参数作为CSRF Token来防止CSRF攻击,很多研发人员根本不使用这个参数,或者是传入一个固定的值。由于认证方无法对这个值进行业务层面的有效性校验,导致了OAuth的CSRF攻击。
④ 在抽奖程序中如果使用的随机数不均匀或者可猜解,可直接造成奖品损失。
⑤ PHP5 windows 存在rand()随机不均匀情况避免使用rand(),建议使用mt_rand()
。
⑥ PHP7 提供了很好的实现方法,使用random_int 与 random_bytes来生成随机数。
4、数字摘要
数字摘要也称作数字签名,是将任意长度的消息变成固定长度的短消息。
它是一个单向的、不可逆转的加密方法,一般采用单项Hash函数将需要加密的明文“摘要”成一串固定长度(如128位)的密文,这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文结果总是不同的,而同样的明文摘要必定一致。
数字摘要常用于互联网上传输的信息加密认证,进行防篡改识别。
常用的数字摘要算法有MD5和SHA等。
消息摘要算法第五版(Message Digest Algorithm MD5,MD5)是计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。MD5被广泛用于数字摘要,是因为对原数据进行任何改动,哪怕只修改1字节,所得到的MD5值都有很大区别。并且,已知原数据和其MD5值,要找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
其他常用的散列函数:
hash file()
: 使用给定文件的内容生成散列值。
hash_hmac()
: 使HMAC方法生成密钥散列值。
hash_init()
: 初始化增量散列运算。
hash()
:生成散列值。
password_hash()
: 创建散列密码。
crypt()
:返回一个基于标准UWIX DES算法或系统上其他可用的替代算法的散列字符串。
5、MA和HMAC简介
消息认证码(Message Authentication Code, MAC) 在发送消息的基础上通过Key生成加密摘要,通常被用于检测消息在传输过程中是否被篡改。
MAC消息认证过程如图:
消息的发送方通过密钥和MAC算法生成MAC数据标记,然后将消息和MAC标签发送到接收方。消息接收方依次使用相同的密钥通过相同的MAC算法运行传输的消息部分,产生MAC数据标签。接收器将在传输中接收的MAC标签与自己生成的MAC标签进行比较。如果它们相同,则接收方可以认为消息在传输期间未发生改变或篡改。
同时,为了防止重放攻击,消息本身必须包含确保该相同消息仅能被发送一次的数据,例如使用时间戳、序列号或使用一次MAC。
散列消息身份验证码(Hashed Message Authentication Code,HMAC)是在MAC算法基础上基于加密散列算法实现的。如PHP使用hash_hmac()
函数。
6、对称加密
对称加密算法是指,数据发信方将明文(原始数据)和密钥一起经过加密处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若要解读原文,则需要使用加密密钥及相同算法的逆算法对密文进行解密,使其恢复成可读明文。对称加密算法的优点是算法公开、计算量小、加密速度快、加密效率高,适用于加密大量数据的场合。
常用的算法有DES、3DES、TDEA、Blowfish、 RC2、RC4、RC5、IDEA、SKIPJACK、 AES等。
PHP中如果需要使用对称加密算法,则需要mcrypt扩展的支持。
7、非对称加密
对称加密算法在加密和解密时使用的是同一个密钥。与对称加密算法不同,非对称加密算法需要两个密钥一一公开密钥 (public key,简称公钥)和私有密钥(private key,简称私钥)进行加密和解密。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
在非对称加密中使用的主要算法有RSA、Elgamal、背包算法、Rabin、D-H、ECC (椭圆曲线加密算法)等。RSA是目前最有影响力的公钥加密算法之一,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO组织推荐为公钥数据加密标准。
END
如有问题请在下方留言。
或关注我的公众号“孙三苗”,输入“联系方式”。获得进一步帮助。