Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Security 散列算法和加密算法的根本区别_Security_Encryption_Hash_Cryptography - Fatal编程技术网

Security 散列算法和加密算法的根本区别

Security 散列算法和加密算法的根本区别,security,encryption,hash,cryptography,Security,Encryption,Hash,Cryptography,我看到散列和加密算法之间有很多混淆,我想听听关于以下方面的专家建议: 何时使用哈希与加密 散列或加密算法的不同之处(从理论/数学层面) i、 e.什么使哈希不可逆(没有彩虹树的帮助) 以下是一些类似的SO问题,这些问题并没有我所想的那么详细: 如果您不想恢复原始输入,请使用哈希,如果您想恢复原始输入,请使用加密 散列接受一些输入并将其转换为一些位(通常被认为是一个数字,如32位整数、64位整数等)。相同的输入总是会产生相同的散列,但在这个过程中,您主要会丢失信息,因此无法可靠地再现原始输入(不

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

  • 何时使用哈希与加密

  • 散列或加密算法的不同之处(从理论/数学层面) i、 e.什么使哈希不可逆(没有彩虹树的帮助)

  • 以下是一些类似的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
    

    就像简单的散列示例一样,这种类型的加密有。

    好吧,您可以在。。。但既然你想要一个解释,我会尽我所能:

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

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

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

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

    用例 当您想要比较一个值但无法存储普通表示形式(出于各种原因)时,请使用哈希函数。密码应该非常适合这个用例,因为出于安全原因,您不希望以纯文本形式存储它们(而且不应该)。但是如果你想检查文件系统中的盗版音乐文件呢?每个音乐文件存储3MB是不切实际的。因此,取而代之的是,获取文件的散列并存储它(md5将存储16个字节而不是3mb)。这样,您只需散列每个文件并与存储的dat进行比较
    var hash = password + salt;
    for (var i = 0; i < 5000; i++) {
        hash = sha512(hash + password + salt);
    }
    
    hash = sha512(password + salt); 
    for (i = 0; i < 1000; i++) {
        hash = sha512(hash); // <-- Do NOT do this!
    }
    
    hash1 = sha1(password + salt);
    
    hash = sha512(password + salt);
    for (i = 0; i < 1000; i++) {
        hash = sha512(hash + password + salt);
    }
    
    4 + 3 = 7  
    
    7 - 3 = 4     
    
    4 * 5 = 20  
    
    20 / 4 = 5    
    
    22 % 7 = 1   
    
    1  ?  7 = 22  
    1  ?  22 = 7
    
    $str = 'My age is 29';
    $hash = hash('sha1', $str);
    echo $hash; // OUTPUT: 4d675d9fbefc74a38c89e005f9d776c75d92623e
    
    // 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 = '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
    
    $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)
    
    $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)