Toolypet
返回博客
Security

加密基础 - 对称密钥 vs 非对称密钥:开发者必知必会

如果你不了解AES、RSA和HTTPS的工作原理,请阅读这篇文章。通过实际案例解释加密的核心概念。

Toolypet Team

Toolypet Team

Development Team

3 分钟阅读

加密基础:对称密钥 vs 非对称密钥

"请把这个数据加密后发送。"

当你听到这句话时,你知道具体该怎么做吗?

加密主要有两种方式。如果不知道何时使用哪种方式,你的安全设计可能会出错。


加密 vs 哈希

首先,让我们区分这两个容易混淆的概念。

加密哈希
方向双向(可解密)单向(不可逆)
目的数据保护完整性验证、密码存储
需要密钥
示例AES, RSASHA-256, bcrypt

加密:可以恢复原始数据 哈希:无法恢复原始数据

密码存储使用哈希,数据传输使用加密。


对称密钥加密

概念

使用同一个密钥进行加密和解密。

明文 + 密钥 → 加密 → 密文
密文 + 密钥 → 解密 → 明文

示例:锁和钥匙

想象一下你家的钥匙。用同一把钥匙锁门,也用同一把钥匙开门。

常见算法

算法密钥长度状态
AES-256256bit当前标准
AES-128128bit安全
3DES168bit遗留系统
DES56bit已不安全

代码示例(Node.js)

const crypto = require('crypto');

// 生成密钥(实际应用中需要安全存储)
const key = crypto.randomBytes(32);  // AES-256
const iv = crypto.randomBytes(16);   // 初始化向量

// 加密
function encrypt(text) {
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

// 解密
function decrypt(encrypted) {
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

const secret = "敏感数据";
const encrypted = encrypt(secret);
const decrypted = decrypt(encrypted);

console.log(encrypted);   // "a3f8b2c1..."
console.log(decrypted);   // "敏感数据"

优缺点

优点缺点
速度快密钥共享问题
适合大数据密钥泄露则全线崩溃
实现简单密钥管理复杂

密钥共享问题

如果A想向B发送加密消息,A必须先把密钥传给B

但是,如何安全地传递这个密钥呢?

非对称密钥加密解决了这个问题。


非对称密钥加密

概念

使用两个密钥

  • 公钥(Public Key):任何人都可以知道
  • 私钥(Private Key):绝对不能公开
公钥加密 → 只有私钥能解密
私钥签名 → 公钥验证

示例:邮箱

  • 公钥 = 邮箱投递口(任何人都可以投递信件)
  • 私钥 = 邮箱钥匙(只有主人能取出信件)

常见算法

算法用途密钥长度
RSA加密、签名2048+ bit
ECDSA签名256+ bit
Ed25519签名256bit

代码示例(Node.js RSA)

const crypto = require('crypto');

// 生成密钥对
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

// 公钥加密
function encryptWithPublic(text) {
  return crypto.publicEncrypt(publicKey, Buffer.from(text)).toString('base64');
}

// 私钥解密
function decryptWithPrivate(encrypted) {
  return crypto.privateDecrypt(privateKey, Buffer.from(encrypted, 'base64')).toString();
}

const secret = "敏感数据";
const encrypted = encryptWithPublic(secret);
const decrypted = decryptWithPrivate(encrypted);

console.log(decrypted);  // "敏感数据"

数字签名

用私钥签名后,任何人都可以用公钥验证是谁签名的

// 私钥签名
const sign = crypto.createSign('SHA256');
sign.update('消息');
const signature = sign.sign(privateKey, 'base64');

// 公钥验证
const verify = crypto.createVerify('SHA256');
verify.update('消息');
const isValid = verify.verify(publicKey, signature, 'base64');

console.log(isValid);  // true

优缺点

优点缺点
解决密钥共享问题速度慢(比对称加密慢1000倍)
支持数字签名不适合大数据
公钥可自由分发密钥长度较长

实战:两者结合使用(混合加密)

这就是HTTPS的工作原理。

流程

1. 服务器:生成RSA公钥/私钥对
2. 客户端:获取服务器的公钥
3. 客户端:生成AES会话密钥
4. 客户端:用RSA公钥加密会话密钥 → 发送给服务器
5. 服务器:用RSA私钥解密会话密钥
6. 双方:使用AES会话密钥加密通信

为什么这样做

  • RSA:仅用于密钥交换(慢但安全)
  • AES:用于实际数据加密(快速)

取两者之长。


实践检查清单

使用对称密钥(AES)时

  • 使用AES-256或AES-128
  • 每次加密生成新的IV(初始化向量)
  • 将密钥存储在环境变量或KMS中
  • 禁止使用ECB模式(使用CBC、GCM)

使用非对称密钥(RSA)时

  • 至少使用2048bit密钥
  • 绝不泄露私钥
  • 使用OAEP填充(避免PKCS#1 v1.5)
  • 制定密钥轮换策略

常见问题

Q:API密钥应该加密存储吗?

A:建议使用环境变量或密钥管理工具(AWS Secrets Manager、HashiCorp Vault)而不是加密。即使加密了,还是要管理解密密钥。

Q:在客户端加密安全吗?

A:不安全。客户端代码对所有人可见,密钥会暴露。敏感加密应该在服务器端进行。

Q:SHA-256是加密吗?

A:不是。SHA-256是哈希,无法解密。如果需要恢复数据,请使用AES等加密算法。


总结

场景使用算法
大数据加密AES-256
密钥交换RSA, ECDH
数字签名RSA, ECDSA, Ed25519
密码存储bcrypt, Argon2(哈希)
HTTPS通信混合加密(RSA + AES)

相关工具

工具用途
加密/解密AES加密
RSA密钥生成器RSA密钥对生成
哈希生成器SHA、MD5哈希
加密AESRSAHTTPS安全开发

关于作者

Toolypet Team

Toolypet Team

Development Team

The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.

Web DevelopmentCSS ToolsDeveloper ToolsSEOSecurity