Skip to content

常见七种加密算法及实现 ​

看在前面 ​

前言:数字签名与加解密 ​

数字签名:通过"可鉴别的数字信息"验证身份,包含签名和验证两种互补的运算。发送者持有私钥(不可泄露),接收者持有对应的公钥验证。数字签名能唯一证明发送方身份,可以防止中间人攻击和 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 MD5SHA1 安全性高但更慢;MD5 安全性中等但更快
对称DES/3DES/AESAES 速度快、安全性高、资源消耗低;3DES 慢且消耗高;DES 密钥太短最弱
非对称RSA vs ECC成熟度和安全性都高;RSA 速度/消耗中等;ECC 密钥短但慢、消耗高

选型建议:

  • 对称算法:加解密速度快(比非对称快百倍以上),适合大数据量加解密。但密钥管理困难,需要安全地把同一把密钥分发给通信双方,适合内部系统。

  • 非对称算法:密钥容易管理(公钥可公开)、安全性高,但速度慢,适合小数据量加解密或数字签名场景。

  • 实践中的混合加密:用非对称算法协商/加密一把对称会话密钥,再用对称算法加密业务数据。HTTPS/TLS 正是这么做的。防篡改和身份认证则叠加 HMAC 或数字签名。

小结 ​

本文介绍了数字签名、加解密、对称/非对称加密的基本概念,以及 MD5、SHA1、HMAC、DES/3DES、AES、RSA、ECC 七类算法。内容覆盖原理、Java 实现要点与横向对比。核心记忆点:摘要算法不可逆、对称快但管钥难、非对称慢但管钥易、真实系统往往混合使用。

内容来源:原文 · 2026-10 整理回填。