
在利用PHP来开展Web应用开发的工作之中, 非常多的项目会提出需要让使用者来进行注册的请求, 当处在进行注册的这个环节之时, 就需要我们去执行针对用户所提供信息的处理操作了, 大家见得比较多的情况无非就是涉及到邮箱以及密码这两个方面内容了, 本文所希望探讨的核心议题在于对密码这一项要素的处理工作, 具体而言也就是围绕着如何实施对密码的加密这个方面的问题展开分析。MD5我相信对于众多初次接触PHP语言的开发者来讲, 在面对密码需要加密的情况时, 很多人会自然而然地将MD5这一个函数当成首选, 而我在那段日子当中就是完全处于这种状态之下的。$password md5($_POST[password]);看着上面这段代码, 你是不是有一种很熟悉的感觉? 不过, MD5这种加密方法, 在现在这个PHP的大环境里, 看起来并不是特别吃得开。为啥? 主要是它的加密算法确实有点过于简单。另外, 网上好多专门破解密码的网站, 里面都存着海量的、经过MD5处理过的密码字符串。所以基于这些原因, 我是真心非常不建议你只单单用MD5这种方式去给用户的密码做加密处理的。和其实跟前面的MD5同期的还有一个SHA1加密方式的不过也是算法比较简单所以这里就一笔带过吧。而这里即将要说到的 和 都是来自于SHA2家族的加密函数看名字可能你就猜的出来了这两个加密方式分别生成256和512比特长度的hash字串。关于他们使用的办法, 具体的状况是这么样的, 如下所叙述。$password hash(sha256, $password);PHP是自带了hash这个函数的, 你完全可以把加密方式作为一个参数直接传给hash函数, 去直接使用它, 像这样你就可以明确地指定md5或者sha1之类的加密方案进行运算。盐值我们经常会用到另一个特别普遍的东西是, 盐值, 这个家伙, 在加密的过程中。没错是这样的, 当进行加密动作之时, 会给原本要被加密的那些字符内容追加上一段额外的字符串数据这么做的目的是为了提升某些方面的安全等级达到一个更高的防护水平这样的:function generateHashWithSalt($password) {$intermediateSalt md5(uniqid(rand(), true));$salt substr($intermediateSalt, 0, 6);return hash(sha256, $password . $salt);}如果由我来给出建议, 那么我所推荐的加密方法可能只是属于基础的最低要求。这主要是因为接下来我会着重向大家介绍并强烈推荐 API 技术。尽管如此, 当前这种加密手段依然不失为一种相对较为理想的选择。function generateHash($password) {if (defined(CRYPT_BLOWFISH) CRYPT_BLOWFISH) {$salt $2y$11$ . substr(md5(uniqid(rand(), true)), 0, 22);return crypt($password, $salt);}}这其实就是函数的结合应用, 我们这里是先进行判断, 看看crypt()函数是否可以使用, 然后再像上面那种方式去生成一个盐值, 但是有一点是需要大家特别注意的, 在crypt()函数里使用的盐值必须在2a$或者2y$这两个里面选一个作为开头, 具体详细的信息资料大家可以去参考一下下面提供的这个网址链接。您可以查看更多的相关资料, 这些资料就在这里:API这里就是我们重点要讲的内容。API这个特性, 是在PHP5.5版本之后才新增的。它主要是提供下面这几个函数, 供我们来使用:password_hash() – 对密码加密.password_verify() – 验证已经加密的密码检验其hash字串是否一致.password_needs_rehash() – 给密码重新加密.password_get_info() – 返回加密算法的名称和一些相关信息.虽然 crypt() 这个函数在实际操作的层面, 算是已经能够满足大家的需求了, 可是, 这里原文有遗漏的括号内容, 需补全逻辑主体不但能够让我们的代码变得更为简短一点, 而且, 还在安全这一方面的事情, 给我们提供了一个更好的保障, 所以的话, 现在 PHP 的官方机构, 大多都是倾向于推荐去使用这样的一种方法, 来实现对用户密码的一个加密操作, 并且, 有很多那种比较流行的开发框架, 例如在原文中可能提到的某个框架, 它们也就是在使用这种相关的加密方式。$hash password_hash($passwod, PASSWORD_DEFAULT);没错, 事情就是这么容易, 只需要编写一行代码, 整个任务就算全部完成结束了。现在大家用的还是那个旧的, 所以我上面才说推荐它, 但是呢因为那个新的 API 把它超越过去了, 所以我就必须郑重其事地想向你推荐这个新的 API。这里存在一个关键点需要被引起注意, 也就是如果你在实际的代码开发过程中始终都是采取特定的加密方式来进行处理的话, 那么对应的数据库表结构里面, 字段就必须被设置为超过六个零个字符的长度规格, 与此同时, 你也拥有另一种选择路径, 即可以采用另外一种替代性的方案去进行操作, 在这种情况下, 经过加密流程之后所产生的字符串结果将会呈现出一种恒定不变的形态, 其长度总是保持在六十个字符的具体数值上。在这里, 你完全可以不提供salt值和cost值。你可以把cost理解成一种性能的消耗指标。当cost变得越大时, 加密算法就会变得越来越复杂, 从而消耗的内存也就越来越多。当然, 如果你是想要指定对应的salt值和cost值, 那么你就按照以下方式来进行编写操作。$options [salt custom_function_for_salt(), //write your own code to generate a suitable saltcost 12 // the default cost is 10];$hash password_hash($password, PASSWORD_DEFAULT, $options);在密码被加密完成之后, 我们还得去对那个密码进行验证的这么一个动作, 通过这个验证的过程, 来确定一下用户当前输入的密码到底是不是正确无误的一个状态:if (password_verify($password, $hash)) {// Pass}else {// Invalid}其实这个事儿是很简单的, 直接把那个代码拿过来用就完了, 它能对咱们之前已经加密好了的字符串进行校验工作的, 而这些个字符串, 是实实在在地存放在数据库里面的。可是, 在有些时候, 咱们得换掉原本的加密法子。比方说, 在某一天, 冷不丁就想改一下那个盐值, 或者是想把消耗值给提上去。遇到这种场合, 咱们就得把 h 函数给用上。if (password_needs_rehash($hash, PASSWORD_DEFAULT, [cost 12])) {// cost change to 12$hash password_hash($password, PASSWORD_DEFAULT, [cost 12]);// dont forget to store the new hash!}只有这样做, PHP的API才会知道我们对加密方式进行了更换, 这样的主要目的就是为了进行密码验证。简单地说一下 () 这个函数一般可以看到下面三个信息algo – 算法实例algoName – 算法名字options – 加密时候的可选参数因此我们现在就应当开始使用php 5.5这个版本了, 对于旧版本的事情, 我们完全可以不再去进行反复的纠结和考量。