密码学系列之:1Password的加密基础PBKDF2
简介
1password是一个非常优秀的密码管理软件,有了它你可以轻松对你的密码进行管理,从而不用再考虑密码泄露的问题,据1password官方介绍,它的底层使用的是PBKDF2算法对密码进行加密。
那么PBKDF2是何方神圣呢?它有什么优点可以让1password得以青睐呢?一起来看看吧。
PBKDF2和PBKDF1
PBKDF的全称是Password-Based Key Derivation Function,简单的说,PBKDF就是一个密码衍生的工具。既然有PBKDF2那么就肯定有PBKDF1,那么他们两个的区别是什么呢?
PBKDF2是PKCS系列的标准之一,具体来说他是PKCS#5的2.0版本,同样被作为RFC 2898发布。它是PBKDF1的替代品,为什么会替代PBKDF1呢?那是因为PBKDF1只能生成160bits长度的key,在计算机性能快速发展的今天,已经不能够满足我们的加密需要了。所以被PBKDF2替换了。
在2017年发布的RFC 8018(PKCS #5 v2.1)中,是建议是用PBKDF2作为密码hashing的标准。
PBKDF2和PBKDF1主要是用来防止密码暴力破解的,所以在设计中加入了对算力的自动调整,从而抵御暴力破解的可能性。
PBKDF2的工作流程
PBKDF2实际上就是将伪散列函数PRF(pseudorandom function)应用到输入的密码、salt中,生成一个散列值,然后将这个散列值作为一个加密key,应用到后续的加密过程中,以此类推,将这个过程重复很多次,从而增加了密码破解的难度,这个过程也被称为是密码加强。
我们看一个标准的PBKDF2工作的流程图:

从图中可以看到,初始的密码跟salt经过PRF的操作生成了一个key,然后这个key作为下一次加密的输入和密码再次经过PRF操作,生成了后续的key,这样重复很多次,生成的key再做异或操作,生成了最终的T,然后把这些最终生成的T合并,生成最终的密码。
根据2000年的建议,一般来说这个遍历次数要达到1000次以上,才算是安全的。当然这个次数也会随着CPU计算能力的加强发生变化。这个次数可以根据安全性的要求自行调整。
有了遍历之后,为什么还需要加上salt呢?加上salt是为了防止对密码进行彩虹表攻击。也就是说攻击者不能预选计算好特定密码的hash值,因为不能提前预测,所以安全性得以提高。标准salt的长度推荐是64bits,美国国家标准与技术研究所推荐的salt长度是128 bits。
详解PBKDF2的key生成流程
上面一小节,我们以一种通俗易懂的方式告诉大家,PBKDF2到底是怎么工作的。一般来说,了解到这一层也就够了,但是如果你想更加深入,了解PBKDF2的key生成的底层原理,那么还请关注这一小节。
我们上面介绍了PBKDF2是一个生成衍生key的函数,作为一个函数,那么就有输入和输出,我们先看下PBKDF2的定义:
DK = PBKDF2(PRF, Password, Salt, c, dkLen)
PBKDF2有5个函数,我们看下各个参数代表什么意思:
- PRF 是一个伪随机散列函数,我们可以根据需要对其进行替换,比如替换成为HMAC函数。
- Password 是主密码用来生成衍生key。
- Salt是一个bits序列,用来对密码加盐。
- c 是循环的次数。
- dkLen 是生成的key要求的bits长度。
- DK是最后生成的衍生key。
在上一节中,我们可以看到其实最后的衍生key是由好几部分组成的,上图中的每一个T都代表着衍生key的一部分,最后将这些T合并起来就得到了最终的衍生key,其公式如下:
DK = T1 + T2 + ⋯ + Tdklen/hlen
Ti = F(Password, Salt, c, i)
上面的F是c次遍历的异或链。其公式如下:
F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
其中:
U1 = PRF(Password, Salt + INT_32_BE(i))
U2 = PRF(Password, U1)
⋮
Uc = PRF(Password, Uc−1)
HMAC密码碰撞
如果PBKDF2的PRF使用的是HMAC的话,那么将会发送一些很有意思的问题。对于HMAC来说,如果密码的长度大于HMAC可以接受的范围,那么该密码会首先被做一次hash运算,然后hash过后的字符串会被作为HMAC的输入。
我们举个例子,如果用户输入的密码是:
Password: plnlrtfpijpuhqylxbgqiiyipieyxvfsavzgxbbcfusqkozwpngsyejqlmjsytrmd
经过一次HMAC-SHA1运算之后,得到:
SHA1 (hex): 65426b585154667542717027635463617226672a
将其转换成为字符串得到:
SHA1 (ASCII): eBkXQTfuBqp'cTcar&g*
所以说,如果使用PBKDF2-HMAC-SHA1的加密方式的话,下面两个密码生成衍生key是一样的。
"plnlrtfpijpuhqylxbgqiiyipieyxvfsavzgxbbcfusqkozwpngsyejqlmjsytrmd"
"eBkXQTfuBqp'cTcar&g*"
PBKDF2的缺点
虽然PBKDF2可以通过调节循环遍历的次数来提高密码破解的难度。但是可以为其研制特殊的处理器,只需要很少的RAM就可以对其进行破解。为此bcrypt 和 scrypt 等依赖于大量RAM的加密算法,这样就导致那些廉价的ASIC处理器无用武之地。
总结
以上就是PBKDF2的简单介绍,想要详细了解更多的朋友,可以参考我的其他关于密码学的文章。
本文已收录于 http://www.flydean.com/41-pbkdf2/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
密码学系列之:1Password的加密基础PBKDF2的更多相关文章
- 密码学系列之:feistel cipher
密码学系列之:feistel cipher 简介 feistel cipher也叫做Luby–Rackoff分组密码,是用来构建分组加密算法的对称结构.它是由德籍密码学家Horst Feistel在I ...
- 密码学系列之:Merkle–Damgård结构和长度延展攻击
密码学系列之:Merkle–Damgård结构和长度延展攻击 简介 Merkle–Damgård结构简称为MD结构,主要用在hash算法中抵御碰撞攻击.这个结构是一些优秀的hash算法,比如MD5,S ...
- 密码学系列之:memory-hard函数
密码学系列之:memory-hard函数 目录 简介 为什么需要MHF Memory hard的评估方法 MHF的种类 MHF的密码学意义 memory-hard在MHF中的应用 简介 Memory ...
- [转] swf文件加密基础
本来打算下班回来就写这个东西,一方面算是对今天学习的一个笔记记录,另外一方面,给一些朋友普及一些swf文件加密基础知识.之所以说是基础,那是因为我也是刚学习了一点,灰常的基础.不过晚上看了一会我是传奇 ...
- 老王教您怎么做cass7.1 8.0 9.1所有系列的复制狗 加密狗 破解狗
cass7.1 8.0 9.1所有系列的复制狗 加密狗 破解狗本来是出于好奇看到网上有这样的东西,学了下感觉挺简单的,如果你是cass的初学者想仅仅是想学习这个软件,不想花大价格购买正版的,这个是可以 ...
- 【Xamarin开发 Android 系列 7】 Android 结构基础(下)
原文:[Xamarin开发 Android 系列 7] Android 结构基础(下) *******前期我们不打算进行太深入的东西,省的吓跑刚进门的,感觉门槛高,so,我们一开始就是跑马灯一样,向前 ...
- 【Xamarin开发 Android 系列 6】 Android 结构基础(上)
原文:[Xamarin开发 Android 系列 6] Android 结构基础(上) 前面大家已经熟悉了什么是Android,而且在 [Xamarin开发 Android 系列 4] Android ...
- thinkphp整合系列之支付宝RSA加密方式
thinkphp整合系列之支付宝RSA加密方式上篇博客写的是MD5加密方式:thinkphp整合系列之支付宝MD5加密方式扫码支付http://baijunyao.com/article/75 但是呢 ...
- C#多线程编程系列(二)- 线程基础
目录 C#多线程编程系列(二)- 线程基础 1.1 简介 1.2 创建线程 1.3 暂停线程 1.4 线程等待 1.5 终止线程 1.6 检测线程状态 1.7 线程优先级 1.8 前台线程和后台线程 ...
随机推荐
- taro小程序展示富文本
在微信小程序下会用到wxParse这个东西来达到html转换wxml的效果, taro小程序官方也给出了示例,地址 这里封装成自己的组件: import Taro, { Component } fro ...
- C# Unity容器的使用
最简单的使用方式(记得安装Unity NuGet包呀) Console.WriteLine("***************Unity容器的初步应用***************" ...
- 异步编程async体会
namespace 异步编程{ class Program { static void Main(string[] args) { Console.WriteLine("mian this ...
- IDEA快捷键命令
Ctrl+Alt+T IDEl 抛异常快捷键ctrl +o 继承类时 继承方法快捷键Ctrl+Alt+左右方向键 回到上次光标停留的地方ALt +left/right 快速切换两个页面ctr ...
- ES6对象扩展——扩展运算符
1.复制对象:使用扩展运算符复制对象时是浅拷贝 //复制对象:使用扩展运算符复制对象时是浅拷贝 const obj1 = { a:1, b:2, d:{ aa:1, bb:2 } } const ob ...
- Mysql时间戳转Java时间戳
MySQL 时间戳和Java返回的时间戳是不一样的 例如: 当前时间是 2014-08-04 10:42:55.204000 使用mysql时间戳函数UNIX_TIMESTAMP 返回的结果为: 14 ...
- uni-app 小程序从零开始的开发流程
前言 本文基于 HBuilderX 3.1.22 + 微信开发者工具 1.05.2106300为主要内容进行说明. 文档版本:1.0.0 更新时间:2021-09-03 15:32 一.准备 uni- ...
- Shell脚本基础及基本常用命令
1.概述 脚本语言(shell.python):解释性语言,用解释器解释 运行效率低 | c.java:描述性语言,运行效率高 以.sh结尾会有高亮显示 执行: sh hello.sh 或者 chmo ...
- RHCS+Nginx及Fence机制实现高可用集群
RHCS(Red Hat Cluster Suite,红帽集群套件)是Red Hat公司开发整合的一套综合集群软件组件,提供了集群系统中三种集群构架,分别是高可用性集群.负载均衡集群.存储集群,可以通 ...
- Kubernetes-Pod介绍(-)
前言 本篇是Kubernetes第四篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战.从现在开始都是重要的核心概念,此篇偏一些Pod的概念介绍,后续每篇都会有实战. Kubernetes系列 ...