加密方案
- 对称加密:
- 原理:使用相同的密钥进行加密和解密。例如,使用AES(高级加密标准)算法,AES有不同的密钥长度,如128位、192位和256位。在高并发场景下,128位密钥通常能在安全性和性能之间取得较好平衡。
- 代码示例(Java):
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
public class AESExample {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String AES = "AES";
private static final int KEY_SIZE = 128;
public static String encrypt(String data, SecretKey secretKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
byte[] iv = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
byte[] encryptedIVAndCiphertext = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, encryptedIVAndCiphertext, 0, iv.length);
System.arraycopy(encrypted, 0, encryptedIVAndCiphertext, iv.length, encrypted.length);
return Base64.getEncoder().encodeToString(encryptedIVAndCiphertext);
}
public static String decrypt(String encryptedData, SecretKey secretKey) throws Exception {
byte[] decoded = Base64.getDecoder().decode(encryptedData);
byte[] iv = new byte[16];
System.arraycopy(decoded, 0, iv, 0, iv.length);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
byte[] encrypted = new byte[decoded.length - iv.length];
System.arraycopy(decoded, iv.length, encrypted, 0, encrypted.length);
byte[] original = cipher.doFinal(encrypted);
return new String(original, StandardCharsets.UTF_8);
}
public static SecretKey generateKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
keyGenerator.init(KEY_SIZE);
return keyGenerator.generateKey();
}
}
- 非对称加密:
- 原理:使用公钥加密,私钥解密。在JWT场景下,可以用公钥对JWT中的敏感用户行为数据部分进行加密。例如,使用RSA算法。但由于RSA加密速度相对较慢,一般不适合对整个JWT进行加密,而是对对称加密的密钥进行加密传输。
- 代码示例(Java):
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class RSAExample {
private static final String ALGORITHM = "RSA/ECB/PKCS1Padding";
private static final String RSA = "RSA";
public static String encrypt(String data, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decoded = Base64.getDecoder().decode(encryptedData);
byte[] original = cipher.doFinal(decoded);
return new String(original, StandardCharsets.UTF_8);
}
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA);
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
}
- 混合加密:
- 原理:结合对称加密和非对称加密的优点。先用对称加密算法(如AES)对JWT中的用户行为数据进行加密,然后用非对称加密算法(如RSA)对对称加密使用的密钥进行加密。在解密时,先使用私钥解密得到对称加密的密钥,再用该密钥解密用户行为数据。
性能优化策略
- 缓存:
- JWT加密密钥缓存:对于对称加密密钥或非对称加密的公钥,可以进行缓存。例如,使用Redis等缓存工具,避免每次加密都重新生成或读取密钥,减少I/O操作。
- 加密结果缓存:对于一些频繁访问且不经常变化的用户行为数据加密结果,可以进行缓存。这样在高并发情况下,相同数据的加密请求可以直接从缓存中获取结果,减轻加密计算压力。
- 硬件加速:
- 使用支持加密加速的硬件:一些服务器硬件提供了专门的加密指令集或硬件模块,如Intel的AES - NI(Advanced Encryption Standard - New Instructions)。启用这些硬件特性可以显著提高加密和解密的速度。
- 异步处理:
- 异步加密:在高并发场景下,可以将JWT的加密操作放到异步线程池中处理。这样主线程可以继续处理其他请求,不会因为加密操作的耗时而阻塞,提高系统整体的并发处理能力。例如,在Java中可以使用
ExecutorService
创建线程池来执行加密任务。
- 优化算法参数:
- 合理选择算法参数:对于对称加密算法,如AES,选择合适的密钥长度和加密模式。较短的密钥长度加密速度快但安全性相对较低,要在安全性和性能之间找到平衡点。对于非对称加密算法,如RSA,合适的密钥长度也很关键,2048位密钥在安全性和性能上相对平衡,避免选择过长的密钥导致性能大幅下降。