我看到哈希和加密算法之间有很多混淆,我想听到一些关于以下方面的专家建议:
什么时候使用哈希和加密 是什么让哈希或加密算法不同(从理论/数学层面) 例如,是什么使得哈希不可逆(没有彩虹树的帮助)
以下是一些类似的SO问题,但没有像我想要的那样详细:
混淆、哈希和加密之间的区别是什么? 加密和哈希的区别
我看到哈希和加密算法之间有很多混淆,我想听到一些关于以下方面的专家建议:
什么时候使用哈希和加密 是什么让哈希或加密算法不同(从理论/数学层面) 例如,是什么使得哈希不可逆(没有彩虹树的帮助)
以下是一些类似的SO问题,但没有像我想要的那样详细:
混淆、哈希和加密之间的区别是什么? 加密和哈希的区别
当前回答
当你不想返回原始输入时,使用哈希,当你想要返回原始输入时,使用加密。
哈希表获取一些输入并将其转换为一些位(通常被认为是一个数字,如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
就像简单的哈希示例一样,这种类型的加密在历史上也被使用过。
其他回答
Use hashes when you only need to go one way. For example, for passwords in a system, you use hashing because you will only ever verify that the value a user entered, after hashing, matches the value in your repository. With encryption, you can go two ways. hashing algorithms and encryption algorithms are just mathematical algorithms. So in that respect they are not different -- its all just mathematical formulas. Semantics wise, though, there is the very big distinction between hashing (one-way) and encryption(two-way). Why are hashes irreversible? Because they are designed to be that way, because sometimes you want a one-way operation.
当涉及到传输数据的安全性时,即双向通信,你使用加密。所有加密都需要密钥
当涉及到授权时,您使用哈希。哈希中没有键
Hashing takes any amount of data (binary or text) and creates a constant-length hash representing a checksum for the data. For example, the hash might be 16 bytes. Different hashing algorithms produce different size hashes. You obviously cannot re-create the original data from the hash, but you can hash the data again to see if the same hash value is generated. One-way Unix-based passwords work this way. The password is stored as a hash value, and to log onto a system, the password you type is hashed, and the hash value is compared against the hash of the real password. If they match, then you must've typed the correct password
为什么哈希是不可逆的:
哈希是不可逆的,因为输入到哈希的映射不是1对1的。 有两个输入映射到相同的哈希值通常被称为“哈希碰撞”。出于安全考虑,“好的”哈希函数的属性之一是在实际使用中很少发生冲突。
对称加密:
对称加密也可以称为共享密钥或共享秘密加密。在对称加密中,一个密钥同时用于加密和解密流量。
非对称加密:
非对称加密也称为公钥加密。非对称加密与对称加密的主要区别在于使用两个密钥:一个用于加密,一个用于解密。最常用的非对称加密算法是RSA。
与对称加密相比,非对称加密施加了很高的计算负担,并且往往要慢得多。因此,它通常不用于保护有效负载数据。相反,它的主要优势在于能够在不安全的媒介(例如Internet)上建立安全通道。这是通过交换公钥来完成的,而公钥只能用于加密数据。互补私钥(从不共享)用于解密。
散列:
最后,哈希是一种不同于加密的加密安全形式。加密是一个两步过程,用于首先加密消息,然后解密消息,而哈希将消息压缩为不可逆的固定长度值或哈希。网络中最常见的两种哈希算法是MD5和SHA-1。
更多信息请点击:http://packetlife.net/blog/2010/nov/23/symmetric-asymmetric-encryption-hashing/
我的两句台词……面试官一般想要以下答案。
哈希是一种方法。您不能将数据/字符串从哈希代码转换。
加密是两种方式-如果你有密钥,你可以再次解密加密的字符串。
哈希函数将可变大小的文本转换为固定大小的文本。
来源:https://en.wikipedia.org/wiki/Hash_function
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()使用不同的密码哈希值验证密码时,该密码将被接受为有效密码。
$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://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中删除。 应该在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)