Appearance
常见七种加密算法及实现
看在前面
前言:数字签名与加解密
数字签名:通过"可鉴别的数字信息"验证身份,包含签名和验证两种互补的运算。发送者持有私钥(不可泄露),接收者持有对应的公钥验证。数字签名能唯一证明发送方身份,可以防止中间人攻击和 CSRF 跨域身份伪造。它广泛应用于设备认证、用户认证、第三方认证体系。
加密/解密:加密是将明文按某种算法处理成不可读的"密文",防止数据被窃取阅读。解密是加密的逆过程,将密文还原为原始数据。
对称加密 vs 非对称加密:
对称加密(共享密钥加密):加解密使用同一把密钥,双方必须事先约定好密钥。代表算法:DES、3DES、AES。
非对称加密(公开密钥加密):使用公钥/私钥一对密钥,公钥加密的数据只能用私钥解密,反之亦然。代表算法:RSA、DSA。
另外还有无需密钥的散列(哈希)算法,例如 SHA1、MD5。严格来说它们不是加密算法,而是摘要算法。
MD5
哈希/摘要算法:任意长度的输入,输出 128 位信息摘要(32 个十六进制字符)。具有不可逆性,主要用于防止信息篡改。
java
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] digest = md5.digest(plainText.getBytes());SHA1
安全散列算法:对长度小于 2^64 位的消息产生 160 位摘要,不可逆,安全性强于 MD5。主要用于文件完整性校验和数字签名。
java
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
byte[] digest = sha1.digest(plainText.getBytes());HMAC
散列消息鉴别码(Hash-based Message Authentication Code):以一个密钥和一个消息作为输入,生成一个消息摘要。收发双方共享密钥 key,第三方没有 key 就无法计算出正确的散列值,因此可防止消息篡改。
实现时可以选择 HmacMD5、HmacSHA1、HmacSHA256 这类变体:
java
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"));
byte[] rawHmac = mac.doFinal(data.getBytes());注意:Mac 实例不是线程安全的,多线程场景建议用 ThreadLocal 为每个线程缓存一个实例,避免加锁。
DES / 3DES / AES(对称加密,可逆)
DES:数据加密标准,64 位分组、56 位密钥,加解密用同一算法。因密钥太短,穷举破译理论上只需 2^56 次运算,已不安全。
3DES:用 3 把不同的密钥对数据做 3 次 DES 加密,强度更高但速度慢。
AES:高级加密标准,分组固定 128 位,密钥支持 128/192/256 位(JDK 默认不支持 AES256,需安装 JCE 无限强度权限补丁)。安全性、效率、灵活性均优于 DES,是美国联邦政府采用的区块加密标准。
Java 实现示例(AES/CFB/NoPadding,密钥不足 16 字节会抛异常,IV 可由密钥的 MD5 派生):
java
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(key.getBytes()));
SecretKey secretKey = kgen.generateKey();
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
IvParameterSpec iv = new IvParameterSpec(
md5DigestOf(secretKey.getEncoded())); // 由密钥摘要生成 IV
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] encrypted = cipher.doFinal(plainText.getBytes());RSA(非对称加密)
目前最有影响力的公钥加密算法,也是第一个能同时用于加密和数字签名的算法。原理基于大数分解难题:两个大素数相乘很容易,但对其乘积做因式分解极其困难。因此乘积(部分)可以作为公钥公开。
Java 生成密钥对并加解密(借助 BouncyCastle 提供者):
java
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
// RSA 单次加密块长度受密钥长度限制,长数据需分块处理签名验证使用 Signature.getInstance("SHA1WithRSA"),用私钥签名、公钥验签。
ECC(非对称加密)
椭圆曲线加密算法(Elliptic Curve Cryptography):主要优势是用更小的密钥长度达到与 RSA 相当甚至更高的安全级别。例如 160 位 ECC ≈ 1024 位 RSA 的安全强度。缺点是加解密耗时更长、CPU 消耗较大。
Java 实现同样依赖 BouncyCastle:
java
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("EC", "BC");
keyPairGen.initialize(new ECGenParameterSpec("secp256k1"));
// 加密用 ECIES:Cipher.getInstance("ECIES", "BC")
// 签名用 ECDSA:Signature.getInstance("SHA1withECDSA", "BC")算法对比与选型
| 类别 | 对比项 | 结论 |
|---|---|---|
| 散列 | SHA1 vs MD5 | SHA1 安全性高但更慢;MD5 安全性中等但更快 |
| 对称 | DES/3DES/AES | AES 速度快、安全性高、资源消耗低;3DES 慢且消耗高;DES 密钥太短最弱 |
| 非对称 | RSA vs ECC | 成熟度和安全性都高;RSA 速度/消耗中等;ECC 密钥短但慢、消耗高 |
选型建议:
对称算法:加解密速度快(比非对称快百倍以上),适合大数据量加解密。但密钥管理困难,需要安全地把同一把密钥分发给通信双方,适合内部系统。
非对称算法:密钥容易管理(公钥可公开)、安全性高,但速度慢,适合小数据量加解密或数字签名场景。
实践中的混合加密:用非对称算法协商/加密一把对称会话密钥,再用对称算法加密业务数据。HTTPS/TLS 正是这么做的。防篡改和身份认证则叠加 HMAC 或数字签名。
小结
本文介绍了数字签名、加解密、对称/非对称加密的基本概念,以及 MD5、SHA1、HMAC、DES/3DES、AES、RSA、ECC 七类算法。内容覆盖原理、Java 实现要点与横向对比。核心记忆点:摘要算法不可逆、对称快但管钥难、非对称慢但管钥易、真实系统往往混合使用。
内容来源:原文 · 2026-10 整理回填。