ChatGPT解决这个技术问题 Extra ChatGPT

哈希算法和加密算法之间的根本区别

我看到哈希和加密算法之间存在很多混淆,我想听听更多关于以下方面的专家建议:

何时使用散列与加密什么使散列或加密算法不同(从理论/数学层面),即是什么使散列不可逆(没有彩虹树的帮助)

这里有一些类似的 SO Questions 并没有像我想要的那样详细:

What is the difference between Obfuscation, Hashing, and Encryption?
Difference between encryption and hashing

我可以预见这是人们在混淆这些术语时要参考的问题。 :)
散列是一种方式(无法还原),加密是两种方式(可以解密)
散列对于索引大型结构和对象(例如文件)也很有用。请参阅hash table
哈希就像绞肉机。你可以把一头牛变成汉堡包,但反过来不行。
我注意到我的问题已被编辑。我一直都知道两者之间的顶级差异,但对低级/数学差异更加好奇。 :) 无论哪种方式,SO 都有很多好的内容!非常感谢!

Z
Ziezi

好吧,您可以在 Wikipedia 中查找它...但是既然您需要解释,我会在这里尽力而为:

哈希函数

它们提供了任意长度输入和(通常)固定长度(或更小长度)输出之间的映射。它可以是任何东西,从简单的 crc32 到完整的加密哈希函数,例如 MD5 或 SHA1/2/256/512。关键是正在进行单向映射。它总是一个多:1 映射(意味着总会有冲突),因为每个函数产生的输出都比它能够输入的要小(如果你将每个可能的 1mb 文件输入 MD5,你会得到大量的冲突)。

它们很难(或实际上不可能)逆转的原因是它们内部的工作方式。大多数加密哈希函数会多次迭代输入集以产生输出。因此,如果我们查看每个固定长度的输入块(取决于算法),散列函数将称其为当前状态。然后它将遍历状态并将其更改为新状态并将其用作自身的反馈(MD5 对每个 512 位数据块执行 64 次此操作)。然后它以某种方式将所有这些迭代的结果状态组合在一起,形成最终的哈希值。

现在,如果您想解码散列,您首先需要弄清楚如何将给定的散列拆分为其迭代状态(输入小于数据块大小的一种可能性,许多用于较大的输入)。然后你需要反转每个状态的迭代。现在,为了解释为什么这非常困难,想象一下尝试从以下公式推导出 ab10 = a + bab 有 10 种有效的组合。现在循环了很多次:tmp = a + b; a = b; b = tmp。对于 64 次迭代,您将有超过 10^64 次尝试的可能性。这只是一个简单的添加,在迭代中保留了一些状态。真正的散列函数做的操作远不止 1 次(MD5 对 4 个状态变量做了大约 15 次操作)。而且由于下一次迭代取决于前一次的状态,并且前一次在创建当前状态时被破坏,因此几乎不可能确定导致给定输出状态的输入状态(对于每次迭代来说不少于)。结合这些,再加上涉及的大量可能性,即使是 MD5 解码也将占用近乎无限(但不是无限)的资源量。如此多的资源,如果您知道输入的大小(对于较小的输入),那么暴力破解哈希实际上比尝试解码哈希要便宜得多。

加密函数

它们在任意长度的输入和输出之间提供 1:1 映射。而且它们总是可逆的。需要注意的重要一点是,使用某种方法它是可逆的。对于给定的键,它始终是 1:1。现在,有多个输入:密钥对可能生成相同的输出(实际上通常有,取决于加密函数)。良好的加密数据与随机噪声无法区分。这与始终具有一致格式的良好哈希输出不同。

用例

当您想要比较一个值但不能存储普通表示时(出于多种原因),请使用哈希函数。密码应该非常适合这个用例,因为出于安全原因(也不应该),您不想将它们存储为纯文本。但是,如果您想检查文件系统中的盗版音乐文件怎么办?每个音乐文件存储 3 mb 是不切实际的。因此,取而代之的是,获取文件的哈希值并存储它(md5 将存储 16 个字节而不是 3mb)。这样,您只需对每个文件进行哈希处理并与存储的哈希数据库进行比较(由于重新编码、更改文件头等,这在实践中效果不佳,但这是一个示例用例)。

在检查输入数据的有效性时使用散列函数。这就是它们的设计目的。如果您有 2 条输入,并且想检查它们是否相同,请通过哈希函数运行它们。对于小输入大小(假设散列函数良好),碰撞的概率非常低。这就是为什么建议使用密码。对于最多 32 个字符的密码,md5 有 4 倍的输出空间。 SHA1 有 6 倍的输出空间(大约)。 SHA512 的输出空间大约是 16 倍。您并不真正关心密码是什么,您关心的是它是否与存储的密码相同。这就是为什么你应该使用哈希作为密码。

每当您需要取回输入数据时,请使用加密。注意需要这个词。如果您要存储信用卡号码,则需要在某个时候将它们取回,但不希望以纯文本形式存储它们。因此,请存储加密版本并尽可能安全地保存密钥。

散列函数也非常适合签署数据。例如,如果您使用 HMAC,您可以通过将数据与已知但未传输的值(秘密值)连接起来的哈希值来签署数据。因此,您发送纯文本和 HMAC 哈希。然后,接收方简单地用已知值对提交的数据进行哈希处理,并检查它是否与传输的 HMAC 匹配。如果相同,您就知道它没有被没有秘密值的一方篡改。这通常用于 HTTP 框架的安全 cookie 系统,以及通过 HTTP 进行数据的消息传输,在这种情况下您需要确保数据的完整性。

关于密码哈希的注释:

加密哈希函数的一个关键特性是它们应该非常快速地创建,并且非常难以/缓慢地反转(以至于几乎不可能)。这带来了密码问题。如果您存储 sha512(password),您就没有做任何事情来防范彩虹表或暴力攻击。请记住,哈希函数是为速度而设计的。因此,攻击者只需通过哈希函数运行字典并测试每个结果是微不足道的。

添加盐会有所帮助,因为它会在哈希中添加一些未知数据。因此,他们不需要找到任何与 md5(foo) 匹配的东西,而是需要找到添加到已知盐中会产生 md5(foo.salt) 的东西(这很难做到)。但它仍然不能解决速度问题,因为如果他们知道盐,这只是运行字典的问题。

因此,有一些方法可以解决这个问题。一种流行的方法称为 key strengthening(或键拉伸)。基本上,您会多次迭代哈希(通常是数千次)。这有两件事。首先,它显着减慢了散列算法的运行时间。其次,如果实施得当(在每次迭代中将输入和盐传回)实际上会增加输出的熵(可用空间),从而减少冲突的机会。一个简单的实现是:

var hash = password + salt;
for (var i = 0; i < 5000; i++) {
    hash = sha512(hash + password + salt);
}

还有其他更标准的实现,例如 PBKDF2BCrypt。但这种技术被相当多的安全相关系统(如 PGP、WPA、Apache 和 OpenSSL)使用。

最重要的是,hash(password) 还不够好。 hash(password + salt) 更好,但还不够好...使用拉伸散列机制生成密码散列...

关于琐碎拉伸的另一个注意事项

在任何情况下都不要将一个哈希的输出直接反馈回哈希函数:

hash = sha512(password + salt); 
for (i = 0; i < 1000; i++) {
    hash = sha512(hash); // <-- Do NOT do this!
}

其原因与碰撞有关。请记住,所有散列函数都会发生冲突,因为可能的输出空间(可能输出的数量)小于输入空间。要了解原因,让我们看看会发生什么。作为前言,我们假设 sha1() 发生碰撞的可能性为 0.001%(实际上它要低得多,但出于演示目的)。

hash1 = sha1(password + salt);

现在,hash1 的碰撞概率为 0.001%。但是当我们执行下一个 hash2 = sha1(hash1); 时,hash1 的所有冲突都会自动变为 hash2 的冲突。所以现在,我们将 hash1 的比率设为 0.001%,第二个 sha1() 调用增加了这一点。所以现在,hash2 的碰撞概率为 0.002%。那是两倍的机会!每次迭代都会给结果增加另一个 0.001% 的碰撞机会。因此,经过 1000 次迭代,碰撞的几率从微不足道的 0.001% 跃升至 1%。现在,退化是线性的,真实概率小,但效果是一样的(估计与 md5 发生单次碰撞的几率约为 1/(2128) 或 1/(3x1038)。虽然看起来很小,但多亏了 the birthday attack,它并没有看起来那么小)。

相反,通过每次重新附加盐和密码,您将数据重新引入哈希函数。因此,任何特定回合的任何碰撞都不再是下一轮的碰撞。所以:

hash = sha512(password + salt);
for (i = 0; i < 1000; i++) {
    hash = sha512(hash + password + salt);
}

与原生 sha512 函数具有相同的碰撞机会。这就是你想要的。改用那个。


太糟糕了,LinkedIn 的程序员在将密码存储为无盐 SHA1 哈希值之前没有阅读此内容...money.cnn.com/2012/06/06/technology/linkedin-password-hack/…
@Pacerier:它也强调了散列。它详细介绍了密码哈希...
如果可以有多个键导致相同的输出,我不明白它如何是 1 对 1 映射。对于 DES,密钥长度为 56 位,块大小为 64 位。因此,不是有 256 个不同的键可以映射到同一个输出块吗?
@Renren29 是的。你是对的。在实践中,整个密码既不是满射也不是单射。但是,对于给定的密钥,它是全射的(每个纯文本都有一个密文),但不一定是单射的(不是每个可能的密文都有一个映射回)。这就是为什么我说给定密钥始终是 1:1。如果没有多个密钥可以输出到同一个输出块,那么密码就没有用,因为密文会告诉你一些关于密钥的信息(不知道它)。
很好的答案。我唯一的挑剔是琐碎拉伸的退化不能是线性的,否则最终会超过 100%。我认为在您使用 0.001% 的示例中,第二步应该是 0.001 + (1 - 0.001) * .001,或 0.001999。
M
Marc B

散列函数可以被认为与烘烤一条面包相同。您从输入(面粉、水、酵母等)开始,在应用散列函数(混合 + 烘焙)后,最终得到输出:一条面包。

走另一条路是非常困难的——你不能真正把面包分成面粉、水、酵母——其中一些在烘焙过程中丢失了,你永远无法准确地知道用了多少水、面粉或酵母一个特定的面包,因为该信息已被散列函数(又名烤箱)破坏。

理论上,许多不同的输入变体会产生相同的面包(例如,2 杯水和 1 茶匙酵母产生的面包与 2.1 杯水和 0.9 茶匙酵母完全相同),但给定其中一个面包,你无法分辨究竟是什么输入组合产生了它。

另一方面,加密可以被视为保险箱。无论你放在那里的东西都会回来,只要你拥有一开始就用来锁住它的钥匙。这是一个对称操作。给定一个键和一些输入,你会得到一个特定的输出。鉴于该输出和相同的键,您将获得原始输入。这是一个 1:1 的映射。


除了你不能轻易地证明一个特定的汉堡包完全来自特定的牛,这是哈希的基本属性,所以这是一个有趣的想法,但却是一个可怕的类比。
@caf 哈哈,确实是经典。然而,奶牛几乎没有进入市场,它是“公牛”;-) 奶牛:牛奶。牛:肉。
E
Eric J.

当您不想取回原始输入时使用散列,当您这样做时使用加密。

哈希接受一些输入并将其转换为一些位(通常被认为是一个数字,如 32 位整数、64 位整数等)。相同的输入将始终产生相同的哈希,但您在此过程中主要丢失信息,因此您无法可靠地重现原始输入(但是有一些警告)。

加密主要保留您输入加密功能的所有信息,只是让任何人都很难(理想情况下不可能)在不拥有特定密钥的情况下反转回原始输入。

散列的简单示例

这是一个简单的示例,可帮助您理解为什么散列不能(在一般情况下)取回原始输入。假设我正在创建一个 1 位哈希。我的哈希函数将一个位字符串作为输入,如果输入字符串中设置了偶数位,则将哈希设置为 1,否则如果有奇数则设置为 0。

例子:

Input    Hash
0010     0
0011     1
0110     1
1000     0

请注意,有许多输入值导致哈希为 0,而许多输入值导致哈希为 1。如果您知道哈希为 0,则无法确定原始输入是什么。

顺便说一句,这个 1 位哈希并不是人为设计的……看看 parity bit

加密的简单示例

您可以使用简单的字母替换来加密文本,例如如果输入是 A,则写 B。如果输入是 B,则写 C。一直到字母表的末尾,如果输入是 Z,则再写A。

Input   Encrypted
CAT     DBU
ZOO     APP

就像简单的哈希示例一样,这种类型的加密具有 been used historically


值得注意的是,“加密”通俗地指强加密,不应与上面示例中的凯撒密码等弱加密相混淆。
@Fax 是的,但是构成强加密的东西一直是一个移动的酒吧。德国二战谜机几乎是不可能破解的(有一部很棒的电影)。今天,您的智能手表可以轻松破解它。 DES 曾经被认为是强大的,MD5 也是如此。今天的强加密有可能在可预见的未来很容易成为量子计算技术的牺牲品。
当然,检查提供密码学建议的帖子和文章的日期总是一个好主意。话虽如此,我很确定凯撒密码即使在 2011 年也被认为是弱密码。
在这些答案中看到一些非常好的例子(奇偶校验、模数、CRC)。散列经常用于分区和平衡方案,例如队列,这经常被遗忘。
m
mrsrinivas

散列和加密/解密技术的基本概述是。

散列:

如果您再次散列任何纯文本,则无法从散列文本中获得相同的纯文本。简而言之,这是一个单向过程。

加密和解密:

如果您再次使用密钥加密任何纯文本,您可以通过使用相同(对称)/不同(不对称)密钥对加密文本进行解密来获得相同的纯文本。

更新:解决已编辑问题中提到的要点。

1. 何时使用散列与加密 如果您想向某人发送文件,散列是很有用的。但是您担心其他人可能会截获该文件并对其进行更改。因此,收件人可以确保它是正确文件的一种方法是公开发布哈希值。这样,接收者可以计算接收到的文件的哈希值并检查它是否与哈希值匹配。如果您说有消息要发送给某人,则加密很好。您使用密钥加密消息,而收件人使用相同(甚至可能不同)的密钥解密以取回原始消息。学分

2. 是什么使散列或加密算法不同(从理论/数学层面),即是什么使散列不可逆(没有彩虹树的帮助)

基本上散列是一种丢失信息但不加密的操作。让我们看一下简单的数学方式的区别,以便我们理解,当然两者都有更复杂的数学运算,其中涉及重复 加密/解密(可逆): 加法:4 + 3 = 7 这可以通过求和来反转并减去一个加数 7 - 3 = 4 乘法:4 * 5 = 20 这可以通过乘积除以因子之一 20 / 4 = 5 来反转所以,在这里我们可以假设一个加数/因子是解密密钥,result(7,20) 是加密文本。散列(不可逆):模除法:22 % 7 = 1 这不能反转,因为您无法对商和被除数执行任何操作来重构除数(反之亦然)。你能找到一个操作来填写'?是? 1 ? 7 = 22 1 ? 22 = 7 因此散列函数具有与模除法相同的数学质量并且会丢失信息。

学分


非常简单易懂的例子..我很感激你分享这个
S
Shiv Mohan

我的两个班轮......一般面试官想要以下答案。

散列是一种方法。您不能从哈希码转换您的数据/字符串。

加密是 2 种方式 - 如果您有密钥,您可以再次解密加密的字符串。


嘿!那是两条线。
不错的收获....刚刚编辑了答案... :) 谢谢队友
J
Julian

哈希函数将可变大小的文本转换为固定大小的文本。

https://i.stack.imgur.com/IUNeO.jpg

来源:https://en.wikipedia.org/wiki/Hash_function

PHP中的哈希函数

哈希将字符串转换为哈希字符串。见下文。

哈希:

$str = 'My age is 29';
$hash = hash('sha1', $str);
echo $hash; // OUTPUT: 4d675d9fbefc74a38c89e005f9d776c75d92623e

密码通常以哈希表示形式存储,而不是作为可读文本存储。当最终用户想要访问受密码保护的应用程序时,必须在身份验证期间提供密码。当用户提交他的密码时,有效的身份验证系统会收到密码并散列这个给定的密码。将此密码哈希与系统已知的哈希进行比较。在平等的情况下授予访问权限。

去哈希:

SHA1 是一种单向哈希。这意味着您不能对哈希进行去哈希处理。

但是,您可以暴力破解哈希。请参阅:https://hashkiller.co.uk/sha1-decrypter.aspx

MD5,是另一个哈希。可以在此网站上找到 MD5 去哈希器:https://www.md5online.org/

为了阻止对哈希的暴力攻击,可以给出盐。在 php 中,您可以使用 password_hash() 创建密码哈希。函数 password_hash() 自动创建盐。要在密码散列(使用盐)上验证密码,请使用 password_verify()

// Invoke this little script 3 times, and it will give you everytime a new hash
$password = '1234';  
$hash = password_hash($password, PASSWORD_DEFAULT);  

echo $hash; 
// OUTPUT 

$2y$10$ADxKiJW/Jn2DZNwpigWZ1ePwQ4il7V0ZB4iPeKj11n.iaDtLrC8bu 

$2y$10$H8jRnHDOMsHFMEZdT4Mk4uI4DCW7/YRKjfdcmV3MiA/WdzEvou71u 

$2y$10$qhyfIT25jpR63vCGvRbEoewACQZXQJ5glttlb01DmR4ota4L25jaW

一个密码可以由一个以上的哈希表示。当您使用 password_verify() 验证具有不同密码哈希的密码时,该密码将被接受为有效密码。

$password = '1234';  

$hash = '$2y$10$ADxKiJW/Jn2DZNwpigWZ1ePwQ4il7V0ZB4iPeKj11n.iaDtLrC8bu';  
var_dump( password_verify($password, $hash) );  

$hash = '$2y$10$H8jRnHDOMsHFMEZdT4Mk4uI4DCW7/YRKjfdcmV3MiA/WdzEvou71u';  
var_dump( password_verify($password, $hash) );  

$hash = '$2y$10$qhyfIT25jpR63vCGvRbEoewACQZXQJ5glttlb01DmR4ota4L25jaW';  
var_dump( password_verify($password, $hash) );

// OUTPUT 

boolean true 

boolean true 

boolean true

https://i.stack.imgur.com/aQkNY.png

来源:https://en.wikipedia.org/wiki/Encryption

PHP中的加密

让我们深入研究一些处理加密的 PHP 代码。

--- Mcrypt 扩展 ---

加密:

$cipher = MCRYPT_RIJNDAEL_128;
$key = 'A_KEY';
$data = 'My age is 29';
$mode = MCRYPT_MODE_ECB;

$encryptedData = mcrypt_encrypt($cipher, $key , $data , $mode);
var_dump($encryptedData);

//OUTPUT:
string '„Ùòyªq³¿ì¼üÀpå' (length=16)

解密:

$decryptedData = mcrypt_decrypt($cipher, $key , $encryptedData, $mode);
$decryptedData = rtrim($decryptedData, "\0\4"); // Remove the nulls and EOTs at the END
var_dump($decryptedData);

//OUTPUT:
string 'My age is 29' (length=12)

--- OpenSSL 扩展 ---

Mcrypt 扩展在 7.1 中已弃用。并在 php 7.2 中删除。 OpenSSL 扩展应在 php 7 中使用。请参见下面的代码片段:

$key = 'A_KEY';
$data = 'My age is 29';

// ENCRYPT
$encryptedData = openssl_encrypt($data , 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($encryptedData);

// DECRYPT    
$decryptedData = openssl_decrypt($encryptedData, 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($decryptedData);

//OUTPUT
string '4RJ8+18YkEd7Xk+tAMLz5Q==' (length=24)
string 'My age is 29' (length=12)

请注意,PHP mcrypt 现在已被弃用(我可能与此有关)并且 SHA-1、MD5 和 ECB 都被认为是不安全的。 A_KEY 不是 AES/Rijndael-128 密钥;这是一个密码,而不是一个 ke 盟友。
@MaartenBodewes 是的,这是真的。 OpenSSL 现在很流行。 php.net/manual/en/book.openssl.php
V
Vahid Farahmandian

对称加密:

对称加密也可以称为共享密钥或共享秘密加密。在对称加密中,单个密钥用于加密和解密流量。

https://i.stack.imgur.com/Yt9x6.png

非对称加密:

非对称加密也称为公钥加密。非对称加密与对称加密的主要区别在于使用了两个密钥:一个用于加密,一个用于解密。最常见的非对称加密算法是RSA

与对称加密相比,非对称加密带来了很高的计算负担,而且速度往往要慢得多。因此,它通常不用于保护有效载荷数据。相反,它的主要优势在于它能够在非安全介质(例如 Internet)上建立安全通道。这是通过交换公钥来完成的,公钥只能用于加密数据。永远不会共享的互补私钥用于解密。

https://i.stack.imgur.com/OcHpG.png

散列:

最后,散列是一种不同于加密的加密安全形式。加密是用于首先加密然后解密消息的两步过程,而散列将消息压缩为不可逆的固定长度值或散列。网络中最常见的两种散列算法是 MD5SHA-1

https://i.stack.imgur.com/Jlmsx.png

在此处阅读更多信息:http://packetlife.net/blog/2010/nov/23/symmetric-asymmetric-encryption-hashing/


抱歉,我是一个安全新手,但您能否进一步解释“通常用于保护有效负载数据”的含义?
@Abdul 非对称加密具有很高的计算负担,因此它不用于保护通过网络作为数据包(有效负载)发送的数据。相反,它用于通过交换公钥来建立安全的网络连接以保护数据。
h
hvgotcodes

当您只需要走一种方式时,请使用哈希。例如,对于系统中的密码,您使用散列,因为您只会验证用户输入的值在散列后是否与您的存储库中的值匹配。使用加密,您可以采用两种方式。散列算法和加密算法只是数学算法。所以在这方面它们没有什么不同——都只是数学公式。但是,在语义方面,散列(单向)和加密(双向)之间存在很大区别。为什么哈希是不可逆的?因为它们被设计成那样,因为有时你想要一种单向操作。


J
Justin Morgan

加密和散列算法以类似的方式工作。在每种情况下,都需要在位之间创建 confusion and diffusion。归根结底,混淆是在密钥和密文之间建立复杂的关系,diffusion是在传播每一位的信息。

许多哈希函数实际上使用加密算法(或加密算法的原语。例如,SHA-3 候选Skein使用 Threefish 作为底层方法来处理每个块。不同之处在于,它们不是保留每个密文块,而是破坏性地,确定性地合并到一个固定的长度


a
ayush

当涉及到传输数据的安全性时,即使用加密的双向通信。所有加密都需要密钥

当涉及到授权时,您使用散列。散列没有关键

散列采用任意数量的数据(二进制或文本)并创建一个表示数据校验和的恒定长度散列。例如,哈希可能是 16 个字节。不同的散列算法产生不同大小的散列。您显然无法从散列重新创建原始数据,但您可以再次散列数据以查看是否生成了相同的散列值。基于 Unix 的单向密码以这种方式工作。密码存储为哈希值,要登录系统,您输入的密码会经过哈希处理,然后将哈希值与真实密码的哈希值进行比较。如果它们匹配,那么您一定输入了正确的密码

为什么哈希不可逆:

散列是不可逆的,因为输入到散列的映射不是一对一的。将两个输入映射到相同的哈希值通常称为“哈希冲突”。出于安全目的,“好”散列函数的属性之一是在实际使用中很少发生冲突。


“哈希是不可逆的,因为输入到哈希的映射不是一对一的”,谢谢,我认为这是区分哈希和加密的一个非常重要的因素! :)
这并没有清楚地区分普通散列函数、加密散列函数和密码散列。它们都有不同的属性。
f
fetknoppen

你已经得到了一些好的答案,但我想你可以这样看:加密:如果你有正确的密钥,加密必须是可解密的。

示例:就像您发送电子邮件一样。您可能不希望世界上的每个人都知道您在给接收电子邮件的人写什么,但接收电子邮件的人可能希望能够阅读它。

散列:散列的工作方式类似于加密,但它根本不能反转它。

示例:就像您将钥匙放入锁着的门(当您关闭它们时锁定的那种)。您不必关心锁的详细工作原理,只要在您使用钥匙时它会自行解锁即可。如果出现问题,您可能无法修复它,而是获得一个新锁。(就像每次登录时忘记密码一样,至少我一直这样做,这是使用散列的常见领域)。

...我想在这种情况下你可以称彩虹算法为锁匠。

希望事情澄清=)


A
Anonymous Platypus

密码学处理数字和字符串。基本上,整个宇宙中的每一个数字事物都是数字。当我说数字时,它是 0 和 1。你知道它们是什么,二进制。你在屏幕上看到的图像,你通过耳机听的音乐,一切都是二进制的。但是我们的耳朵和眼睛不会理解二进制文件,对吧?只有大脑可以理解,即使它可以理解二进制文件,它也无法享受二进制文件。因此,我们将二进制文件转换为人类可以理解的格式,例如 mp3、jpg 等。让我们将这个过程称为编码。这是双向过程,可以很容易地解码回其原始形式。

散列

散列是另一种加密技术,其中一旦转换为其他形式的数据将永远无法恢复。在 Layman 的术语中,没有称为去散列的过程。有许多哈希函数可以完成这项工作,例如 sha-512、md5 等。

如果无法恢复原始值,那么我们在哪里使用它呢?密码!当您为手机或 PC 设置密码时,会创建密码哈希并将其存储在安全的地方。当您下次尝试登录时,输入的字符串再次使用相同的算法(散列函数)进行散列,并且输出与存储的值匹配。如果相同,则您已登录。否则,您将被淘汰。

致谢:wikimedia 通过对密码应用哈希,我们可以确保攻击者即使窃取了存储的密码文件也永远不会得到我们的密码。攻击者将拥有密码的哈希值。他大概可以找到最常用的密码列表,并将 sha-512 应用于每个密码,并将其与手中的值进行比较。它被称为字典攻击。但他要这样做多久?如果您的密码足够随机,您认为这种破解方法可行吗? Facebook、谷歌和亚马逊数据库中的所有密码都经过哈希处理,或者至少它们应该经过哈希处理。

然后是加密

加密介于散列和编码之间。编码是一个双向过程,不应用于提供安全性。加密也是一个双向过程,但当且仅当加密密钥已知时,才能检索原始数据。如果您不知道加密是如何工作的,请不要担心,我们将在这里讨论基础知识。这足以理解 SSL 的基础知识。因此,有两种类型的加密,即对称加密和非对称加密。

对称密钥加密

我试图让事情尽可能简单。那么,让我们通过移位算法来理解对称加密。该算法用于通过向左或向右移动字母来加密字母。让我们取一个字符串 CRYPTO 并考虑一个数字 +3。然后,CRYPTO 的加密格式将是 FUBSWR。这意味着每个字母向右移动 3 个位置。这里,CRYPTO这个词叫做Plaintext,输出的FUBSWR叫做Ciphertext,值+3叫做Encryption key(对称密钥),整个过程就是一个密码。这是最古老和基本的对称密钥加密算法之一,它的第一次使用是在 Julius Caesar 时代报道的。所以,它以他的名字命名,就是著名的凯撒密码。任何知道加密密钥并且可以应用凯撒算法的逆向并检索原始明文的人。因此,它被称为对称加密。

非对称密钥加密

我们知道,在对称加密中,加密和解密都使用相同的密钥。一旦该密钥被盗,所有数据都将消失。这是一个巨大的风险,我们需要更复杂的技术。 1976 年,Whitfield Diffie 和 Martin Hellman 首次发表了非对称加密的概念,该算法被称为 Diffie-Hellman 密钥交换。然后在 1978 年,麻省理工学院的 Ron Rivest、Adi Shamir 和 Leonard Adleman 发表了 RSA 算法。这些可以被认为是非对称密码学的基础。

与对称加密相比,在非对称加密中,将有两个密钥而不是一个。一个称为公钥,另一个称为私钥。理论上,在初始化期间,我们可以为我们的机器生成公钥-私钥对。私钥应保存在安全的地方,绝不应与任何人共享。顾名思义,公钥可以与希望向您发送加密文本的任何人共享。现在,那些拥有你的公钥的人可以用它来加密秘密数据。如果密钥对是使用 RSA 算法生成的,那么它们在加密数据时应该使用相同的算法。通常算法会在公钥中指定。加密数据只能使用您拥有的私钥解密。

资料来源:SSL/TLS for dummies 第 1 部分:密码套件、散列、加密 | WST (https://www.wst.space/ssl-part1-ciphersuite-hashing-encryption/)


M
Mark van der Dam

加密加密的目的是转换数据以使其保密,例如(向某人发送他们只能阅读的秘密文本,通过 Internet 发送密码)。目标不是关注可用性,而是确保数据发送可以秘密发送,并且只有您发送的用户才能看到。它将数据加密为另一种格式,将其转换为独特的模式,可以用密钥加密,拥有密钥的用户可以通过可逆过程看到消息。例如(AES,BLOWFISH,RSA) 加密可能看起来像这样 FhQp6U4N28GITVGjdt37hZN 散列 在技术上我们可以说它需要一个任意输入并产生一个固定长度的字符串。其中最重要的是您不能从输出转到输入。它会产生给定信息未修改的强输出。该过程是获取输入并对其进行哈希处理,然后在接收者收到后使用发送者的私钥发送,他们可以使用发送者的公钥对其进行验证。如果散列错误并且与散列不匹配,我们将看不到任何信息。例如(MD5,SHA .....)