加密:对称与非对称
密码学广泛使用两类主要加密方案:对称加密,使用同一个秘密密钥加密和解密数据;以及非对称加密,使用公钥密码系统,通过一对公钥及其对应的私钥完成加密和解密。下面详细解释这些基础密码学概念。
对称加密的概念与算法
对称加密方案使用同一个对称密钥(或密码)来加密数据,并将加密数据解密回原始形式:

对称加密通常会将多种密码算法组合成一种对称加密方案,例如 AES-256-CTR-HMAC-SHA256。一个加密方案(密码构造)可能包括:带有特定参数的基于密码的密钥派生算法、带有特定参数的对称密码算法、分组密码工作模式算法,以及消息认证(MAC)算法。因此,上图经过了简化,并未完整呈现整个过程。
秘密密钥
用于对数据进行加密和解密的秘密密钥通常为 128、192 或 256 位。它有时也称为“加密密钥”或“共享密钥”,因为发送方和接收方都必须知道它。
大多数应用会使用从密码派生密钥方案,从某个密码中提取秘密密钥,因为用户通常更容易记住密码而不是二进制数据。此外,加密还常与消息认证结合,以提供完整性和真实性;这种加密方法称为“认证加密”。
一个秘密密钥是什么样的?先来看一个简单的 256 位秘密密钥示例,它编码为十六进制字符串:
02c324648931b89e3e8a0fc42c96e8e3be2e42812986573a40d46563bceaf75110
在许多系统中,例如公有区块链、PGP 和 OpenSSL,秘密密钥会编码为 base58 或 base64,以获得更短的字符串表示。
例如,上述密钥以 base58 表示如下:
pbPRqYDxnKZfs8j4KKiqYmx6nzipAjTJf1oCD1WKgy99
同一个密钥以 base64 表示如下:
AsMkZIkxuJ4+ig/ELJbo474uQoEphlc6QNRlY7zq91EQ
在十进制系统中,上述密钥是以下整数:
319849484316084980661994213716306415989897600164422912728298459349458028548368
现代对称加密算法
现代密码学广泛使用的对称加密算法(密码)包括:AES(AES-128、AES-192、AES-256)、ChaCha20、Twofish、IDEA、Serpent)、Camellia) 等。其中大多数是分组密码,以固定大小的分组加密数据,例如每组 128 位;另一些则是流密码,像处理数据流一样逐字节加密。利用“分组密码工作模式”技术,可以将分组密码转换为流密码。
稍后会更详细地介绍 AES 和 ChaCha20 算法,并给出代码示例。
对称加密在线演示
为了更好地理解对称加密背后的思路,可以使用在线对称加密工具,通过示例秘密密钥或密码,对示例消息进行加密和解密。你可以试用这个网站:https://aesencryption.net。

它演示了如何使用具有特定设置的 AES 密码(更准确地说是 AES-128-CBC)和某种基于密码的密钥派生函数,对消息进行加密和解密。在上面的示例中,如果使用密码“p@ss”加密文本“secret msg”,输出会是经过 base64 编码的二进制数据“jVJwOBmH+qMqHdg22KwMyg==”。使用相同的秘密密钥解密后,会恢复原始文本“secret msg”。
请注意,上述密文取决于许多算法参数和设置。因此,如果在另一个“AES 在线示例”网站上加密相同内容,结果很可能不同。
还要注意,上述网站采用了不良实践、旧算法和薄弱的密码设置,不要照搬其代码示例。
公钥密码学的概念
在介绍非对称密钥加密方案和算法之前,首先需要理解公钥密码学(非对称密码学)的概念。
公钥密码学使用不同的密钥来加密和解密数据,或对消息进行签名和验证。密钥总是以公钥与私钥组成的密钥对出现。非对称密码学处理使用公钥和私钥对消息进行加密与解密、为消息签名、验证签名,以及安全地交换密钥等问题。
现代密码学广泛使用 RSA(Rivest–Shamir–Adleman)、ECC(椭圆曲线密码学)、Diffie-Hellman、ECDH、ECDSA 和 EdDSA 等常见公钥密码系统(非对称密码算法)。本书将通过代码示例实际演示其中大多数算法。
公钥加密与解密
非对称加密方案使用一对在密码学上相关的公钥和私钥:用公钥加密数据,再用私钥将加密数据解密回原始形式。由公钥加密的数据,需要由对应的私钥解密:

加密产生的数据称为“密文”。密文是一段人类无法读取的二进制序列,而且按照设计,没有解密密钥就无法将其解密。

请注意,上图经过了高度简化,并未完整呈现非对称加密和解密过程。通常,公钥密码系统只能加密长度有限的消息,速度也比对称密码慢。要加密较长的消息,例如 PDF 文档,通常会使用公钥加密方案,也称混合加密方案,按如下方式组合对称加密和非对称加密:
- 加密时,生成一个随机对称密钥
sk,使用sk对消息执行对称加密,再使用接收者的公钥对sk执行非对称加密。 - 解密时,先使用接收者的私钥对
sk密钥执行非对称解密,再使用sk对密文执行对称解密。
上述过程称为密钥封装机制(KEM):封装一个经非对称加密的随机临时对称密钥,再使用对称算法加密数据。
数字签名采用与公钥加密不同的方向:使用私钥为数据签名,再使用公钥验证签名。这样,某人只需公开相应的公钥,就能证明自己拥有某个私钥。应注意,签名并不是“使用私钥加密数据”。
签名:非对称签名与验证
在数字签名场景中,先使用私钥为消息签名以生成数字签名,随后再使用对应的公钥验证该签名。

稍后会更详细地解释数字签名。简而言之,可以使用某个私钥对消息进行签名,之后再使用对应的公钥验证所得签名。一条已签名消息在签名后不能被篡改。消息签名能够证明某条消息,例如区块链交易,是由某个公钥的所有者创建。数字签名为消息提供身份认证、完整性和不可否认性。
数字签名广泛用于金融行业,以授权付款。在操作系统中,操作系统组件和设备驱动程序通常带有数字签名,以防不安全代码、木马或病毒被注入操作系统。在区块链系统中,交易通常由某个区块链地址的所有者签名;该地址对应某个公钥,而公钥又有相应的私钥。因此,已签名的区块链交易包含签署者身份的证明:数学上能够保证签名由某个区块链地址的持有者创建,并且交易在签名后没有被修改。这非常适合数字支付以及文档和合同的数字签署场景。
密钥对
公钥密码学使用一对密钥:公钥加私钥。这两个密钥在数学上相互关联,并作为一对共同使用。
在某些公钥密码系统中,例如椭圆曲线密码学(ECC),可以由私钥计算出公钥。在另一些密码系统中,例如 RSA,公钥和私钥会同时生成,但不能直接由其中一个计算出另一个。
通常,公钥与私钥组成的密钥对会在安全环境中随机生成,例如硬件钱包。公钥会被公开,而私钥则安全地存储在加密货币钱包中,并受到密码或多因素身份验证的保护。
以下是基于 secp256k1 曲线的 256 位私钥及其对应的 256 位公钥示例:
privKey: 648fc1fa828c7f185d825c04a5b21af9e473b867eeee1acea4dbab938433e158
pubKey: 02c324648931b89e3e8a0fc42c96e8e3be2e42812986573a40d46563bceaf75110
私钥
消息解密和签名通过私钥完成。所有者始终会像保护密码一样对私钥保密。在服务器基础设施中,私钥通常保存在经过加密和保护的密钥库中。在区块链系统中,私钥通常保存在称为“加密货币钱包”的专用软件、硬件应用或设备中,这些钱包会安全存储一组私钥。
256 位私钥示例:
648fc1fa828c7f185d825c04a5b21af9e473b867eeee1acea4dbab938433e158
公钥
消息加密和签名验证通过公钥完成。公钥按照设计就是公开信息,并非秘密。从对应的公钥计算出私钥在数学上不可行。
在许多系统中,公钥被封装在数字证书中,证书会把某个身份,例如个人或互联网域名,与某个公钥绑定。在区块链系统中,公钥通常作为区块链交易的一部分发布,以帮助识别每笔交易的签名者。在 PGP 和 SSH 等系统中,经过用户手动验证后,公钥会从服务器下载一次并保存,供日后使用。
256 位公钥示例:
02c324648931b89e3e8a0fc42c96e8e3be2e42812986573a40d46563bceaf75110
在大多数区块链系统中,区块链地址通过哈希和其他变换从公钥派生。因此,如果拥有某人的公钥,通常也可以认为拥有其区块链地址。
某个公钥可以与某个个人或组织相关联,也可以匿名使用。除非拥有额外证明,例如数字证书,否则永远无法知道与某个公钥对应的私钥究竟归谁所有。
常见公钥密码系统
公钥密码系统提供数学框架和算法,以密码学安全的方式生成公钥与私钥组成的密钥对,对消息进行签名、验证、加密和解密,以及交换密钥。
著名的公钥密码系统包括 RSA)、ECC 和 ElGamal。许多密码算法都基于这些密码系统提供的原语,例如 RSA 签名、RSA 加密与解密、ECDH 密钥交换,以及 ECDSA 和 EdDSA 签名。
RSA 密码系统
RSA 公钥密码系统)基于模幂运算(对一个数求幂后取模)的数学原理和一些额外假设,同时依赖整数分解问题的计算困难性。稍后将结合示例详细讨论它。
ECC 密码系统
椭圆曲线密码学(ECC)公钥密码系统基于有限域上椭圆曲线的代数结构,以及椭圆曲线离散对数问题(ECDLP)的困难性。ECC 通常与 ECDSA 算法(椭圆曲线数字签名算法)配合使用。稍后将结合示例详细讨论 ECC 和 ECDSA。
通常推荐使用 ECC
与 RSA 相比,ECC 使用的密钥、密文和签名都更短,因此大多数应用都推荐使用 ECC。数学上已经证明,3072 位 RSA 密钥与 256 位 ECC 密钥具有相近的密码学强度。ECC 的密钥生成速度也明显快于 RSA。
基于上述原因,大多数区块链网络,例如 Bitcoin 和 Ethereum,都使用基于椭圆曲线的密码学(ECC)来保护交易。
请注意,RSA 和 ECC 密码系统都不具备抗量子能力。这意味着,如果有人拥有足够强大的量子计算机,就可以在几秒钟内由给定的公钥推导出私钥。
实践中的非对称加密
非对称加密只适用于较短的消息,消息长度受公钥和私钥长度限制。要加密较长的消息,可以使用密钥封装机制或其他技术:先用非对称方式加密一个随机秘密密钥,再用该密钥以对称方式加密较长消息。在实践中,现代非对称加密方案会将对称加密算法与公钥密码系统、密钥封装和消息认证结合使用。
常见的非对称加密方案包括:RSA-OAEP(基于 RSA 和 OAEP 填充)、RSAES-PKCS1-v1_5(基于 RSA 和 PKCS#1 v1.5 填充)、DLIES(基于离散对数和对称加密),以及 ECIES(基于椭圆曲线密码学和对称加密)。
非对称加密在线演示
为了更好地理解非对称加密背后的思路,可以使用在线公钥加密工具,通过示例 RSA 私钥和公钥,对示例消息进行加密与解密。你可以试用这个网站:http://travistidwell.com/jsencrypt/demo/。

在这个在线演示中,可以生成 RSA 公钥与私钥组成的密钥对,并加密或解密文本消息。请注意,消息长度受密钥长度限制,因此无法加密长文本,尝试这样做会得到错误。该网站内部使用 RFC3447 中规定的 RSAES-PKCS1-v1_5 公钥加密方案。
接下来的几个章节将详细讨论 RSA 和 ECC 密码系统。现在最重要的是理解:对称密码系统和非对称密码系统的工作方式不同,适用于不同场景。