前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我赵永强又回来了:单散、认证与数签(五上)

我赵永强又回来了:单散、认证与数签(五上)

作者头像
老李秀
发布2019-11-13 15:07:56
4110
发布2019-11-13 15:07:56
举报
文章被收录于专栏:可能是东半球最正规的API社区

各位好,我是永强,首先请你们按捺一下激动心情,然后我要开始了。

作为一个后知后觉的人,我也是昨天看到有人在光天化日之下公开批判我【尥蹶子】【不写公众号】,你们先感受下:

看完这段话后我陷入了深深地思考,在思考了几秒钟后,作为一个浑身上下闪耀着人性光辉的人,我决定对上图中倒数第二句话进行一番友好的回应以及错误纠正:

  • 首先,我一点儿都不忙,我就是懒而已
  • 其次是那玩意不叫工业机器人,确切说是工业视觉寻径AI机器人

同时,我也决定对上图中的正数第二句话进行简单的评述:

懒就是懒,何必甩锅给忙,欺负"忙"不会说话?

我觉得我有必要给新来的朋友先自我介绍一下,首先我的存在确实是为了当老李没空整公众号时候来顶数的,在此之前,我写过的文章在这里,质量真的非常好但是阅读量都贼低,也算是我的一大特色,你们感受下:

在更新完第四篇后,由于我工作繁忙所以一直好长时间没有接着写,所以今天我就打算牺牲一下自己宝贵的周末时间来补充一下今天的内容:单散是单向散列的简称,认证则是消息认证码的简称,数签则是数字签名的简称。这三项内容本身与加密解密可能看起来没有太大关联,而且相对来说也比加解密【xue微】简单不烧脑一些。好了,我要开始了。

单向散列

(后文中将一直使用单散来称呼单向散列)一直以来各路腿子们对单散有着强大且难以更正的误解,那就是一直拿加密来称呼单散,比如在公司干活的时候大佬会经常告诉你【前端把密码传过来,你加个盐用md5加密一下存到数据库里】,是吧... ...不过我也可以理解为习惯性口误,就是实际上人家知道单散并不是加密,但是为了适应大家所以才这么表达。

实际上我们最常见的单散就是md系或sha系,不过,还有其他并不常用的系列,在世界上最好的语言里,我们可以用这么个函数可以一次性列出一大坨单散函数,你们琢磨下:

代码语言:javascript
复制
<?php
$a_hash_method = hash_algos();
print_r( $a_hash_method );
// 然后结果是这样的...
/*
Array
(
    [0] => md2
    [1] => md4
    [2] => md5
    [3] => sha1
    [4] => sha224
    [5] => sha256
    [6] => sha384
    [7] => sha512
    [8] => ripemd128
    [9] => ripemd160
    [10] => ripemd256
    [11] => ripemd320
    [12] => whirlpool
    [13] => tiger128,3
    [14] => tiger160,3
    [15] => tiger192,3
    [16] => tiger128,4
    [17] => tiger160,4
    [18] => tiger192,4
    [19] => snefru
    [20] => snefru256
    [21] => gost
    [22] => gost-crypto
    [23] => adler32
    [24] => crc32
    [25] => crc32b
    [26] => fnv132
    [27] => fnv1a32
    [28] => fnv164
    [29] => fnv1a64
    [30] => joaat
    [31] => haval128,3
    [32] => haval160,3
    [33] => haval192,3
    [34] => haval224,3
    [35] => haval256,3
    [36] => haval128,4
    [37] => haval160,4
    [38] => haval192,4
    [39] => haval224,4
    [40] => haval256,4
    [41] => haval128,5
    [42] => haval160,5
    [43] => haval192,5
    [44] => haval224,5
    [45] => haval256,5
)
 */

前几个还算能看,后面那些纯属只认识字母,假设要用的话应该咋用?

代码语言:javascript
复制
<?php
$s_str = '小毒舌';
echo '直接用md5: '.md5( $s_str ).PHP_EOL;
echo '用hash函数: '.hash( 'md5', $s_str ).PHP_EOL;
echo 'md4: '.hash( 'md4', $s_str ).PHP_EOL;
echo 'sha512: '.hash( 'sha512', $s_str ).PHP_EOL;
echo 'tiger192,4: '.hash( 'tiger192,4', $s_str ).PHP_EOL;

单散的目的是为了将非常大非常大的一大坨(想象一下郭德纲说的谦儿哥家里那个能包住长颈鹿的一大坨松油琥珀)变成一串固定长度的体积相对贼小的数据,而且这个过程是不可逆的,并且这个计算速度还要足够快能够让人忍受,最后最重要的是当原来的【非常大非常大的一大坨】发生任何任何哪怕只有一丁点一丁点儿改变的时候生成的【一串固定长度的体积相对贼小的数据】也必然一定要发生变化(然而实际上会有相同的概率,一旦发生这种情况,专业说法称之为哈希碰撞)...

所以,单散最常用的场景就是用来验证文件、验证数据是否被篡改过。

此处额外说一说大家最常用的一个场景,就是上面大佬告诉你的【前端把密码传过来,你加个盐用md5加密一下存到数据库里】,这里推荐大家使用password_hash函数来代替md5,这里我给大家贴一篇PHP官网的资料,你们自己琢磨下...

https://www.php.net/manual/zh/faq.passwords.php#faq.passwords.fasthash

还有就是,实际上从理论上讲,md4、md5已经不太推荐了,推荐你们用sha系的单散算法。

单散能够向你保证数据的完整性(有人叫一致性),也就说相对于你期待的原本的数据,它是没有被篡改过的。但是,单散无法保证数据是谁发来的...这句话不好理解,我举个最常见的场景:客户端与API飞数据。

一般说来客户端和API都会遵循同一个单散算法,客户端会将飞给API的数据进行单散,然后API收到数据后也会对收到的数据进行同样的单散行为,然后再对比一下双方单散算出来的数值是否相同。但是,如果一个人天天吃饱了撑的(这种行为典型就是老李,我知道他一般要去某个公司面试前就会拿青花瓷给人家产品一顿研究)拿青花瓷对你们的API进行“数据分析”,他就会有可能DIY一个第三方客户端,他这个客户端也能单散出正确的数值和你们的API交互,但是他这个客户端并不是“合法”的客户端...

这就是我说的:单散无法保证数据是你想要的人或物给你发来的...

那么如何保证与你沟通的对方是你想要的那个人或物...

消息认证码

来了!来了!他来了!

泥,是不是也因为数据发送方伪装而头疼?

泥,是不是也为了哈希碰撞而烦恼?

泥,是否由于这些困惑缺陷而夜夜无法入睡!

来了!他来了!!

消息认证码!既能保证数据完整一致性,又能最大程度保证发送方!

泥TM,还在等什么?!赶紧拿起手中电话...哦哦,错了,赶紧操起手中的鼠标,打开看下吧!

https://www.php.net/manual/zh/function.hash-hmac.php

消息认证码的英文全程叫做Message Authenxxxxxx Code,简称MAC,但是TA和Macbook没有半毛钱关系,同时和网卡的Mac地址也没有半毛钱关系...

我们粗暴地去理解消息验证码,这玩意和单散很相似,这个玩意本身也是将【一大坨一大坨松油子】数据转换成相对小很多的【一小坨松油子】,但是,转换的过程中,TA需要一个密钥...听起来就像是:

MAC = 单散+密钥

你们注意我说是【像】,而不是说【是】...

我们还是引入客户端和API飞数据这个典型应用场景,客户端准备好一坨数据,利用密钥123456根据MAC算法计算出一个MAC值;数据飞给API后,API也根据密钥123456根据相同的MAC算法计算出一个MAC值,然后和客户端计算出来的MAC一对比~

那么这个时候,如果有人知道了这个密钥(比如老李),那么他又能冒充客户端了,这个时候的主要矛盾是:客户端和API如何才能通过安全的方式共享这个密钥。很可惜,这不是我们今天讨论的重点,不过我可以提示一些内容大家可以搜索一下:密钥交换...但是,老李之前好像写过相关内容,比如这篇:《周一到五忙着吹牛划水骗工资周六日抓紧时间发个伪高端技术文章》

MAC有很几种不同的具体的实现,比如HMAC就是其中【xue微】常见的一种,HMAC中的H表示Hash的意思,所以HMAC是一种利用单散实现的一种MAC算法,在世界上最好的语言里,相关函数是这样shai儿的,你们琢磨下:

代码语言:javascript
复制
<?php
// 注意此函数需要php>=7.2
$a_hmac_method = hash_hmac_algos();
// 既然是利用单散实现的mac算法,那么先看看支持的单散有哪些...
print_r( $a_hmac_method );
$s_raw_content = "lalalaxiaodushe";
$s_password    = "123456";
$s_hmac = hash_hmac( 'md5', $s_raw_content, $s_password );
echo $s_hmac.PHP_EOL;

上述这坨PHP代码的意思就是,利用md5单散算法结合上密钥123456对内容lalalaxiaodushe进行MAC值计算,当然了计算结果是这样shai儿的:

但是,你结合上述应用常见:客户端和API飞数据,一般都是跨语言的,少年~~~所以,在跨语言以及相同数据条件情况下,计算出来的MAC值应该是一样的。哥们儿活儿全,nodejs演示一把:

代码语言:javascript
复制
const crypto = require('crypto');
// 创建一个hmac对象
const hmac = crypto.createHmac('md5', '123456');
// 往hmac对象中添加摘要内容
const up = hmac.update('lalalaxiaodushe');
// 使用 digest 方法输出摘要内容
const result = up.digest('hex'); 
console.log(result);

运行结果如下,你们琢磨下:

完美~~~(未完待续)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 高性能API社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档