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

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

  1. 什么时候使用哈希和加密

  2. 哈希或加密算法的不同之处(从理论/数学层面) 例如,是什么使哈希不可逆(没有彩虹树的帮助)

以下是一些类似的 SO问题,它们并没有像我想要的那样详细:

< p > # EYZ0 < br > # EYZ0 < / p >
224107 次浏览

当你不想返回原始输入时,使用哈希,当你想要返回原始输入时,使用加密。

哈希表获取一些输入并将其转换为一些位(通常被认为是一个数字,如32位整数,64位整数等)。相同的输入总是会产生相同的散列,但是在这个过程中你主要会丢失信息,所以你不能可靠地重现原始输入(但是有一些注意事项)。

加密主要保留了您输入到加密函数中的所有信息,只是使任何人在不拥有特定密钥的情况下很难(理想情况下不可能)逆转到原始输入。

哈希的简单例子

这里有一个简单的例子来帮助您理解为什么哈希(在一般情况下)不能返回原始输入。假设我要创建一个1位哈希。我的哈希函数接受一个比特字符串作为输入,如果输入字符串中设置了偶数位,则将哈希值设置为1,如果输入字符串中设置了奇数位,则设置为0。

例子:

Input    Hash
0010     0
0011     1
0110     1
1000     0

注意,有许多输入值的哈希值为0,也有许多输入值的哈希值为1。如果你知道哈希值是0,你就不能确定原始输入是什么。

顺便说一下,这个1位哈希并不是完全人为的…看看校验位

加密的简单例子

你可以通过使用简单的字母替换来加密文本,比如如果输入是a,你就写B。如果输入是B,你就写c。一直到字母表的末尾,如果输入是Z,你又写a。

Input   Encrypted
CAT     DBU
ZOO     APP

就像简单的哈希示例一样,这种类型的加密具有历史上使用过

嗯,你可以在维基百科中查找它…但既然你想要一个解释,我在这里尽我所能:

哈希函数

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

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

现在,如果您想解码散列,首先需要弄清楚如何将给定的散列分割为其迭代状态(1种可能用于小于数据块大小的输入,许多用于较大的输入)。然后需要为每个状态反转迭代。现在,为了解释为什么这非常困难,想象一下试图从下面的公式中推导出ab: 10 = 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)。这样,您只需散列每个文件,并与存储的散列数据库进行比较(这在实践中并不是很好,因为需要重新编码、更改文件头等,但这是一个示例用例)。

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

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

哈希函数对于签名数据也很有用。例如,如果您正在使用HMAC,则通过获取与已知但未传输的值(秘密值)连接的数据的哈希来对数据进行签名。你发送明文和HMAC哈希。然后,接收端简单地用已知值散列提交的数据,并检查它是否与传输的HMAC匹配。如果它是相同的,您就知道它没有被没有秘密值的一方篡改。这通常用于HTTP框架的安全cookie系统,以及通过HTTP传输数据的消息时,您希望保证数据的完整性。

关于密码散列的注意事项:

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

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

有很多处理方法。一种流行的方法称为重点加强(或键拉伸)。基本上,迭代哈希多次(通常是数千次)。这有两个作用。首先,它显著降低了哈希算法的运行速度。其次,如果实现正确(在每次迭代中传递输入和盐),实际上会增加输出的熵(可用空间),减少碰撞的机会。一个简单的实现是:

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)更好,但仍然不够好…使用一个扩展散列机制来生成你的密码散列…

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

# EYZ0:

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);#EYZ0的所有碰撞都会自动变成hash2的碰撞。现在,hash1的速率为0.001%,第2次sha1()调用增加了这个值。所以现在,hash2的碰撞概率是0.002%。这是两倍的机会!每次迭代都将在结果中添加另一个0.001%的碰撞机会。因此,经过1000次迭代,碰撞的几率从微不足道的0.001%跃升至1%。现在,退化是线性的,实际概率更小,但效果是相同的(与md5发生单次碰撞的概率约为1/(2hash2 = sha1(hash1);0)或1/(3x10hash2 = sha1(hash1);1)。虽然这看起来很小,但多亏了hash2 = sha1(hash1);2,它并没有看起来那么小)。

相反,通过每次重新追加盐和密码,将数据重新引入散列函数。所以任何一轮的碰撞都不再是下一轮的碰撞。所以:

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

具有与本机sha512函数相同的碰撞几率。这就是你想要的。那就用这个吧。

  1. 当你只需要走一条路的时候使用哈希。例如,对于系统中的密码,您可以使用散列,因为在散列之后,您只需要验证用户输入的值是否与存储库中的值匹配。有了加密,你可以有两种选择。

  2. 哈希算法和加密算法只是数学算法。所以在这方面它们并没有什么不同——都是数学公式。但是,在语义上,哈希(单向)和加密(双向)之间有很大的区别。为什么哈希是不可逆的?因为它们就是这样设计的,因为有时候你想要单向操作。

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

当涉及到授权时,您使用哈希。哈希中没有键

哈希取任意数量的数据(二进制或文本)并创建一个表示数据校验和的常量长度哈希。例如,哈希值可能是16字节。不同的哈希算法产生不同大小的哈希值。显然不能从散列重新创建原始数据,但是可以再次散列数据,以查看是否生成了相同的散列值。单向基于unix的密码就是这样工作的。密码存储为哈希值,要登录到系统,您输入的密码将被哈希,并将哈希值与实际密码的哈希值进行比较。如果匹配,那么你输入的密码一定是正确的

为什么哈希是不可逆的:

哈希是不可逆的,因为输入到哈希的映射不是1对1。 有两个输入映射到相同的哈希值通常被称为“哈希碰撞”。出于安全考虑,“好的”哈希函数的属性之一是在实际使用中很少发生冲突。< / p >

哈希函数可以看作是烤一条面包。你从输入(面粉、水、酵母等)开始,在应用哈希函数(混合+烘焙)后,你最终会得到一个输出:一条面包。

另一种方法是非常困难的——你不能真正地把面包分成面粉、水和酵母——其中一些在烘焙过程中丢失了,你永远无法确切地说出某条面包使用了多少水、面粉或酵母,因为这些信息被哈希函数(又名烤箱)破坏了。

从理论上讲,许多不同的输入变体将生产相同的面包(例如,2杯水和1茶匙酵母生产的面包与2.1杯水和0.9茶匙酵母生产的面包完全相同),但给定其中一个面包,你无法确切地说出哪种输入组合生产了它。

另一方面,加密可以被看作是一个保险箱。不管你放进去什么,只要你有一开始锁进去的钥匙,它就会出来。这是一个对称运算。给定一个键和一些输入,就会得到一个特定的输出。给定这个输出和相同的键,您将得到原始的输入。这是一个1:1的映射。

加密和哈希算法的工作原理类似。在每种情况下,都需要在位之间创建混乱和扩散。简而言之,混乱在密钥和密文之间创建了一个复杂的关系,而扩散则在传播每个比特的信息。

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

哈希和加密/解密技术的基本概述如下。

散列:

如果你哈希任何纯文本你<强>不能得到同样的平淡 来自散列文本。简单地说,这是一个单向过程

hash


加密和解密:

如果你加密任意纯文本与一个键再次你<强>可以 使用相同(对称)/不同(不对称)密钥对加密文本执行解密,得到相同的纯文本

加密和解密


< >强更新:

.

.

1. 什么时候使用哈希和加密

哈希是有用的,如果你想发送一个文件。但是您担心其他人会拦截文件并更改它。所以一个 接收者可以确保它是正确的文件的方法是如果 公开发布哈希值。这样接收者就可以计算了 接收到的文件的哈希值,并检查它是否与哈希值匹配 价值。< / p >

加密很好,如果你说有消息要发送给某人。使用密钥加密消息,收件人使用 相同(甚至可能是不同的)键来返回原始消息。 # EYZ0 < / p >


< p > <强> 2。是什么使哈希或加密算法不同(从理论/数学层面),即什么使哈希不可逆 (没有彩虹树的帮助)

基本上哈希是一个 丢失信息但不加密的操作。让我们看看 用简单的数学方法来区分 当然两者都有更复杂的数学运算 it中涉及的重复

加密/解密(可逆):

# EYZ0:

4 + 3 = 7

这可以通过取和并减去一个 叫做加数< / p >

7 - 3 = 4

# EYZ0:

4 * 5 = 20

这可以通过取乘积并除以其中一个 因素< / p >

20 / 4 = 5

因此,这里我们可以假设其中一个加数/因数是一个解密密钥,结果(7,20)是一个加密文本。


哈希(不可逆):

# EYZ0:

22 % 7 = 1

这是不能逆转的,因为你不能对商和被除数做任何操作 重构除数(反之亦然)。

你能找到一个操作来填充'吗?”是吗?

1  ?  7 = 22
1  ?  22 = 7

所以哈希函数与模除法具有相同的数学性质,并且丢失了信息。

信用< a href = " https://stackoverflow.com/questions/2112685/how-do-one-way-hash-functions-work " > < / >

我的两句台词……面试官一般想要以下答案。

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

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

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

Hash

来源:# EYZ0


PHP中的哈希函数

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

散列:

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

密码通常以散列表示形式存储,而不是以可读文本的形式存储。当终端用户希望访问受密码保护的应用程序时,必须在身份验证过程中提供密码。当用户提交密码时,有效的身份验证系统接收密码并对给定的密码进行散列。将此密码哈希与系统已知的哈希进行比较。在平等的情况下,允许访问。

DEHASH:

SHA1是单向哈希。这意味着你不能去散列。

但是,您可以强制使用散列。请参见:https://hashkiller.co.uk/sha1-decrypter.aspx

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

为了阻止对哈希的暴力攻击,可以给一个盐。 在php中,您可以使用password_hash()来创建密码散列。 函数password_hash()自动创建一个盐。 使用password_verify().

验证密码哈希(使用salt)
// 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()验证具有不同密码散列的密码时,该密码将被接受为有效密码。< / p >

$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

<人力资源>



加密功能通过使用加密密钥将文本转换为无意义的密文,反之亦然。 enter image description here

来源:# EYZ0


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中删除。 应该在php 7中使用OpenSSL扩展。参见下面的代码片段:

$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)

对称加密:

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

enter image description here

非对称加密:

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

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

enter image description here

散列:

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

enter image description here

点击这里阅读更多内容:http://packetlife.net/blog/2010/nov/23/symmetric-asymmetric-encryption-hashing/

加密的目的是对数据进行转换,以使其保密。例如(给某人发送一个只能让他们阅读的秘密文本,通过互联网发送密码)。

我们的目标不是关注可用性,而是确保发送的数据可以秘密发送,并且只能被发送的用户看到。

它将数据加密为另一种格式,将其转换为唯一的模式,它可以用秘密密钥加密,拥有秘密密钥的用户可以通过可逆过程看到消息。 如(AES、河豚、RSA) < / p >

加密可能简单地像这样FhQp6U4N28GITVGjdt37hZN

从技术上讲,我们可以说它是接受任意输入并产生固定长度的字符串。

这里最重要的是你不能从输出到输入。它产生的强输出表明给定的信息没有被修改。 这个过程是获取一个输入并哈希它,然后在接收方收到后使用发送方的私钥发送,他们可以用发送方的公钥验证它

如果哈希是错误的,与哈希不匹配,我们就不能看到任何信息。如(MD5,沙……)

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

哈希

哈希是另一种加密技术,数据一旦转换为其他形式就永远无法恢复。用外行的术语来说,没有称为de-hashing的过程。有许多哈希函数来完成这项工作,例如sha-512, md5等等。

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

< p >学分:维基 通过对密码应用哈希,我们可以确保攻击者即使窃取了存储的密码文件也永远不会得到我们的密码。攻击者将得到密码的哈希值。他可能会找到一个最常用的密码列表,并将sha - 512应用于每个密码,并将其与他手中的值进行比较。它被称为字典攻击。但他会这样做多久?如果你的密码足够随机,你认为这种破解方法有用吗? Facebook,谷歌和Amazon数据库中的所有密码都是散列的,或者至少应该是散列的

然后是加密

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

对称密钥加密

我正努力让事情尽可能简单。让我们通过移位算法来理解对称加密。该算法通过将字母向左或向右移动来加密字母。让我们以字符串CRYPTO为例,考虑一个数字+3。那么,CRYPTO的加密格式将是FUBSWR。这意味着每个字母都向右移动了3个位置。 这里,单词CRYPTO被称为明文,输出FUBSWR被称为密文,值+3被称为加密 关键(对称密钥),整个过程是密码。这是最古老和最基本的对称密钥加密算法之一,它的第一次使用是在尤里乌斯·凯撒时期被报道的。所以,它以他的名字命名,就是著名的凯撒密码。任何人谁知道加密密钥,并可以应用凯撒的反向算法和检索原始明文。因此它被称为对称加密.

非对称密钥加密

我们知道,在对称加密中,相同的密钥用于加密和解密。一旦钥匙被盗,所有的数据都消失了。这是一个巨大的风险,我们需要更复杂的技术。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/)

你已经得到了一些很好的答案,但我猜你可以这样看: 加密: 如果你有正确的密钥,加密必须是可以解密的 < p >的例子: 就像你发电子邮件一样。 你可能不希望世界上每个人都知道你在给接收电子邮件的人写什么,但接收电子邮件的人可能希望能够阅读它 < p >散列: 哈希的工作原理类似于加密,但它应该完全不能反转加密 < p >的例子: 就像你把钥匙插进一扇锁着的门里(就是那种你关门时就会锁上的门)。你不需要关心锁的具体工作原理,只要在你使用钥匙时它能自己解锁就行了。如果出现问题,你可能无法修复它,不如换一个新锁。(就像每次登录都会忘记密码一样,至少我一直这样做,这是使用哈希的常见领域)

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

希望事情好转=)