密码学是什么?又如何工作?

Cryptography

Not Just a Digital Thing

正如 Bruce Schneier 在其应用密码学(Applied Cryptography) 一书中所定义的那样, “The art and science of keeping messages secure is cryptography […].”  密码学虽然现在被认为是我们数字生活的基础,但与计算无关。几千年来它已经以各种形式存在。下面是维基百科关于密码学历史的文章节选:

已知的最早使用密码学的地方是在公元前1900年左右从埃及古王国雕刻到墓葬墙上的非标准象形文字中发现的。虽然,并不能严谨的说明是在进行加密通信,更像是试图给别的文明添加神秘。以下是密码学在实际用途方面的例子。之后,一些来自Mesopotamia的粘土片显然是为了保护信息 –可以追溯到公元前1500年左右的黏土片被发现用来加密一名工匠的陶器釉料配方,据推测,这种釉料具有商业价值。再后来,大约在500至600年之间,希伯来学者开始使用简单的单字母替代密码(如 Atbash 密码)。在印度,大约在公元前400年至公元前200年,Mlecchita vikalpa 或许是理解了在 cypher 中的写作艺术,用一种特殊方式写作的文字记载于「Kama Sutra」中,为了恋人之间进行沟通。这也可能是一个简单的替代密码。埃及 Greek Magical Papyri 的部分是用密码脚本编写的。 

你可能以前见过简单的密码学例子。Caesar cipher 或 shift cipher  通常用于解密秘密信息的儿童游戏。ROT13 是一种非常常见的移位密码,其中字母按13步旋转,如下所示:

很容易看出,这种密码不提供真正的安全性,但它简单而有趣的说明了密码学背后的基本思想。

今天当我们谈论密码学时,我们通常会在技术环境中谈论它。例如,当我们进行购买或查看我们的银行账户时,个人和财务信息是如何在网络上安全的进行传输(保护传输中的数据)的?如何安全地存储数据(称为保护静态数据),以便别人不能够打开计算机,弹出硬盘驱动器,还能在现场获得有关此信息的日期?

 Definitions

A Quick Cybersecurity Primer

在网络安全方面,涉及到数据时,我们会关注很多事情。这些包括数据的 Confidentiality (机密性),integrity (完整性),availability (可用性) 和 non-repudiation (不可否认性)。

Confidentiality 意味着我们的数据不能被未经授权的用户访问/读取。

integrity 意味着我们的数据 100% 还原,并且没有被修改,无论是由恶意参与者、数据丢失还是其他原因造成的。

availability  意味着我们的数据在需要时可以访问。

non-repudiation 意味着,如果 Bob 将一些数据发送给 Mary,那么他就不能在以后声称他不是那个信息的发送者。换句话说,有一些方法可以确定除了 Bob 之外没有人可以发送数据。

密码学在可用性方面对我们没有多大帮助,但是我们将研究各种形式的数字密码学,以及它们如何帮助我们实现上述其他的三个目标。当我们谈论数字密码学时,我们通常指的是以下其中之一:

  1. 对称加密

  2. 非对称加密

  3. 散列函数

  4. 数字签名

接下来会对每一个进行扩展。所有的代码示例都是改编自 Jesus Castello 在 SitePoint 上的精彩文章,「Exploring Cryptography Fundamentals in Ruby」以及官方 Ruby 文档。同时请记住,这些示例是为了说明这些概念,而不是提供数据安全性的最佳实践。

对称加密

Not Just a Digital Thing

在深入探讨之前:“encryption”究竟意味着什么?加密和解密通常分别用来表示使用密码和解除密码; 简单地说,对消息进行加密意味着使用密码(这样做的具体方法)使未授权方无法读取消息。解密消息意味着逆转过程并使数据再次可读。

为了正确加密和解密我们的数据,我们需要数据和一个密钥(它决定了我们的密码输出)。

使用对称加密,用于加密和解密数据的密钥是相同的。取一个字符串并使用 Ruby 和OpenSSL 对其进行加密:

注意,这样做是有破坏性的 (重新分配包含原始字符串的变量),为了证明确实在加密和解密。现在进入我们的 Pry 控制台 :

注意我们的 data_to_encrypt 变量,它最初设置为 “now you can read me !” ,现在是一堆不可读的垃圾。使用我们最初保存在 key 变量中的 key 来逆转这个过程。

正如我们所看到的,使用我们为加密设置的相同密钥,返回原始字符串。

非对称加密

Asymmetric Encryption

对称加密的问题在于:如果需要在恶劣环境(如 Internet)中安全地发送数据,该怎么办?如果使用相同的密钥来加密和解密数据,那么首先需要向您发送解密密钥来建立安全连接。但这意味着我将密钥通过一个不安全的连接发送,密钥可以被第三方拦截和使用!如何解决这个问题?输入非对称加密。

以下有一个大概的想法。要使用非对称密码,需要生成两个数学关联的密钥。一个是私钥(只有您有权访问),以及公钥(顾名思义)可以与任何人公开共享。

因此,请求安全的连接到服务器,服务器发送它的公钥,客户端为对称密码生成密钥并使用服务器的公钥对其进行加密,服务器使用其私钥对包含对称密钥的消息进行解密,现在双方都有对称密钥,可以使用对称加密建立安全连接。

可是接下来我们有另一个问题。我怎么知道服务器的公钥是合法的,即属于该服务器!?通常,处理这个问题有两种方法,但最常用的方法(以及网上使用的方法)是通过使用公钥基础结构(PKI)。有一种情况就是网站,有一个证书颁发机构,该机构有一个包含所有已颁发证书的网站的目录以及它们的公钥。当您连接到网站时,首先使用证书颁发机构验证它的公钥。

将字符串从最后一节加回来,并生成一个公钥/私钥对:

现在进入我们的Pry控制台并处理我们的字符串:

首先,请注意我们的密钥和我们的公钥是具有不同对象 ID 的独立对象。使用 #private_encrypt,我们可以使用私钥加密我们的字符串。再次注意我们在 data_to_encrypt 变量中输入的无意义输出。现在让我们使用公钥解密数据:

使用 #public_decrypt,我们就不能够使用我们最初加密信息的私钥,而是使用与其相关的公钥来获取原始消息。同理可得。

散列函数

Hashing functions

散列函数与对称/非对称加密不同,是一种单向函数。您可以从某些数据创建散列,但无法真正逆转该过程。因此,它对于存储数据没有用,但它是在验证某些数据完整性方面很有效果。

散列函数将一些数据作为输入,并输出一个看起来随机(但不是全部)的字符串,该字符串的长度始终相同。理想的散列函数为不同的输入创建唯一的值。完全相同的输入将始终产生完全相同的散列 - 这就是为什么我们可以使用它来验证数据完整性。

我们这次使用一个新字符串,通过散列函数运行它,并将该散列存储在一个变量中。

 

首先,让我们再次对字符串进行散列,并将其与我们保存在 digest 变量中的那个进行比较。

正如我们所看到的,只要数据保持不变,digests 仍然会匹配。现在让我们稍微改变一下数据并比较 digests 。然后,我们会将数据更改回原来的格式,并再次比较 digests 。

为了让您了解在类似数据中 digests 看起来有多不同,请查看 digests 本身:

  

数字签名

Digital Signatures

数字签名对完整性和不可否认性都有很好的应用。数字签名是散列和非对称加密的组合。也就是说,信息首先被散列函数计算,并且该散列用发送者的私钥加密。这就组成了签名,与消息一起发送。

收件人使用发件人的公钥从签名中提取散列,然后对信息进行散列处理以与提取的散列进行比较。如果您确信公钥属于发件人,并且公钥解密成功,那么您可以确信邮件确实来自发件人。如果提取的散列与信息的计算散列匹配,则可以确定消息的完整性。

请记住,数字签名不一定会使信息保密; 因为有可能签署明文消息。 数字签名将与加密的消息一起工作,但是信息本身的加密必须单独执行。

猜你喜欢

转载自blog.csdn.net/weixin_42470308/article/details/81481908
今日推荐