概述
本文档提供各种加密和签名算法的性能对比数据和分析,帮助选择最适合的算法。
目录
对称加密算法性能
性能对比表
| 算法 | 密钥长度 | 加密速度 (MB/s) | 解密速度 (MB/s) | 内存占用 | 硬件加速 | 推荐度 |
|---|---|---|---|---|---|---|
| AES-256-GCM | 256位 | 1000-3000 | 1000-3000 | 低 | ✓ | ⭐⭐⭐⭐⭐ |
| AES-128-GCM | 128位 | 1200-3500 | 1200-3500 | 低 | ✓ | ⭐⭐⭐⭐⭐ |
| ChaCha20-Poly1305 | 256位 | 800-2500 | 800-2500 | 低 | ✗ | ⭐⭐⭐⭐⭐ |
| AES-256-CBC | 256位 | 800-2000 | 800-2000 | 低 | ✓ | ⭐⭐⭐⭐ |
| SM4 | 128位 | 600-1500 | 600-1500 | 低 | 部分 | ⭐⭐⭐⭐ |
| Blowfish | 128-448位 | 200-600 | 200-600 | 中 | ✗ | ⭐⭐⭐ |
| 3DES | 168位 | 50-150 | 50-150 | 低 | 部分 | ⭐⭐ |
注: 速度取决于CPU和实现,硬件加速时AES性能显著提升。
性能测试代码
public class EncryptionPerformanceTest {
public static void benchmark(String algorithm, int dataSizeMB) throws Exception {
// 生成测试数据
byte[] data = new byte[dataSizeMB * 1024 * 1024];
new SecureRandom().nextBytes(data);
// 生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm.split("/")[0]);
keyGen.init(256);
SecretKey key = keyGen.generateKey();
// 初始化加密器
Cipher cipher = Cipher.getInstance(algorithm);
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
// 加密测试
long start = System.nanoTime();
cipher.doFinal(data);
long encryptTime = System.nanoTime() - start;
double encryptSpeed = (dataSizeMB * 1024.0 * 1024.0) / (encryptTime / 1e9);
System.out.println(algorithm + " 加密: " +
String.format("%.2f", encryptSpeed) + " MB/s");
}
public static void main(String[] args) throws Exception {
String[] algorithms = {
"AES/GCM/NoPadding",
"AES/CBC/PKCS5Padding",
"ChaCha20-Poly1305"
};
for (String alg : algorithms) {
benchmark(alg, 100); // 100MB数据
}
}
}
性能分析
AES优势:
- 硬件加速广泛支持(AES-NI指令集)
- 现代CPU性能优异
- 内存占用小
ChaCha20优势:
- 软件实现性能好
- 无硬件依赖
- 移动设备友好
选择建议:
- 有硬件加速:AES-256-GCM
- 无硬件加速:ChaCha20-Poly1305
- 移动设备:ChaCha20-Poly1305
非对称加密算法性能
性能对比表
| 算法 | 密钥长度 | 密钥生成 (ms) | 加密速度 (ops/s) | 解密速度 (ops/s) | 签名速度 (ops/s) | 验证速度 (ops/s) |
|---|---|---|---|---|---|---|
| ECC P-256 | 256位 | 1-5 | 500-2000 | 500-2000 | 2000-5000 | 2000-5000 |
| ECC P-384 | 384位 | 2-8 | 300-1200 | 300-1200 | 1500-3000 | 1500-3000 |
| Ed25519 | 256位 | 1-3 | 2000-5000 | 2000-5000 | 3000-8000 | 3000-8000 |
| RSA-2048 | 2048位 | 50-200 | 100-500 | 100-500 | 200-800 | 2000-5000 |
| RSA-3072 | 3072位 | 100-400 | 50-200 | 50-200 | 100-400 | 1000-3000 |
| SM2 | 256位 | 1-5 | 400-1500 | 400-1500 | 1500-4000 | 1500-4000 |
注: 非对称加密通常用于小数据(如密钥)或签名,不适合大数据加密。
性能分析
ECC优势:
- 密钥生成快(比RSA快10-100倍)
- 签名和验证快
- 密钥和签名长度小
RSA优势:
- 验证速度快(公钥指数小)
- 广泛支持
- 成熟稳定
Ed25519优势:
- 签名和验证最快
- 固定长度签名
- 现代应用推荐
选择建议
密钥交换:
- 首选:ECDH P-256
- 备选:RSA-2048(兼容性)
数字签名:
- 首选:Ed25519或ECDSA P-256
- 备选:RSA-2048(兼容性)
性能优先:
- 首选:Ed25519
- 次选:ECDSA P-256
哈希算法性能
性能对比表
| 算法 | 输出长度 | 速度 (MB/s) | CPU使用率 | 内存占用 | 硬件加速 | 推荐度 |
|---|---|---|---|---|---|---|
| SHA-256 | 256位 | 200-800 | 低 | 低 | ✓ | ⭐⭐⭐⭐⭐ |
| SHA-512 | 512位 | 300-1000 | 中 | 中 | ✓ | ⭐⭐⭐⭐ |
| SHA3-256 | 256位 | 150-500 | 中 | 中 | ✗ | ⭐⭐⭐⭐ |
| BLAKE2b | 可变 | 400-1200 | 低 | 低 | ✗ | ⭐⭐⭐⭐ |
| SM3 | 256位 | 180-600 | 低 | 低 | 部分 | ⭐⭐⭐⭐ |
| SHA-1 | 160位 | 250-900 | 低 | 低 | ✓ | ❌ |
| MD5 | 128位 | 300-1000 | 低 | 低 | ✓ | ❌ |
性能测试
public class HashPerformanceTest {
public static void benchmark(String algorithm, int dataSizeMB) throws Exception {
byte[] data = new byte[dataSizeMB * 1024 * 1024];
new SecureRandom().nextBytes(data);
MessageDigest digest = MessageDigest.getInstance(algorithm);
long start = System.nanoTime();
digest.digest(data);
long time = System.nanoTime() - start;
double speed = (dataSizeMB * 1024.0 * 1024.0) / (time / 1e9);
System.out.println(algorithm + ": " +
String.format("%.2f", speed) + " MB/s");
}
public static void main(String[] args) throws Exception {
String[] algorithms = {"SHA-256", "SHA-512", "SHA3-256"};
for (String alg : algorithms) {
benchmark(alg, 500); // 500MB数据
}
}
}
性能分析
SHA-256:
- 性能优秀
- 硬件加速支持
- 最广泛使用
BLAKE2b:
- 软件实现最快
- 无硬件依赖
选择建议:
- 通用场景:SHA-256
- 高性能需求:BLAKE2b
- 新项目考虑:SHA3-256
数字签名算法性能
性能对比表
| 算法 | 签名速度 (ops/s) | 验证速度 (ops/s) | 签名长度 | CPU使用率 | 推荐度 |
|---|---|---|---|---|---|
| Ed25519 | 3000-8000 | 3000-8000 | 512位 | 低 | ⭐⭐⭐⭐⭐ |
| ECDSA P-256 | 2000-5000 | 2000-5000 | 512位 | 低 | ⭐⭐⭐⭐⭐ |
| ECDSA P-384 | 1500-3000 | 1500-3000 | 768位 | 中 | ⭐⭐⭐⭐ |
| RSA-2048 | 200-800 | 2000-5000 | 2048位 | 高 | ⭐⭐⭐⭐ |
| RSA-3072 | 100-400 | 1000-3000 | 3072位 | 高 | ⭐⭐⭐ |
| SM2 | 1500-4000 | 1500-4000 | 512位 | 低 | ⭐⭐⭐⭐ |
性能分析
Ed25519:
- 签名和验证都很快
- 固定长度签名
- 推荐用于新项目
ECDSA:
- 性能优于RSA
- 签名长度小
- 移动设备友好
RSA:
- 验证速度快
- 兼容性好
- 签名速度慢
性能测试
public class SignaturePerformanceTest {
public static void benchmarkSignature(String algorithm, int iterations) throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm.split("with")[1]);
if (algorithm.contains("RSA")) {
keyGen.initialize(2048);
} else {
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");
keyGen.initialize(ecSpec);
}
KeyPair keyPair = keyGen.generateKeyPair();
byte[] data = "测试数据".getBytes();
Signature signature = Signature.getInstance(algorithm);
signature.initSign(keyPair.getPrivate());
signature.update(data);
// 签名性能
long start = System.nanoTime();
for (int i = 0; i < iterations; i++) {
signature.initSign(keyPair.getPrivate());
signature.update(data);
signature.sign();
}
long signTime = System.nanoTime() - start;
byte[] signBytes = signature.sign();
// 验证性能
start = System.nanoTime();
for (int i = 0; i < iterations; i++) {
signature.initVerify(keyPair.getPublic());
signature.update(data);
signature.verify(signBytes);
}
long verifyTime = System.nanoTime() - start;
double signOps = iterations / (signTime / 1e9);
double verifyOps = iterations / (verifyTime / 1e9);
System.out.println(algorithm);
System.out.println(" 签名: " + String.format("%.0f", signOps) + " ops/s");
System.out.println(" 验证: " + String.format("%.0f", verifyOps) + " ops/s");
}
public static void main(String[] args) throws Exception {
String[] algorithms = {
"SHA256withECDSA",
"SHA256withRSA"
};
for (String alg : algorithms) {
benchmarkSignature(alg, 1000);
System.out.println();
}
}
}
消息认证码性能
性能对比表
| 算法 | 速度 (MB/s) | CPU使用率 | 输出长度 | 推荐度 |
|---|---|---|---|---|
| HMAC-SHA256 | 200-800 | 低 | 256位 | ⭐⭐⭐⭐⭐ |
| HMAC-SHA512 | 300-1000 | 中 | 512位 | ⭐⭐⭐⭐ |
| AES-CMAC | 800-2000 | 中 | 128位 | ⭐⭐⭐ |
| GMAC | 1000-3000 | 低 | 128位 | ⭐⭐⭐⭐ |
| Poly1305 | 800-2500 | 低 | 128位 | ⭐⭐⭐⭐ |
性能分析
HMAC:
- 性能取决于底层哈希函数
- SHA-256是最佳平衡
GMAC/Poly1305:
- 通常与加密结合使用
- 性能优秀
密钥派生函数性能
性能对比表
| 算法 | 配置 | 计算时间 (ms) | 内存占用 | 推荐度 |
|---|---|---|---|---|
| Argon2id | 64MB, 3 iter | 100-500 | 64MB | ⭐⭐⭐⭐⭐ |
| scrypt | N=16384, r=8 | 50-300 | ~16MB | ⭐⭐⭐⭐ |
| bcrypt | cost=12 | 100-400 | 低 | ⭐⭐⭐⭐ |
| PBKDF2 | 100000 iter | 50-200 | 低 | ⭐⭐⭐ |
注: 密钥派生函数设计为慢速,性能测试应关注"足够慢"以确保安全。
性能建议
目标计算时间:
- 交互式登录:100-500ms
- API认证:10-100ms
- 高安全需求:500-1000ms
配置调整:
- 根据硬件性能调整迭代次数/成本因子
- 定期增加参数以适应硬件发展
性能优化建议
1. 硬件加速
利用CPU指令集:
- AES-NI:AES加密加速
- SHA扩展:SHA-256/512加速
检查支持:
// 检查AES-NI支持
String[] providers = Security.getProviders();
// 某些JVM会自动使用硬件加速
2. 并行处理
适用场景:
- 大文件加密
- 批量签名验证
- 哈希计算
示例:
// 并行处理多个文件哈希
List<Path> files = getFilesToHash();
files.parallelStream()
.forEach(file -> {
String hash = hashFile(file);
// 处理结果
});
3. 缓存和预计算
策略:
- 缓存常用密钥
- 预生成密钥对
- 批量操作优化
4. 算法选择
性能优先级:
- 对称加密 > 非对称加密
- ECC > RSA
- 硬件加速算法 > 纯软件算法
5. 数据大小优化
策略:
- 大数据使用对称加密
- 小数据使用非对称加密(如密钥)
- 混合加密方案
性能测试方法论
测试环境
- 标准化硬件:相同CPU和内存
- 多次测试:取平均值
- 预热JVM:避免JIT编译影响
- 监控资源:CPU、内存使用
测试代码模板
public class PerformanceBenchmark {
// 预热
public static void warmup() {
// 执行一些操作预热JVM
}
// 基准测试
public static long benchmark(Runnable task, int iterations) {
warmup();
long totalTime = 0;
for (int i = 0; i < iterations; i++) {
long start = System.nanoTime();
task.run();
totalTime += System.nanoTime() - start;
}
return totalTime / iterations;
}
// 内存测试
public static long getMemoryUsage(Runnable task) {
Runtime runtime = Runtime.getRuntime();
long before = runtime.totalMemory() - runtime.freeMemory();
task.run();
long after = runtime.totalMemory() - runtime.freeMemory();
return after - before;
}
}
综合性能排名
加密算法(大数据)
- AES-256-GCM(硬件加速)
- ChaCha20-Poly1305(软件)
- AES-128-GCM
- AES-256-CBC
签名算法
- Ed25519
- ECDSA P-256
- RSA-2048(验证快)
哈希算法
- SHA-256(平衡)
- BLAKE2b(软件最快)
- SHA-512
总结
关键要点
- 对称加密:AES硬件加速最快,ChaCha20软件实现好
- 非对称加密:ECC性能优于RSA
- 数字签名:Ed25519最快,ECDSA次之
- 哈希算法:SHA-256是最佳平衡
- 性能优化:利用硬件加速、并行处理、算法选择
性能与安全性平衡
⚠️ 不要为了性能牺牲安全性:
- 使用已认证的安全算法
- 不要降低密钥长度
- 不要跳过安全验证步骤
✅ 在安全前提下优化性能:
- 选择性能更好的安全算法
- 利用硬件加速
- 优化实现方式