开发网站登录功能时,如何保证密码在传输过程/储存的安全?
相信不少前后端的朋友,在面试时都会被问到类似的问题。
在我对密码学一无所知时,也仅会回答:“MD5
加密啊。”
诸不知,密码学在网络七层模型,甚至web
开发中的应用比我想象得多得多。
密码学是各种安全应用程序所必需的,现代密码学旨在创建通过应用数学原理和计算机科学来保护信息的机制。但相比之下,密码分析旨在解密此类机制,以便获得对信息的非法访问。
密码学具有三个关键属性:
例如个人医疗数据:
在本文中,我们将从加密,哈希,编码和混淆四种密码学基础技术来入门。
本文图片经过再制,方便看懂。
大纲和主体内容引自:How Secure Are Encryption, Hashing, Encoding and Obfuscation?[1]
加密定义:以保证机密性的方式转换数据的过程。
为此,加密需要使用一个保密工具,就密码学而言,我们称其为“密钥”。
加密密钥和任何其他加密密钥应具有一些属性:
加密分为两类:对称和非对称
对称加密:
用途:文件系统加密,Wi-Fi 保护访问(WPA),数据库加密(例如信用卡详细信息)
非对称加密:
用途:TLS
,V**
,SSH
。
其主要区别是:所需的密钥数量:
能被密码界承认的加密算法都是公开的:
哈希算法定义:·一种只能加密,不能解密的密码学算法,可以将任意长度的信息转换成一段固定长度的字符串。
加密算法是可逆的(使用密钥),并且可以提供机密性(某些较新的加密算法也可以提供真实性),而哈希算法是不可逆的,并且可以提供完整性,以证明未修改特定数据。
哈希算法的前提很简单:给定任意长度的输入,输出特定长度的字节。在大多数情况下,此字节序列对于该输入将是唯一的,并且不会给出输入是什么的指示。换一种说法:
为了说明这一点,请想象一个强大的哈希算法通过将每个唯一输入放在其自己的存储桶中而起作用。当我们要检查两个输入是否相同时,我们可以简单地检查它们是否在同一存储桶中。
散列文件的存储单位称为桶(Bucket)
提供文件下载的网站通常会返回每个文件的哈希值,以便用户可以验证其下载副本的完整性。
例如,在Debian
的图像下载服务中,您会找到其他文件,例如SHA256SUMS
,其中包含可供下载的每个文件的哈希输出(在本例中为SHA-256
算法)。
在终端中,可以用openssl
来对文件进行哈希处理:
$ openssl sha256 /Users/hiro/Downloads/非对称.pngSHA256(/Users/hiro/Downloads/非对称.png)= 7c264efc9ea7d0431e7281286949ec4c558205f690c0df601ff98d59fc3f4f64
同一个文件采用相同的hash
算法时,就可以用来校验是否同源。
在强大的哈希算法中,如果有两个不同的输入,则几乎不可能获得相同的输出。
而相反的,如果计算后的结果范围有限,就会存在不同的数据经过计算后得到的值相同,这就是哈希冲突。(两个不同的数据计算后的结果一样)
这种称为:哈希碰撞(哈希冲突)。
如果两个不同的输入最终出现在同一个存储桶中,则会发生冲突。如MD5
和SHA-1
,就会出现这种情况。这是有问题的,因为我们无法区分哪个碰撞的值匹配输入。
强大的哈希算法几乎会为每个唯一输入创建一个新存储桶。
在web
开发中,哈希算法使用最频繁的是在网站登陆应用上:
绝大多数的网站,在将登陆数据存入时,都会将密码哈希后存储。
注册:
登陆:
哈希算法的一个有趣的方面是:无论输入数据的长度如何,散列的输出始终是相同的长度。
从理论上讲,碰撞冲突将始终在可能性的范围之内,尽管可能性很小。
与之相反的是编码。
编码定义:将数据从一种形式转换为另一种形式的过程,与加密无关。
它不保证机密性,完整性和真实性这三种加密属性,因为:
URL
编码
又叫百分号编码,是统一资源定位(URL
)编码方式。URL
地址(常说网址)规定了:
/,:@
等)%xx
编码处理。现在已经成为一种规范了,基本所有程序语言都有这种编码,如:
编码方法很简单,在该字节ascii
码的 16 进制字符前面加%
. 如 空格字符,ascii
码是 32,对应 16 进制是'20',那么urlencode
编码结果是:%20
。
# 源文本:The quick brown fox jumps over the lazy dog
# 编码后:#!shell%54%68%65%20%71%75%69%63%6b%20%62%72%6f%77%6e%20%66%6f%78%20%6a%75%6d%70%73%20%6f%76%65%72%20%74%68%65%20%6c%61%7a%79%20%64%6f%67
HTML实体编码
在HTML
中,需要对数据进行HTML
编码以遵守所需的HTML
字符格式。转义避免 XSS 攻击也是如此。
Base64/32/16
编码
base64
、base32
、base16
可以分别编码转化 8 位字节为 6 位、5 位、4 位。
16,32,64 分别表示用多少个字符来编码,
Base64
常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME
的email,email via MIME
,在XML
中存储复杂数据。
编码原理:
Base64
编码要求把 3 个 8 位字节转化为 4 个 6 位的字节A-Z,a-z,0-9,+,/
这 64 个编码字符,=
号不属于编码字符,而是填充字符Base64
映射表,如下:
举个栗子:
引自:一篇文章彻底弄懂 Base64 编码原理[2]
M
”、“a
”、"n
"对应的ASCII
码值分别为 77,97,110,对应的二进制值是01001101
、01100001
、01101110
。如图第二三行所示,由此组成一个 24 位的二进制字符串。00010011
、00010110
、00000101
、00101110
。分别对应的值(Base64
编码索引)为:19、22、5、46。T、W、F、u
。因此“Man
”Base64
编码之后就变为:TWFu
。上面的示例旨在指出,编码的用例仅是数据处理,而不为编码的数据提供保护。
混淆定义:将人类可读的字符串转换为难以理解的字符串
。
尽管不能保证机密性,但混淆仍有其它应用:
但是,如此存在许多有助于消除应用程序代码混淆的工具。那就是其它话题了。。。
JavaScript
混淆
JavaScript
源代码:
function hello(name) { console.log('Hello, ' + name);}
hello('New user');
混淆后:
var _0xa1cc=["\x48\x65\x6C\x6C\x6F\x2C\x20","\x6C\x6F\x67","\x4E\x65\x77\x20\x75\x73\x65\x72"];function hello(_0x2cc8x2){console[_0xa1cc[1]](_0xa1cc[0]+ _0x2cc8x2 "_0xa1cc[1]")}hello(_0xa1cc[2])
从机密性,完整性,真实性分析四种密码技术:
加密 | 哈希 | 编码 | 混淆 | |
---|---|---|---|---|
机密性 | ✅ | ❌ | ❌ | ❌ |
完整性 | ❓ | ✅ | ❌ | ❌ |
真实性 | ❓ | ❌ | ❌ | ❌ |
HMAC
)和某些传输层安全性(TLS
)方法。
常用的哈希函数:
MD5
,一种被广泛使用的密码杂凑函数,可以产生出一个 128 位元(16 位元组)的哈希值,用于确保信息传输完整一致。*虽广泛,但过时。SHA-256/SHA512
, "加盐"。在比特币中,区块链使用SHA-256
算法作为基础的加密哈希函数。secure hash algorithm
,是一个密码哈希函数家族。SHA
家族有五个算法,分别是SHA-1,SHA-224,SHA-256,SHA-384,SHA-512
SHA-2
bcrypt
算法相对来说是运算比较慢的算法。
salt
和const
这两个值来减缓加密过程,ta 的加密时间(百 ms 级)远远超过md5
(大概1ms
左右)。Bcrypt
的计算速度很慢,但是对于用户来说,这个过程不算慢。bcrypt
是单向的,而且经过salt
和cost
的处理,使其受rainbow
攻击破解的概率大大降低,同时破解的难度也提升不少。MD5
等加密方式更加安全,而且使用也比较简单.PBKDF2
,bcrypt
,scrypt
。
那么,如何保证密码在传输过程/储存的安全呢?
我们下回分解!
如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:
也可以来我的GitHub
博客里拿所有文章的源文件:
前端劝退指南:https://github.com/roger-hiro/BlogFN
[1]
How Secure Are Encryption, Hashing, Encoding and Obfuscation?: https://auth0.com/blog/how-secure-are-encryption-hashing-encoding-and-obfuscation/#What-is-Encoding-
[2]
引自:一篇文章彻底弄懂Base64编码原理: https://blog.csdn.net/wo541075754/article/details/81734770
[3]
How Secure Are Encryption, Hashing, Encoding and Obfuscation?: https://auth0.com/blog/how-secure-are-encryption-hashing-encoding-and-obfuscation/#What-is-Encoding-
[4]
CTF中那些脑洞大开的编码和加密: https://www.cnblogs.com/godoforange/articles/10850493.html
[5]
散列文件的存储——‘桶’: https://blog.csdn.net/Dearye_1/article/details/78492021