原始出处:www.smatrix.org 信息来源:邪恶八进制信息安全团队(www.eviloctal.com)文章作者:fleshwound
Author:fleshwound
From:Security Matrix(http://www.smatrix.org),转载请注明出处!
//
目录
1.    PHP的散列函数及其应用
2.    PHP中的对称密码算法及其应用
3.    PHP的公钥密码算法及其应用
///
序: 这么几年一直在潜心修炼内功,没有在网上写点东西,安全矩阵作为一个国内少有的以密码学和信息安全理论研究为特色的学术技术研究组织,在国内推广密码学应用是我们的责任,虽然这个道路比较艰辛和漫长,但总是需要人来做的。我计划对几大主流的脚本语言分别进行阐述,系统总结,力图做到普通的脚本开发者和网友能够看懂。这是第一篇关于PHP的,以下假设读者已经具有PHP的基本知识。
1.    PHP的散列函数及其应用
1.1    什么是散列函数
散列函数又被称为hash函数(哈希函数),也称杂凑函数,就是把任意长的输入消息串变化成固定长的输出串的一种函数。这个输出串就叫做该消息的哈希值(或称为杂凑值)。一般用于产生消息摘要,进行数据消息的完整性检验。严格意义上来讲,散列函数并不是密码算法,因为它是单向不可逆的。一个散列函数有以下特点:(1)输入长度是任意的,而输出长度是固定的,长度应该足够的长,以便抵抗生日攻击(关于生日攻击请百度)。(2)对每一个给定的输入,正向计算输出即散列值是很容易的,但逆向寻找碰撞时困难的。
Hash函数主要用于完整性校验和提高数字签名的有效性,在密码协议中有着非常重要的应用,目前已有很多成熟的方案。关于具体的密码学方面的知识可以到安全矩阵上去下载一些书来看。
常见散列函数(Hash函数)有两种:
(1)、MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,MD5被广泛使用,可以用来把不同长度的数据块进行暗码运算成一个128位的数值; 
(2、SHA(Secure Hash Algorithm)这是一种较新的散列算法,可以对任意长度的数据运算生成一个160位的数值。 
目前在理论上MD5和SHA已经被破解,但是在实际应用中并非那么简单,只要合理应用总是可行的。另外以下这些也被认为具有散列函数的功能。
(1)、MAC(Message Authentication Code):消息认证代码,是一种使用密钥的单向函数,可以用它们在系统上或用户之间认证文件或消息。HMAC(用于消息认证的密钥散列法)就是这种函数的一个例子。 
(2)、CRC(Cyclic Redundancy Check):循环冗余校验码,CRC校验由于实现简单,检错能力强,被广泛使用在各种数据校验应用中。
(3)、自产山寨版和基于一些对称加密算法的散列函数。
1.2 PHP中散列函数及其应用
Php中的最常用的散列函数有这么几个:
md5(),md5_file(), sha1(),sha1_file().
其实还有更为强悍和灵活的crypt和mhash系列。首先我们从简单常用的开始,先看一个列子:

复制内容到剪贴板

代码:

<?php
  
  $str="security matrix is a website about cryptograhy.";
  $hashmd5=md5($str);
  $hashsha1=sha1($str);
  echo "md5 hash value is:".$hashmd5;
  echo '<br>';
  echo "sha1 hash value is:$hashsha1";
  //最后的结果是:
  //md5 hash value is:c4558a37e61eb1db03f7270d4f674ae6
//sha1 hash value is:d10155e45624bf84b4d1fdf4e6e47e067b7a4e1a
?>

很显然,我们的字符串经过这两个函数后得到一系列没有规律的16进制序列。注意到SHA1产生的序列比MD5多了8个字符,总共SHA1这是因为SHA1是160位的散列,而MD5是128位的散列。密码学中所说的位是指二进制的位数,一个16进制占4个二进制位,所以SHA1是16进制40位,MD5是16进制32位。这两个函数的原型是:

复制内容到剪贴板

代码:

string md5 ( string str [, bool raw_output] )
string sha1 ( string str [, bool raw_output] )

其中有个可选参数raw_output是布尔类型的,默认是false,如果此处写1或者true等能够保证这个值为真的表达式。则输出时真实的消息摘要。看同样的例子:

复制内容到剪贴板

代码:

<?php
  
  $str="security matrix is a website about cryptograhy.";
  $hashmd5=md5($str,1);
  $hashsha1=sha1($str,1);
  echo "md5 hash value is:".$hashmd5;
  echo '\<br>';
  echo "sha1 hash value is:$hashsha1";
  //最后的结果是:
//md5 hash value is:腢??臂 ? OgJ鎈
//sha1 hash value is:?U銿$縿囱驿~ {zN 
?>

很显然,这有点像火星文,在MYSQL存储时这个消息摘要,有时候因为字符集会出现难以解释的人品问题。一般我们只用默认的,以16进制的形式输出的,存储方便。一般,MD5和SHA1用得最多的场合就是验证用户密码的场合。通常将用户的口令用MD5或者SHA1处理后放入数据库中,以减少万一被SQL注入攻击或者获得数据表后的暴露真实口令信息的风险。但是,由于使用标准的MD5算法,常用的口令的散列值可以很容易穷举,所以实际上寻找一个碰撞可能就比较容易了。网上有很多这样的MD5散列碰撞的查询站点。为了对付这种穷举,我们在使用时可以采用些变形或者带有salt的MAC,而且最好使用SHA1。以下给个例子:

复制内容到剪贴板

代码:

<?php
  
  $passwd="13455564432";
  $salt="dfdasafgr4vtrgrrgf";
  $str=$passwd.$salt;
  $hashmd5=md5(md5($str).$salt);
   
   echo $hashmd5; //结果:bc052554e38b588df52594176a148b8b
?>

现在我们来谈谈md5_file(), sha1_file().很显然,这个是用来计算给定文件名的散列值的。函数原型如下:

复制内容到剪贴板

代码:

string md5_file ( string filename [, bool raw_output])
string sha1_file ( string filename [, bool raw_output])

其中参数的意义和用法跟前面md5(), sha1()是一样的。我们可以来看个例子:

复制内容到剪贴板

代码:

<?php
$filename = '1.txt';
$hash = md5_file($filename);
echo $hash; //结果e0a7a59e58c7b138e850b8055fba27da
?>

这两个函数可以用来判断自己的程序文件是否被篡改过,比如是否嵌入了木马。DISCUZ论坛源码有个代码检查功能,就用这个实现。除此之外,还可以用来构造复杂的数学验证算法,防止别人破解需要授权的PHP程序。因为只要修改了程序,其文件的散列值基本上都要改变的。对脚本代码加壳当然这对于一般的程序员有一定的难度。一般应用中有这几个基本上也够用了,这是PHP默认就支持的。接下来我们来看看MAC和CRC。
其中主要的函数是mhash(),通俗的说,就是带有一个密钥的哈希函数。为什么要带个密钥呢,其实这种改进主要是为了防止散列函数的在线暴力破解和提高抗碰撞能力。函数原型如下:

复制内容到剪贴板

代码:

string mhash ( int hash, string data [, string key])

因为这个属于扩展模块,所以要使用mhash(),需要在编译PHP的时候增加一项配置,在PHP的配置时,添加--with-mhash[=DIR]。如果没有,就会出现“Fatal error: Call to undefined function…”,这个函数的第一项参数是我们要使用的哈希算法模式,由一些预定义算法模式构成,每种算法模式得到的散列值是不一样的,其中最常用的如下:

复制内容到剪贴板

代码:

MHASH_MD5 
MHASH_SHA1 
MHASH_HAVAL256  //HAVAL系列算法支持多种输出长度,从128-256
MHASH_HAVAL192 
MHASH_HAVAL160 
MHASH_HAVAL128 
MHASH_RIPEMD160 //RIPEMD系列算法也支持多种输出长度,从128-256
MHASH_GOST 
MHASH_TIGER 
MHASH_CRC32 
MHASH_CRC32B

第二项参数是我们要计算哈希值的字符串,第三项参数是密钥。除此之外,HMAC体系还有其他的一些函数,如下所示:

复制内容到剪贴板

代码:

mhash_count --获取最多能够支持的HASH函数算法模式的个数
mhash_get_block_size --获取特定预定义算法模式的散列值长度
mhash_get_hash_name --获取预定义算法名称
mhash_keygen_s2k --产生一个安全的密码散列值,完全可以取代MD5对用户输入口令的处理
mhash --计算散列值

为了说明他们的用法,我们来看看例子:

复制内容到剪贴板

代码:

<?php
$input = "security matrix";
$hash = mhash(MHASH_MD5, $input);
echo "The hash is " . bin2hex($hash) . "<br />\n";//结果是:The hash is e6cfee2c4530b72d7f8f4b010fa80a00
$hash = mhash(MHASH_MD5, $input, "smatrix");
echo "The hmac is " . bin2hex($hash) . "<br />\n";//结果是:The hmac is d3e7983ba7bdb7c7d0150e056d2c5017
echo mhash_count()."<br />\n";
$hash = MHASH_RIPEMD160;
echo mhash_get_hash_name($hash)."<br />\n"; //获取算法名称,为RIPEMD160
echo mhash_get_hash_name(24)."<br />\n"; //让我们看看它提供的24号算法模式是什么,获取算法名称,为RIPEMD256
echo mhash_get_block_size(24)."<br />\n"; //获取24号算法模式产生的散列值长度,结果为32,32*8=256,一个字符占8位

?>

其中mhash_keygen_s2k是个特别好的东西,建议PHP开发者能够用它取代传统的MD5来处理用户口令,至少让网上的这些MD5碰撞检索站点失效。mhash_keygen_s2k()函数以指定参数1-hash算法模式,指定的参数3-随机的盐,对原始口令参数2产生bytes长度(参数4)产生一个伪随机腌制的口令。所谓盐,就是在信息中添加噪声干扰,破坏其部分语义特征。 这个函数的原型是:

复制内容到剪贴板

代码:

string mhash_keygen_s2k ( int hash, string password, string salt, int bytes )

下面,我们看下具体的用法:

复制内容到剪贴板

代码:

<?php
$password = "security matrix";
$salt = "f34iffffffffj4";
$hash = MHASH_RIPEMD160;
$bytes=160;
echo mhash_keygen_s2k ( $hash, $password, $salt, $bytes ); //产生长度160的腌制后口令
//结果:
//毉v9銑B??韔?幢a 镝X K藎ù壥Vd磌?目 ?┕ ?潿(j  Iゎ忲" ? ¬潥护窯1〧//蠊得牶熔.跆]?欭:躎?  3浹か戠3-がJ篮9&?v1懏^?縋3 鄡 鳖-?鎿轐p`xxJ;?
//恏 
?>

值得注意的是,实际使用中,最好不同的用户口令使用不同的盐,相同的盐总是让人不是很放心,一般情况下,我们没必要自带一个盐库,随机产生一个又需要保留,否则到时候用户口令比较时候会出错。这里我可以给一个可行的方案,使得盐和用户口令内相关,免去记忆盐的烦恼,如下:

复制内容到剪贴板

代码:

<?php
$password = "security matrix";
$salt = md5($password);
$hash = MHASH_RIPEMD160;
$bytes=160;
echo mhash_keygen_s2k ( $hash, $password, $salt, $bytes ); //产生长度160的腌制后口令
?>

现在我们介绍最后一个单向散列函数crypt,这个很多人会误认是对称加密函数,其实不是,下一章我会专门论述PHP的对称加密算法。现在我们看看这个函数的原型:

复制内容到剪贴板

代码:

string crypt ( string str [, string salt])

这个函数使用了参数,其中第一个是我们需要求散列值的字符串,后面一个可选参数是盐。如果你自己不填,它会使用默认的盐。不过我不建议使用默认的,默认的可能会出现一些应用中的特殊问题。比如由于盐的改变导致用户口令腌制时最后的散列值不同,导致验证用户失败。这个函数如果你看PHP手册,可能会有点晕,发现该函数不知道在何处定义其散列算法。实际上认真分析会发现,它是根据盐的长度和格式来决定使用何种算法的,这是个非常古怪的方法。我们还是看看例子。

复制内容到剪贴板

代码:

<?php

if (CRYPT_STD_DES == 1) {
    echo 'Standard DES: ' . crypt('www.smatrix.org', 'rl') . "<br>\n";
}//当盐是两个字符的时候,内置的散列算法使用了标准的DES构造,也就是CRYPT_STD_DES模式

if (CRYPT_EXT_DES == 1) {
    echo 'Extended DES: ' . crypt('www.smatrix.org', '_J9..rasm') . "<br>\n";
}//当盐是九个字符的时候,内置的散列算法使用了扩展的DES构造,也就是CRYPT_EXT_DES模式

if (CRYPT_MD5 == 1) {
    echo 'MD5:          ' . crypt('www.smatrix.org', '$1$rasmusle$') . "<br>\n";
}//当盐采用$1$开头,且12个字符时,内置的散列算法使用了MD5,也就是CRYPT_MD5模式

if (CRYPT_BLOWFISH == 1) {
    echo 'Blowfish:     ' . crypt('www.smatrix.org', '$2a$07$rasmuslerd...........$') . "<br>\n";
}//当盐采用$2a$或者$2$开头,且16个字符时,内置的散列算法使用了BLOWFISH构造,也就是CRYPT_BLOWFISH 模式
//结果:
//Standard DES: rls0yK8/sarN6
//Extended DES: _J9..rasm6cqPLViS6Po
//MD5: $1$rasmusle$Z4lIslfbi/Oo4nyaxR4eB/
//Blowfish: $2a$07$rasmuslerd............wnbDKPDtWJSnGforY7iyGVP8XWLrCni
?>

PHP中关于散列算法基本已经讲完了,从上面的论述看,MHASH函数体系使用灵活而且安全性更好一些。CRYPT比较古怪,一般很少有人会使用。基本散列函数使用最方便,但是问题也较多,容易穷举。当然,并不是每个IDC都会在其PHP模块中加载MHASH,我们开发应用时一定要搞清楚服务器环境。一般可以通过phpinfo函数中信息看出来:
mhash
MHASH support     Enabled 
MHASH API Version     Emulated Support 
就写到这里,下一节是PHP的对称密码算法及其应用。希望大家能在开发时多使用成熟的密码学解决方案,而不是自己创新山寨一个。

转载于:https://www.cnblogs.com/hailuo/archive/2012/01/13/2321337.html

转:PHP中的密码学算法及其应用相关推荐

  1. optee中的密码学算法注册模型

    1.optee中Symmetric ciphers.HASH.RNG等算法的注册模型 1.1.aes_desc 结构模型 (1).如果开启硬件加速(如ARM Cryptography Extensio ...

  2. 区块链中的密码学系列之SHA256算法(三)

    1. 前言 SHA系列算法是一种密码散列函数,由美国国家安全局设计,并由美国国家标准技术研究所(NIST)发布为联邦数据处理标准(FIPS).现在已经被破解. 我们本文主要研究SHA256算法. 2. ...

  3. 比特币中的密码学知识汇总

    比特币中的密码学知识汇总 目前,我的阅读比特币源码系列文章已经更新了5篇,对应于精通比特币前3章内容的学习. 现在来到第4章密钥与地址的学习,本章主要介绍了比特币系统中公钥,私钥和地址之间相互的关系, ...

  4. 区块链中的密码学(五)-零知识证明简述

    本篇是这个系列的最后一篇,尽管在区块链中还有很多的密码学应用,将来会必然会更多,然而笔者认为,就今天我们有限的学习时间来讲的话,任何人都应该对信息的获取做减法.思来想去,选择了"零知识证明& ...

  5. Java 密码学算法

    Java 密码学算法 候捷老师在< 深入浅出MFC 2e(电子版)>中引用林语堂先生的一句话: 只用一样东西,不明白它的道理,实在不高明 只知道How,不知道Why,出了一点小问题时就无能 ...

  6. TPM分析笔记(七)TPM 模块中的密码算法家族。

    目录 密码攻击 暴力破解 根据类型来计算算法强度 针对算法本身的攻击 安全的定义 密码家族 哈希(摘要) 哈希扩展(HashExtend) 基于哈希的消息认证码(HashedMessageAuthen ...

  7. go区块链培训学习:密码学算法家族

    时至今日密码学已经发展了数千年,在公元前的古埃及就出现过使用特殊字符和简单替换形式的密码.近代密码的发展源自第一.二次世界大战对军事机密的保护.现代密码学的发展与计算机信息技术关系密切,已经发展为包括 ...

  8. 区块连中的密码学--SHA256实现机制

    区块连中的密码学–SHA256实现机制 摘要 本文主要介绍区块链中所使用的密码学知识,同时因为Hash函数是区块链中重要的一环,因此也使用python3对SHA256进行了实现. 一.什么是区块链 关 ...

  9. 区块链中的密码学应用

    区块链中应用到的密码学主要包括以下几方面: 数字摘要 区块链本质上是一种分布式数据存储方式,每一个数据区块之间靠数字摘要建立起联系,比如比特币中每一个区块都包含了它前一个区块的摘要值.因此数字摘要是区 ...

最新文章

  1. 提高网站页面收录的几个方法 返回列表 发新帖回复
  2. 监控、链路追踪、日志这三者有何区别?
  3. 单片机要学多久才能自己开发?学单片机以后做什么?
  4. spring-session源码解读 sesion
  5. 通过CH340G驱动的Nano ATMEAG328P驱动板初步测试
  6. RIPv1与RIPv2互通
  7. ServiceStack学习之一准备工作
  8. python ==》 元组
  9. rabbitmq消息重回队列
  10. jQuery 学习笔记之十六 评分
  11. elementui带输入建议查询_知道Profiler是什么吗?带你了解SQL Server的性能优化工具...
  12. 『号外』 排名进入2000!再创佳绩!
  13. 什么是SIP协议,和Freeswitch什么关系
  14. 百练2815:城堡问题题解 深度优先搜索解法
  15. Word 边框刷使用方法
  16. CodeForces 332B Maximum Absurdity(线段树单点更新)
  17. python27读书笔记0.1
  18. 修复duilib库UISlider控件的4个bug
  19. 用gin进行web开发的基本框架搭建
  20. 绝密!!!!!明星的身份证照片!!!!

热门文章

  1. java亮屏,Java 屏幕背光长亮
  2. 详细解读petalinux的配置
  3. 【装卸臂项目】【MATLAB】液压阀模型——输入开度输出速度
  4. 基于cv2的图片处理之轮廓、截图(一)
  5. java双精度怎么比较?误差怎么办?javaDouble类型怎么比较大小?
  6. Matplotlib折线图线型设置
  7. mac pyenv 报错
  8. 2023 车险计算器微信小程序源码
  9. 0x80004005加载疑难解答时出错怎么办?
  10. 项目启动bug记录:出现报错:Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedd