OpenSSL 入门:密码学基础知识

2024年 7月 18日 74.5k 0

想要入门密码学的基础知识,尤其是有关 OpenSSL 的入门知识吗?继续阅读。

OpenSSL 入门:密码学基础知识-1

本文是使用 OpenSSL 的密码学基础知识的两篇文章中的第一篇,OpenSSL 是在 Linux 和其他系统上流行的生产级库和工具包。(要安装 OpenSSL 的最新版本,请参阅这里。)OpenSSL 实用程序可在命令行使用,程序也可以调用 OpenSSL 库中的函数。本文的示例程序使用的是 C 语言,即 OpenSSL 库的源语言。

本系列的两篇文章涵盖了加密哈希、数字签名、加密和解密以及数字证书。你可以从我的网站的 ZIP 文件中找到这些代码和命令行示例。

让我们首先回顾一下 OpenSSL 名称中的 SSL。

OpenSSL 简史

安全套接字层 Secure Socket Layer (SSL)是 Netscape 在 1995 年发布的一种加密协议。该协议层可以位于 HTTP 之上,从而为 HTTPS 提供了 S: 安全 secure 。SSL 协议提供了各种安全服务,其中包括两项在 HTTPS 中至关重要的服务:

  • 对等身份验证 Peer authentication (也称为相互质询):连接的每一边都对另一边的身份进行身份验证。如果 Alice 和 Bob 要通过 SSL 交换消息,则每个人首先验证彼此的身份。
  • 机密性 Confidentiality :发送者在通过通道发送消息之前先对其进行加密。然后,接收者解密每个接收到的消息。此过程可保护网络对话。即使窃听者 Eve 截获了从 Alice 到 Bob 的加密消息(即中间人攻击),Eve 会发现他无法在计算上解密此消息。

反过来,这两个关键 SSL 服务与其他不太受关注的服务相关联。例如,SSL 支持消息完整性,从而确保接收到的消息与发送的消息相同。此功能是通过哈希函数实现的,哈希函数也随 OpenSSL 工具箱一起提供。

SSL 有多个版本(例如 SSLv2 和 SSLv3),并且在 1999 年出现了一个基于 SSLv3 的类似协议 传输层安全性 Transport Layer Security (TLS)。TLSv1 和 SSLv3 相似,但不足以相互配合工作。不过,通常将 SSL/TLS 称为同一协议。例如,即使正在使用的是 TLS(而非 SSL),OpenSSL 函数也经常在名称中包含 SSL。此外,调用 OpenSSL 命令行实用程序以 openssl 开始。

除了 man 页面之外,OpenSSL 的文档是零零散散的,鉴于 OpenSSL 工具包很大,这些页面很难以查找使用。命令行和代码示例可以将主要主题集中起来。让我们从一个熟悉的示例开始(使用 HTTPS 访问网站),然后使用该示例来选出我们感兴趣的加密部分进行讲述。

一个 HTTPS 客户端

此处显示的 client 程序通过 HTTPS 连接到 Google:

/* compilation: gcc -o client client.c -lssl -lcrypto */
#include 
#include 
#include  /* BasicInput/Output streams */
#include  /* errors */
#include  /* core library */
#define BuffSize 1024

void report_and_exit(const char* msg) {
  perror(msg);
  ERR_print_errors_fp(stderr);
  exit(-1);
}

void init_ssl() {
  SSL_load_error_strings();
  SSL_library_init();
}

void cleanup(SSL_CTX* ctx, BIO* bio) {
  SSL_CTX_free(ctx);
  BIO_free_all(bio);
}

void secure_connect(const char* hostname) {
  char name[BuffSize];
  char request[BuffSize];
  char response[BuffSize];

  const SSL_METHOD* method = TLSv1_2_client_method();
  if (NULL == method) report_and_exit("TLSv1_2_client_method...");

  SSL_CTX* ctx = SSL_CTX_new(method);
  if (NULL == ctx) report_and_exit("SSL_CTX_new...");

  BIO* bio = BIO_new_ssl_connect(ctx);
  if (NULL == bio) report_and_exit("BIO_new_ssl_connect...");

  SSL* ssl = NULL;

  /* 链路 bio 通道,SSL 会话和服务器端点 */

  sprintf(name, "%s:%s", hostname, "https");
  BIO_get_ssl(bio, &ssl); /* 会话 */
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* 鲁棒性 */
  BIO_set_conn_hostname(bio, name); /* 准备连接 */

  /* 尝试连接 */
  if (BIO_do_connect(bio) |Alice's private key|---> Bob's msg
             +------------------+                +-------------------+

理论上可以在没有 Alice 的私钥的情况下解密消息,但在实际情况中,如果使用像 RSA 这样的加密密钥对系统,则在计算上做不到。

现在,第二个示例,请对文档签名以证明其真实性。签名算法使用密钥对中的私钥来处理要签名的文档的加密哈希:

                    +-------------------+
Hash of document--->|Alice's private key|--->Alice's digital signature of the document
                    +-------------------+

假设 Alice 以数字方式签署了发送给 Bob 的合同。然后,Bob 可以使用 Alice 密钥对中的公钥来验证签名:

                                             +------------------+
Alice's digital signature of the document--->|Alice's public key|--->verified or not
                                             +------------------+

假若没有 Alice 的私钥,就无法轻松伪造 Alice 的签名:因此,Alice 有必要保密她的私钥。

client 程序中,除了数字证书以外,这些安全性都没有明确展示。下一篇文章使用使用 OpenSSL 实用程序和库函数的示例填充更多详细的信息。

命令行的 OpenSSL

同时,让我们看一下 OpenSSL 命令行实用程序:特别是在 TLS 握手期间检查来自 Web 服务器的证书的实用程序。调用 OpenSSL 实用程序可以使用 openssl 命令,然后添加参数和标志的组合以指定所需的操作。

看看以下命令:

openssl list-cipher-algorithms

该输出是组成 加密算法套件 cipher suite 的相关算法的列表。下面是列表的开头,加了澄清首字母缩写词的注释:

AES-128-CBC ## Advanced Encryption Standard, Cipher Block Chaining
AES-128-CBC-HMAC-SHA1 ## Hash-based Message Authentication Code with SHA1 hashes
AES-128-CBC-HMAC-SHA256 ## ditto, but SHA256 rather than SHA1
...

下一条命令使用参数 s_client 将打开到 www.google.com 的安全连接,并在屏幕上显示有关此连接的所有信息:

openssl s_client -connect www.google.com:443 -showcerts

端口号 443 是 Web 服务器用于接收 HTTPS(而不是 HTTP 连接)的标准端口号。(对于 HTTP,标准端口为 80)Web 地址 www.google.com:443 也出现在 client 程序的代码中。如果尝试连接成功,则将显示来自 Google 的三个数字证书以及有关安全会话、正在使用的加密算法套件以及相关项目的信息。例如,这是开头的部分输出,它声明证书链即将到来。证书的编码为 base64:

Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com
 i:/C=US/O=Google Trust Services/CN=Google Internet Authority G3
-----BEGIN CERTIFICATE-----
MIIEijCCA3KgAwIBAgIQdCea9tmy/T6rK/dDD1isujANBgkqhkiG9w0BAQsFADBU
MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMSUw
...

诸如 Google 之类的主要网站通常会发送多个证书进行身份验证。

输出以有关 TLS 会话的摘要信息结尾,包括加密算法套件的详细信息:

SSL-Session:
    Protocol : TLSv1.2
    Cipher : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: A2BBF0E4991E6BBBC318774EEE37CFCB23095CC7640FFC752448D07C7F438573
...

client 程序中使用了协议 TLS 1.2,Session-ID 唯一地标识了 openssl 实用程序和 Google Web 服务器之间的连接。Cipher 条目可以按以下方式进行解析:

  • ECDHE( 椭圆曲线 Diffie-Hellman(临时) Elliptic Curve Diffie Hellman Ephemeral )是一种用于管理 TLS 握手的高效的有效算法。尤其是,ECDHE 通过确保连接双方(例如,client 程序和 Google Web 服务器)使用相同的加密/解密密钥(称为会话密钥)来解决“密钥分发问题”。后续文章会深入探讨该细节。
  • RSA(Rivest Shamir Adleman)是主要的公共密钥密码系统,并以 1970 年代末首次描述了该系统的三位学者的名字命名。这个正在使用的密钥对是使用 RSA 算法生成的。
  • AES128( 高级加密标准 Advanced Encryption Standard )是一种 块式加密算法 block cipher ,用于加密和解密 位块 blocks of bits 。(另一种算法是 流式加密算法 stream cipher ,它一次加密和解密一个位。)这个加密算法是对称加密算法,因为使用同一个密钥进行加密和解密,这首先引起了密钥分发问题。AES 支持 128(此处使用)、192 和 256 位的密钥大小:密钥越大,安全性越好。

通常,像 AES 这样的对称加密系统的密钥大小要小于像 RSA 这样的非对称(基于密钥对)系统的密钥大小。例如,1024 位 RSA 密钥相对较小,而 256 位密钥则当前是 AES 最大的密钥。

  • GCM( 伽罗瓦计数器模式 Galois Counter Mode )处理在安全对话期间重复应用的加密算法(在这种情况下为 AES128)。AES128 块的大小仅为 128 位,安全对话很可能包含从一侧到另一侧的多个 AES128 块。GCM 非常有效,通常与 AES128 搭配使用。
  • SHA256( 256 位安全哈希算法 Secure Hash Algorithm 256 bits )是我们正在使用的加密哈希算法。生成的哈希值的大小为 256 位,尽管使用 SHA 甚至可以更大。

加密算法套件正在不断发展中。例如,不久前,Google 使用 RC4 流加密算法(RSA 的 Ron Rivest 后来开发的 Ron’s Cipher 版本 4)。 RC4 现在有已知的漏洞,这大概部分导致了 Google 转换为 AES128。

总结

我们通过安全的 C Web 客户端和各种命令行示例对 OpenSSL 做了首次了解,使一些需要进一步阐明的主题脱颖而出。下一篇文章会详细介绍,从加密散列开始,到对数字证书如何应对密钥分发挑战为结束的更全面讨论。

via: https://opensource.com/article/19/6/cryptography-basics-openssl-part-1

作者:Marty Kalin 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关文章

Linux 命令行的聊天工具 CenterIM
Linux 桌面年仍未到来 但 Linux 移动之年已到来
12 个在线学习 Linux 技能网站
Linux Mint : 会是另一个新的 Ubuntu 吗?
W3Conf 开发者大会将于下周召开
Ubuntu 10.04 ARM 处理器上网本版本结束服务期

发布评论