编码、加密和散列之间的区别

翻译自The Difference Between Encoding, Encryption and Hashing


在我们的日常生活中,有很多关于数据保护和安全的讨论。我们生活在一个可以说数据是新的“货币”的时代。就像我们拥有的任何其他货币一样,我们永远不会希望我们的数据落入他人手中,尤其是有不良意图的人。如果你认为你的个人数据在网上是安全的,那么请相信我,我的朋友,你大错特错了。

好吧,老实说,大多数正在阅读这个文章的人可能已经意识到了这个事实(如果你还没有意识到,你好!醒醒!)。你可能还听说过本文标题中所写的文字,即编码、加密和散列。一种常见的误解是,这些词指的是同一件事,但实际上它们指的是各自自己的技术,这些技术彼此截然不同。因此,让我们戴上好奇的帽子,尝试了解它们的实际含义。

1. 编码

所以首先,让我们把事情弄清楚,与加密和散列不同,编码不用于安全目的。它是一种将数据从一种格式转换为另一种格式的技术,以便不同的系统可以理解和使用它。编码中没有使用任何“密钥”。同样的算法也被用来解码最初用于对其进行编码的数据。由于这个原因,如果攻击者拥有编码数据,他们很容易解码数据。此类算法的示例是 ASCII、Unicode、Base64 等

1.1 为什么我们需要编码?

为了理解这一点,让我们以 BASE64 编码技术为例。在电子邮件的最初几年,数据主要是基于文本的。因此,为了通过互联网传输,文本数据被转换为二进制格式,在接收端,这个二进制数据再次被转换回文本格式。但随着时间的推移,发送附件以及多媒体以及基于文本的电子邮件的需求就出现了。这些附件的二进制数据在原始形式中被破坏的可能性很高。这主要是因为原始二进制文件包含一些字符,这些字符在某些语言中的处理方式不同。例如,在 C/C++ 中,“Null”字符被视为文件的结尾。因此,发送包含“Null”字节的二进制数据最终会阻止文件被读取完成,并会导致数据损坏。为了解决这个问题,BASE64 编码技术应运而生。

1.2 Base64 编码如何工作?

让我们举一个将“abc”转换为Base64的例子。

  1. 使用ASCII 表,将字符串中的字符转换为十进制。

    a = 97,b = 98 , c = 99。

  2. 将这些十进制数中的每一个转换为等效的 8 位二进制形式:

    a = 0110 0001,b = 0110 0010 , c = 0110 0011。

    即 abc = 0110 0001 0110 0010 0110 0011

  3. 将它们分成每组 6 位:

    011000 — 010110 — 001001 — 100011

  4. 将每个二进制转换为其等效的十进制形式:

    011000 = 24,010110 = 22,001001 = 9 , 100011 = 35

  5. 使用 Base64 表,将这些十进制数中的每一个转换成它们对应的 Base64 字符:

    所以,24 = ‘Y’,23 = ‘X’,9 = ‘J’, 35 = ‘j’。

因此,Base64 中的“abc”=>“YXJj”。

注意:有时不可能将组合的二进制分成每组 6 位的精确组。在这种情况下,最后添加 0 以使其成为精确的 24 位倍数。这个过程称为“填充”。为了对填充的数据进行编码,如果有 6 个完全填充的位,则将其映射为“=”。

补充:编码时,每 3 个字节一组,共 8bit*3=24bit,划分成 4 组,即每 6bit 代表一个编码后的索引值(所以下面填充至24的倍数位)

示例:“a:aa” => 011000 010011 101001 100001 011000 01xxxx xxxxxx xxxxxx => “YTphYQ==”

2. 加密

无法想象没有加密的互联网。如果没有它,互联网将是一个不太安全的地方。互联网上的数据使用加密保持机密和安全。加密使攻击者无法读取和解码数据,并防止数据被盗。

加密使用“加密密钥”。使用密钥,数据在发送端加密,使用相同或不同的密钥,数据在接收端解密。根据用于加密/解密信息的密钥类型,加密分为两类:

  • 对称密钥加密
  • 非对称密钥加密

2.1 对称加密

对称密钥加密方法是直截了当的。在将数据发送给接收者之前,发送者使用私钥对数据进行加密。这个私钥只有发送者和接收者知道。因此,一旦接收者获得加密数据,他或她就会使用发送者的相同私钥对其进行解密。由于发送者和接收者使用相同的密钥,这被称为“对称密钥”加密。

是的,使用这种技术进行加密有很多好处,例如,这个系统的简单性提供了后勤优势,因为它需要更少的计算能力。此外,仅通过增加密钥的长度就可以轻松地帮助提高系统的安全级别。但是我们已经看到了使用这种技术的问题。接收者如何知道最初用来加密数据的密钥是什么?为了让他知道密钥,发送者也必须发送密钥。有问题吗?是的!!发送者也必须将密钥传输给接收者,如果是通过不安全的连接完成的,那么他们的密钥很有可能被任何攻击者截获。

2.2 非对称密钥

为了解决使用对称密钥加密技术的问题,非对称密钥加密技术诞生了。与以前的技术相比,这是一种相对较新的技术。正如你可以从名称本身猜到的那样,这种技术涉及两个不同的密钥。一个密钥用于加密数据,称为公钥,互联网上几乎每个人都知道。另一个密钥用于解密数据,称为私钥,只有接收方知道,必须保密。因此,使用两个不同的密钥使系统更加安全,并且攻击者很难破解它。

公钥和私钥在一起才是锁的真实钥匙。他们就像是数学概念上相互关联的两个非常大的素数。也就是说,任何用公钥加密的东西,都只能用相关的私钥解密。

一些众所周知的非对称密钥加密算法是:

  • RSA
  • DSS(数字签名标准)
  • 椭圆曲线密码学

3. 散列(哈希,摘要)

散列是确保通过网络发送的信息完整性的过程。这意味着它确保即使更改了单个事物,你也可以知道它已更改。散列可以保护你的数据免受潜在的更改,因此你的数据甚至不会被更改一丁点。

散列基本上是通过散列算法从输入字符串生成的字符串。无论输入字符串的大小如何,此散列字符串始终具有固定长度。散列也可以被认为是“单向加密”,即一旦散列的数据永远不能恢复到原来的形式。

“Behind every successful hash algorithm, there is a great hash function” — Some nerd on the Internet

散列函数是散列算法的核心。该散列函数以固定长度接收数据,因此通过将输入划分为固定大小的块来向函数提供输入。这些块被称为“数据块”。如果输入数据的大小小于块的大小,则使用“填充”。

散列过程也称为“雪崩效应”。如下:

消息一次处理一个块。输入提供给第一个块,然后将第一个块的输出与第二个块的输入一起提供给函数。对于第三个块遵循相同的过程,其中第二个块的输出与第三个块的输入一起提供给函数。最终输出是所有块的组合值。

这样的话,如果在消息之间的任何地方更改或操纵单个比特位,则整个散列值将更改。

一些流行的散列算法是:

  • Message Digest (MD) Algorithm
  • Secure Hash Algorithm (SHA)
  • RACE Integrity Primitives Evaluation Message Digest (RIPEMD)
  • Whirlpool
  • Cyclic Redundancy Check (CRC)

4. 总结

  • 编码是将数据从一种格式转换为另一种格式的过程散列是一种通过将数据转换为固定长度的字符串来确保数据完整性的技术
  • 加密是使用密钥将信息转换为密码以保持机密性的过程
  • 散列是一种通过将数据转换为固定长度的字符串来确保数据完整性的技术