PHP 加密的几种方式
在使用PHP开发Web应用的中,很多的应用都会要求用户注册,而注册的时候就需要我们对用户的信息进行处理了,最常见的莫过于就是邮箱和密码了,本文意在讨论对密码的处理:也就是对密码的加密处理。
MD5
相信很多PHP开发者在最先接触PHP的时候,处理密码的首选加密函数可能就是MD5了,我当时就是这样的:
$password = md5($_POST["password"]);
上面这段代码是不是很熟悉?然而MD5的加密方式目前在PHP的江湖中貌似不太受欢迎了,因为它的加密算法实在是显得有点简单了,而且很多破解密码的站点都存放了很多经过MD5加密的密码字符串,所以这里我是非常不提倡还在单单使用MD5来加密用户的密码的。
SHA256 和 SHA512
其实跟前面的MD5同期的还有一个SHA1加密方式的,不过也是算法比较简单,所以这里就一笔带过吧。而这里即将要说到的 SHA256
和 SHA512
都是来自于SHA2家族的加密函数,看名字可能你就猜的出来了,这两个加密方式分别生成256和512比特长度的hash字串。
他们的使用方法如下:
$password = hash("sha256", $password);
PHP内置了 hash()
函数,你只需要将加密方式传给 hash()
函数就好了。你可以直接指明 sha256
, sha512
, md5
, sha1
等加密方式。
盐值
在加密的过程,我们还有一个非常常见的小伙伴:盐值。对,我们在加密的时候其实会给加密的字符串添加一个额外的字符串,以达到提高一定安全的目的:
function generateHashWithSalt($password) {
$intermediateSalt = md5(uniqid(rand(), true));
$salt = substr($intermediateSalt, 0, 6);
return hash("sha256", $password . $salt);
}
Bcrypt
如果让我来建议一种加密方式的话, Bcrypt
可能是我给你推荐的最低要求了,因为我会强烈推荐你后面会说到的 Hashing API
,不过 Bcrypt
也不失为一种比较不错的加密方式了。
function generateHash($password) {
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
$salt = '$2y$11$' . substr(md5(uniqid(rand(), true)), 0, 22);
return crypt($password, $salt);
}
}
Bcrypt 其实就是 Blowfish
和 crypt()
函数的结合,我们这里通过 CRYPT_BLOWFISH
判断 Blowfish
是否可用,然后像上面一样生成一个盐值,不过这里需要注意的是, crypt()
的盐值必须以 $2a$
或者 $2y$
开头,详细资料可以参考下面的链接:
http://www.php.net/security/crypt_blowfish.php
更多资料可以看这里:
http://php.net/manual/en/function.crypt.php
Password Hashing API
这里才是我们的重头戏, Password Hashing API
是PHP 5.5之后才有的新特性,它主要是提供下面几个函数供我们使用:
password_hash() – 对密码加密.
password_verify() – 验证已经加密的密码,检验其hash字串是否一致.
password_needs_rehash() – 给密码重新加密.
password_get_info() – 返回加密算法的名称和一些相关信息.
虽然说 crypt()
函数在使用上已足够,但是 password_hash()
不仅可以使我们的代码更加简短,而且还在安全方面给了我们更好的保障,所以,现在PHP的官方都是推荐这种方式来加密用户的密码,很多流行的框架比如 Laravel
就是用的这种加密方式。
$hash = password_hash($passwod, PASSWORD_DEFAULT);
对,就是这么简单,一行代码,All done。
PASSWORD_DEFAULT
目前使用的就是 Bcrypt
,所以在上面我会说推荐这个,不过因为 Password Hashing API
做得更好了,我必须郑重地想你推荐 Password Hashing API
。这里需要注意的是,如果你代码使用的都是 PASSWORD_DEFAULT
加密方式,那么在数据库的表中,password字段就得设置超过60个字符长度,你也可以使用 PASSWORD_BCRYPT
,这个时候,加密后字串总是60个字符长度。
这里使用 password_hash()
你完全可以不提供盐值 (salt)
和 消耗值 (cost)
,你可以将后者理解为一种性能的消耗值, cost
越大,加密算法越复杂,消耗的内存也就越大。当然,如果你需要指定对应的盐值和消耗值,你可以这样写:
$options = [
'salt' => custom_function_for_salt(), //write your own code to generate a suitable salt
'cost' => 12 // the default cost is 10
];
$hash = password_hash($password, PASSWORD_DEFAULT, $options);
密码加密过后,我们需要对密码进行验证,以此来判断用户输入的密码是否正确:
if (password_verify($password, $hash)) {
// Pass
}
else {
// Invalid
}
很简单的吧,直接使用 password_verify
就可以对我们之前加密过的字符串(存在数据库中)进行验证了。
然而,如果有时候我们需要更改我们的加密方式,如某一天我们突然想更换一下盐值或者提高一下消耗值,我们这时候就要使用到 password_needs_rehash()
函数了:
if (password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12])) {
// cost change to 12
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
// don't forget to store the new hash!
}
只有这样,PHP的 Password Hashing API
才会知道我们重现更换了加密方式,这样的主要目的就是为了后面的密码验证。
简单地说一下 password_get_info()
,这个函数一般可以看到下面三个信息:
algo – 算法实例
algoName – 算法名字
options – 加密时候的可选参数
所以,现在就开始用PHP 5.5吧,别再纠结低版本了。
PHP 加密的几种方式的更多相关文章
- 对Java代码加密的两种方式,防止反编译
使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的j ...
- java 实现md5加密的三种方式与解密
java 实现md5加密的三种方式 CreateTime--2018年5月31日15点04分 Author:Marydon 一.解密 说明:截止文章发布,Java没有实现解密,但是已有网站可以免费 ...
- jmeter对接口测试入参进行MD5加密的5种方式
在使用jmeter做测试的过程中,经常需要对请求的入参进行加密,下面列举几种常用的方法,以登录请求密码需要MD5加密为例. 虽然可以先把参数化的明文密码都先md5加密,而不是在登录前先执行加密,但是实 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 10.持续传输大块数据流的两种方式(如:文件)
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- iOS字体加载三种方式
静态加载 动态加载 动态下载苹果提供的多种字体 其他 打印出当前所有可用的字体 检查某字体是否已经下载 这是一篇很简短的文章,介绍了 iOS 自定义字体加载的三种方式. 静态加载 这个可以说是最简单最 ...
- 实现web数据同步的四种方式
http://www.admin10000.com/document/6067.html 实现web数据同步的四种方式 1.nfs实现web数据共享 2.rsync +inotify实现web数据同步 ...
- android 数据存储的几种方式
总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.其中文件和数据库可能用的稍多一些,文件用起来较为方便,程序可以自己定义格式:数据库用起稍烦锁一些,但它有它的优点,比如在海量数 ...
- C# 连接SQL Server数据库的几种方式--server+data source等方式
如何使用Connection对象连接数据库? 对于不同的.NET数据提供者,ADO.NET采用不同的Connection对象连接数据库.这些Connection对象为我们屏蔽了具体的实现细节,并提供了 ...
- web.config文件中配置数据库连接的两种方式
web.config文件中配置数据库连接的两种方式 标签: 数据库webconfig 2015-04-28 18:18 31590人阅读 评论(1)收藏举报 分类: 数据库(74) 在网站开发 ...
随机推荐
- 微信公众平台自定义菜单及高级接口PHP SDK
本文介绍介绍微信公众平台自定义菜单及高级接口的PHP SDK及使用方法. 作者 方倍工作室 修正记录: 2014.05.03 v1.0 方倍工作室 http://www.cnblogs.com/txw ...
- Android各个版本 版本号对应关系表
Platform Version API Level VERSION_CODE Notes Android 5.0 21 LOLLIPOP Platform Highlights Android 4. ...
- 装饰器、生成器,迭代器、Json & pickle 数据序列化
1. 列表生成器:代码例子 a=[i*2 for i in range(10)] print(a) 运行效果如下: D:\python35\python.exe D:/python培训/s14/day ...
- 在CDialog::OnInitDialog设置DEFAULT-BUTTON的注意事项
如果你的Dialog是在资源编辑器里面创建的,那么你首先要去资源编辑器把对应的Button的Default Button选项设置为True 另外,如果你使用GotoDlgCtrl,那么记得OnInit ...
- Linux-QT 开发环境搭建以及编译镜像
搭建Linux-QT 开发环境,需要先搭建Android 的编译环境,然后在Android 编译环境的基础上,再搭建Linux-QT 编译环境. 第一:编译器. 第二:设置环境变量.环境变量设置后,编 ...
- System.Threading.Timer使用心得
System.Threading.Timer 是一个使用回调方法的计时器,而且由线程池线程服务,简单且对资源要求不高. "只要在使用 Timer,就必须保留对它的引用."对于任何托 ...
- redhat vim编辑器永久添加行号
cd ~ vim .vimrc 第一行加入: set nu :wq 保存退出,即可 如果想取消设置,同理删除set nu即可
- Leetcode: Implement Trie (Prefix Tree) && Summary: Trie
Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs a ...
- !!常见的上穿突破M20方式——突破还是试探的判断
1和2相似之处在于M5<M20, 最大的区别是M20和M5之间的间距在放大还是缩小,如果是放大,大盘会先试探一下.如果越缩越小,大盘必须选择方向 但是必须注意的是,即使是夹角缩小,选在方向不一定 ...
- stucts2 基础程序
参考<Struts2+Hibernate+Spring> index.jsp