前言在开发网站登录功能时,如何保证密码在传输/存储过程中的安全性?相信很多前后端朋友在面试的时候都会被问到类似的问题。当我对密码学一窍不通时,只会回答:“MD5加密”。你不知道,密码学在七层网络模型乃至web开发中的应用远比我想象的多。1.什么是密码学?密码学是各种安全应用所必需的,现代密码学旨在通过应用数学原理和计算机科学来创建保护信息的机制。但相比之下,密码分析旨在破译此类机制以获得对信息的非法访问。密码学具有三个关键属性:机密性,防止未经授权的各方访问信息(换句话说,确保只有授权人员才能访问受限数据)。完整性,是指保护信息不被随意篡改。真实性,与识别信息所有者有关。例如个人医疗数据:机密性,个人医疗数据需要保密,这意味着只有医生或医护人员才能访问它。还必须保护完整性,因为篡改此类数据可能会导致错误的诊断或治疗并对患者造成健康风险。真实性,患者数据应链接到已识别的个人,患者需要知道操作员(医生)是谁。在本文中,我们将从密码学的四种基本技术开始:加密、散列、编码和混淆。2.什么是加密?加密定义:以确保机密性的方式转换数据的过程。为此,加密需要使用秘密工具,在密码学中我们称之为“密钥”。加密密钥和任何其他加密密钥都应该具有一些属性:为了保密,密钥的值应该难以猜测。它应该在单个上下文中使用,并避免在不同的上下文中重复使用(类似于JS范围)。密钥重用会带来安全风险,如果因为它“解锁”更敏感的数据而规避其机密性,则更是如此。2.1加密的分类:对称加密和非对称加密分为两类:对称加密和非对称对称加密:用途:文件系统加密,Wi-Fi保护访问(WPA),数据库加密(例如信用卡详细信息)非对称加密:用途:TLS、VPN、SSH。主要区别是:所需的密钥数量:在对称加密算法中,单个密钥用于加密和解密数据。只有那些有权访问数据的人才有一个共享的秘密。在非对称加密算法中,使用了两个密钥:公钥和私钥。顾名思义,私钥必须保密,而公钥是每个人都可以知道的。应用加密时,使用公钥,而解密需要私钥。任何人都应该能够向我们发送加密数据,但只有我们能够解密和读取它。当通过不安全的通道进行通信时,通常使用非对称加密,在两方之间安全地建立公钥。有了这个共享密钥,双方就切换到对称加密。这种加密速度更快,更适合处理大量数据。密码学界认可的加密算法是公开的:一些公司使用“专有”的专有或“军用级”加密技术。并且基于“复杂”算法,但这不是加密的工作原理。密码学界广泛使用和认可的所有加密算法都是公开的,因为它们基于只能通过拥有密钥或高级计算能力才能解决的数学算法。公共算法被广泛采用,证明了它们的价值。3、什么是散列?哈希算法的定义:·一种只能加密不能解密的密码算法。它可以将任意长度的信息转换成固定长度的字符串。加密算法是可逆的(使用密钥)并且可以提供机密性(一些较新的加密算法也可以提供真实性),而哈希算法是不可逆的并且可以提供完整性,证明特定数据。哈希算法的前提很简单:给定任意长度的输入,输出特定长度的字节。在大多数情况下,这个字节序列对于那个输入是唯一的,并且不会给出输入是什么的指示。换句话说:不能仅从散列算法的输出确定原始数据。通过获取一些任意数据并使用哈希算法的输出,可以验证此数据是否与原始输入数据匹配,而无需查看原始数据。为了说明这一点,想象一个强大的哈希算法,它通过将每个唯一的输入放入它自己的桶中来工作。当我们想检查两个输入是否相同时,我们可以简单地检查它们是否在同一个桶中。哈希文件的存储单元称为桶(Bucket)3.1示例1:资源下载提供文件下载的网站通常会返回每个文件的哈希值,以便用户验证其下载副本的完整性。例如,在Debian的图像下载服务中,您会找到其他文件,例如SHA256SUMS,其中包含每个可供下载的文件的哈希输出(在本例中为SHA-256算法)。下载文件后,可以将其传递给选定的哈希算法以输出哈希值。使用此哈希值与校验和文件中列出的哈希值进行匹配,以验证其是否一致。在终端中,可以使用openssl对文件进行哈希处理:$opensslsha256/Users/hiro/Downloads/asymmetric.pngSHA256(/Users/hiro/Downloads/asymmetric.png)=7c264efc9ea7d0431e7281286949ec4c558205f690c0df601ff98d59fc3f4f64,是否可以使用相同的算法来检查相同的文件起源。在强哈希算法中,如果你有两个不同的输入,几乎不可能得到相同的输出。反之,如果计算结果的范围有限,不同的数据计算后会出现相同的值,这就是哈希冲突。(两个不同的数据计算的结果是一样的)这叫做:散列碰撞(hashcollision)。如果两个不同的输入最终进入同一个桶,就会发生冲突。MD5和SHA-1就是这种情况。这是有问题的,因为我们无法判断哪个碰撞值与输入匹配。一个强大的散列算法几乎会为每个独特的输入创建一个新的桶。3.2示例2:网站登录在Web开发中,哈希算法在网站登录应用中的使用频率最高:大多数网站在存储登录数据时,会存储经过哈希处理后的密码。这是为了防止其他人在窃取数据库信息后恢复您的初始输入。下次登录时,Web应用程序将再次对您的密码进行哈希处理,并将此哈希值与之前存储的哈希值进行比较。如果哈希匹配,即使没有实际密码存储在Web应用程序中,Web应用程序也确信您知道密码。注册:登录:散列算法的一个有趣的方面是:不管输入数据的长度如何,散列的输出总是相同的长度。从理论上讲,碰撞冲突总是在可能性范围内,尽管可能性很小。与之相反的是编码。4.什么是编码?编码定义:将数据从一种形式转换为另一种形式的过程,与加密无关。它不保证机密性、完整性和真实性这三个密码学特性,因为:不涉及任何秘密,并且是完全可逆的。通常输出与输入值成比例的数据量,并且始终是该输入的唯一值。编码方法被认为是公开的,通常用于数据处理。编码永远不适合与操作安全相关。4.1URL编码,也称为百分比编码,是一种统一资源定位符(URL)编码方法。URL地址(通常简称URL)规定:常用的数字和字母可以直接使用,另外一批特殊用户字符也可以直接使用(/、:@等),其他所有字符必须通过%xx编码。现在已经成为一种规范,基本上所有的编程语言都有这种编码,比如:js:encodeURI,encodeURIComponentPHP:urlencode,urldecode等编码方式很简单,在16进制字符前加%字节的ascii码。比如一个空格字符,ascii码是32,对应的十六进制是'20',那么urlencode编码结果就是:%20。#源文:Thequickbrownfoxjumpsoverthelazydog#编码后:#!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%674.2HTML实体编码在HTML中,数据需要进行HTML编码以符合所需的HTML字符格式。转义以避免XSS攻击也是如此。4.3Base64/32/16编码base64、base32、base16可以将8位字节分别编码转换为6位、5位、4位。16、32、64表示用多少个字符来编码,在通常处理文本数据的场合,常用Base64来表示、传输、存储一些二进制数据。包含MIME的电子邮件,通过MIME发送的电子邮件,以XML格式存储复杂的数据。编码原理:Base64编码需要将3个8位字节转换成4个6位字节,然后在6位前面加两个0,组成8位1字节。6位二进制所能表示的最大值数是2的6次方是64,所以是64个字符A-Z、a-z、0-9、+、/这64个编码字符,=号是不是编码字符,而是填充字符Base64映射表,如下:举个栗子:第一步:“M”、“a”、“n”对应的ASCII码值分别为77、97、110分别对应的二进制值为01001101、01100001、01101110。如图中第二行和第三行所示,这样就形成了一个24位的二进制串。第二步:如红框所示,将24位分成四组,每组6位二进制位。第三步:在上面每组前面加两个0展开成32位二进制数,现在变成四个字节:00010011、00010110、00000101、00101110。对应的值(Base64编码索引)分别是:19、22、5、46.第四步:用上面的值在Base64编码表中查找,对应:T,W,F,u。所以“Man”经过Base64编码后就变成了:TWFu。上面的示例旨在指出编码的用例仅是数据处理,而不是为编码数据提供保护。4.什么是混淆?混淆定义:将人类可读的字符串转换为难以理解的字符串。与加密相反,混淆不涉及加密密钥。与编码一样,混淆并不能保证任何安全性,尽管它有时被错误地用作加密方法。虽然它不能保证机密性,但混淆还有其他应用:它用于防止篡改和保护知识产权。APP源代码通常在打包前进行混淆,因为源代码驻留在用户的设备中,可以从中提取代码。由于混淆代码不友好,它可以防止逆向工程,从而有助于保护知识产权。反过来,这可以防止代码被篡改和重新分发以供恶意使用。但是,有许多工具可以帮助对应用程序代码进行去混淆处理。那是另一个话题。..4.1示例一:JavaScript混淆JavaScript源码:functionhello(name){console.log('Hello,'+name);}hello('Newuser');混淆后:var_0xa1cc=["\x48\x65\x6C\x6C\x6F\x2C\x20","\x6C\x6F\x67","\x4E\x65\x77\x20\x75\x73\x65\x72"];functionhello(_0x2cc8x2){console[_0xa1cc[1]](_0xa1cc[0]+_0x2cc8x2"_0xa1cc[1]")}hello(_0xa1cc[2])从机密性、完整性和真实性的角度总结了四种密码技术:加密,虽然是为了保证数据的机密性,但某些现代加密算法还采用其他策略来保证数据的完整性(有时通过嵌入式哈希算法)和真实性。哈希只能保证完整性,但可以通过完整性比较来进行权限控制,例如:基于哈希的消息认证码(HMAC)和某些传输层安全(TLS)方法。Encoding,过去是加密的意思,在技术世界之外仍然有这个意思,但在编程世界中,它只是一种数据处理机制,从未提供任何安全措施。混淆,可用于增加对攻击的抵抗力;但是,它永远不能保证数据的机密性。狡猾的对手最终会绕过混淆策略。与编码一样,混淆永远不应被视为可靠的安全控制。附录:HashFunctions常用的哈希函数:MD5是一种广泛使用的密码学哈希函数,可以生成128位(16字节)的哈希值,保证信息传输的完整性和一致性。*虽然广泛,但已经过时。SHA-256/SHA512,“加盐”。在比特币中,区块链使用SHA-256算法作为底层加密哈希函数。安全散列算法是一系列加密散列函数。SHA家族中有五种算法,分别是SHA-1、SHA-224、SHA-256、SHA-384和SHA-512。它们是美国政府标准,后四种称为SHA-2bcrypt:bcrypt算法是相对来说是一种比较慢的算法。密码学界有一句俗语:算法越慢,越安全。算法计算的越多,黑客的破解成本就越高:加密过程被salt和const这两个值减慢,ta(100ms级别)的加密时间远超md5(1ms左右)。对于计算机来说,Bcrypt的计算速度很慢,但是对于用户来说,这个过程并不慢。bcrypt是单向的,经过salt和cost处理后,被rainbow攻击破解的概率大大降低,破解难度也增加不少。与MD5等加密方式相比,更安全、更易用。精心设计的密钥扩展算法,例如PBKDF2、bcrypt和scrypt。后记和引用加密、散列、编码和混淆有多安全?[3]CTF中的加密与加密[4]哈希文件的存储-'bucket'[5]那么,如何保证密码在传输过程/存储过程中的安全性呢?参考加密、散列、编码和混淆的安全性如何?彻底理解Base64编码原理的文章:https://blog.csdn.net/wo541075754/article/details/81734770HowSecureAreEncryption,Hashing,EncodingandObfuscation?:https://auth0.com/blog/how-secure-are-encryption-hashing-encoding-and-obfuscation/#What-is-Encoding-CTF编码加密:https://www.cnblogs.com/godoforange/articles/10850493.htmlhash文件的存储-'bucket':https://blog.csdn.net/Dearye_1/article/details/78492021
