资讯专栏INFORMATION COLUMN

PHP笔记 —— crypt方法

loostudy / 1363人阅读

摘要:关于方法是一个单向的字符串哈希方法。另外,在之前的分支版本以及之前的分支版本,如果的值为,会返回一个使用算法的哈希值,而之后的版本则返回。

关于方法

crypt是一个单向的字符串哈希方法。

string crypt ( string $str [, string $salt ] )

$str是需要进行哈希的字符串。

$salt是进行哈希时使用盐值,是个可选项。

例如以下代码:


会输出类似的结果:

$1$1Y.rRSxY$htFPrMkCbV.Av.yh2lTJd.

注意:从PHP 5.6.0开始,如果没有传$salt参数,会报E_NOTICE错误。

关于盐值

我们既没有指定使用的算法,也没有指定盐值,crypt是怎么知道使用什么算法和盐值的呢?其实crypt是根据$salt参数来判断使用哪种哈希算法。也就是说,$salt本身就包含了算法的类型以及哈希时实际用到盐值

我们先来看看,如果没有传$salt的话,crypt会如何处理。 在5.3版本前,PHP在安装的时候会根据系统的crypt()方法检测可用的算法。如果没有提供$salt参数,PHP会使用自动产生一个标准的两个字符(DES)的盐值或者一个12个字符(MD5)的盐值,视乎MD5算法是否可用。

从PHP 5.3版本开始,PHP包含了自身实现的crypt算法,包括MD5、标准DES、扩展DES和Blowfish算法。如果系统不支持这些算法,就会使用PHP自己实现的。例如上面那个例子,最终使用的是MD5算法的盐值。

PHP设置了一个常量CRYPT_SALT_LENGTH,用来表示盐值最大允许的长度。

关于算法

那crypt是怎么根据盐值判断不同的算法呢?其实它是按照一定规则去匹配盐值,如果符合某个算法的规则,就表示使用哪种算法。我们逐一看下目前支持的几种算法。

标准DES(Standard DES)

在没有匹配到其他算法的情况下,则使用标准DES算法,此时取前两个字符为盐值(不足两个字符则返回*0):


盐值的字符必须是./0-9A-Za-z里的字符,否则会引起 crypt()失败(个人测了下,好像字符的范围要比文档里说的大)。

使用这个算法时,$str只取前面8个字符,所以无论字符串有多长,如果前8个字符一样,在盐值一样的情况下,返回的哈希值也是一样的。

扩展DES(Extended DES)

以下划线_开头,后面紧接着4字节的迭代次数和4字节的盐值:


同样的,那8个字节的字符必须是./0-9A-Za-z里的字符。

MD5

$1$开头,然后是12个字符以内的盐值:


其实例子里的$1$rasmusle$最后一位改成任何字符都不会影响结果,例如$1$rasmuslea$1$rasmusle1得到的结果跟$1$rasmusle$是一样的,因为最后一位一定是$,没有的话会自动补上。例如$1$rasm会变成$1$rasm$$1$会变成$1$$

Blowfish

$2a$$2x$或者$2y$开头,然后是用于cost参数的两位数字,紧接着一个$字符,最后是22位./0-9A-Za-z范围里的字符:


两位数字用于表示Blowfish算法的迭代次数,是以2位底的对数,范围为04-31。在PHP 5.3.7版本之前,只支持$2a$作为前缀,5.3.7之后,增加了$2x$$2y$两种前缀,用于解决一些安全性问题。如果使用5.3.7版本或以上,建议使用$2y$

使用这个算法的时候,$str最长支持72个字符,超过会被截掉。

SHA256

$5$开头,然后是16个字符的盐值,盐值之前还可以使用rounds=$的格式表明哈希的循环次数(N):


rounds的默认值为5000,范围是1000到999,999,999,如果N不在这个范围里,会被截取到最接近的范围里。

PHP 5.3.2增加的算法,算法的实现基于Ulrich Drepper的实现。

SHA512

$6$开头,然后是16个字符的盐值,盐值之前还可以使用rounds=$的格式表明哈希的循环次数(N):


rounds的默认值为5000,范围是1000到999,999,999,如果N不在这个范围里,会被截取到最接近的范围里。

PHP 5.3.2增加的算法,算法的实现基于Ulrich Drepper的实现。

如何判断支持哪种算法

crypt提供了以下的常量来标识是否支持某个算法(1表示支持,0表示不支持):

CRYPT_STD_DES

CRYPT_EXT_DES

CRYPT_MD5

CRYPT_BLOWFISH

CRYPT_SHA256

CRYPT_SHA512

关于输出结果

从上面的那些例子的输出可以看到,crypt方法输出的结果其实包含了盐值本身。所以我们能从输出结果的本身知道这个结果是使用哪个算法和什么盐值进行运算的。

另外,如果盐值包含了非法的字符,例如通常盐值都要求是./0-9A-Za-z范围里的字符,如果不是的话,crypt会返回结果*0。另外,在5.5.21之前的5.5分支版本以及5.6.5之前的5.6分支版本,如果$salt的值为*0,会返回一个使用DES算法的哈希值,而之后的版本则返回*1

关于验证

要验证一字符串的哈希值,我们一般是用相同的盐值相同的算法进行一次运算,然后跟之前的值进行比较。而使用crypt方法,由于它的输出结果本身就带有算法和盐值的信息,我们只需要把输出结果当做$salt参数即可:


为了防止基于时间的攻击,PHP 5.6提供了一个更为安全的字符串比较方法hash_equals(),建议使用:


参考

http://php.net/manual/en/func...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22873.html

相关文章

  • PHP加密与实际应用

    摘要:加密算法以字符十六进制数字形式返回散列值。加密算法是加密是的干扰码,使编码更安全可选的盐值字符串。返回的数据可能是二进制的 数据加密可以简单的理解为:明文(文件或者数据)-->算法处理-->不可读的密文,进而达到加密的效果。 php中的几种加密方式 md5加密算法 crypt算法 sha1加密算法 URL编码技术编码 base64编码 其中 md5、crypt、sha1 都是单向加...

    lakeside 评论0 收藏0
  • phalcon简易指南

    摘要:帮助你开始使用的简易指南。第一种方式参考第二种方式参考使用参考简单粗暴的理解是把下的对应成数据库的表,类属性对应表字段。 帮助你开始使用 phalcon 的简易指南。 简介 Phalcon 2将于2015年4月17日发布,这个版本大约85%的代码是基于 Zephir 语言重写的。Zephir是开源的,使用类似PHP语法的语言,生成C语言代码,并编译成PHP扩展。这提高了PHP扩展的开发...

    whataa 评论0 收藏0
  • Golang 实现RSA 加密解密(附带php

    摘要:安全总是很重要的,各个语言对于通用的加密算法都会有实现。对于和加密算法本身,请查阅相关资料在中,很多功能经常是一个函数解决而中的却不是。该文讨论加密解密。一概要这是一个非对称加密算法,一般通过公钥加密,私钥解密。 安全总是很重要的,各个语言对于通用的加密算法都会有实现。前段时间,用Go实现了RSA和DES的加密解密,在这分享一下。(对于RSA和DES加密算法本身,请查阅相关资料) 在P...

    kun_jian 评论0 收藏0
  • 10 个 Nginx 的安全提示

    摘要:声明是重写模块评估指令强制性的部分。看起来唯一正确的解决方案是在非重写的指令内完全禁用。我们上周发布了这个流行指令的潜在安全漏洞介绍。将设低来防止攻击。限制用户连接数来预防攻击。认证默认使用,它的哈希并不安全。保持与最新的安全更新。 Nginx是当今最流行的Web服务器之一。它为世界上7%的web流量提供服务而且正在以惊人的速度增长。它是个让人惊奇的服务器,我愿意部署它。 下面是一个常...

    wemall 评论0 收藏0
  • 10 个 Nginx 的安全提示

    摘要:声明是重写模块评估指令强制性的部分。看起来唯一正确的解决方案是在非重写的指令内完全禁用。我们上周发布了这个流行指令的潜在安全漏洞介绍。将设低来防止攻击。限制用户连接数来预防攻击。认证默认使用,它的哈希并不安全。保持与最新的安全更新。 Nginx是当今最流行的Web服务器之一。它为世界上7%的web流量提供服务而且正在以惊人的速度增长。它是个让人惊奇的服务器,我愿意部署它。 下面是一个常...

    meteor199 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<