敏感数据的加密是数据安全的重要方面,尤其是对于手机号和身份证号这类个人信息。如果这些信息以明文形式存储在数据库中,一旦数据库被黑客攻破,大量的个人信息就会泄露,可能被用于不法活动。数据加密可以在不同的层面上实现,例如应用层、数据库层或传输层。这里,我们将讨论在业务中如何加密敏感数据。
对称加密 vs 非对称加密
对于敏感信息的存储,我们考虑使用加密算法。通常有两种加密算法可供选择:对称加密和非对称加密。对称加密使用相同的密钥进行加密和解密,而非对称加密使用一对公私钥。对于服务器端加密和解密敏感数据的场景,对称加密通常是更优的选择,因为它比非对称加密更快,而且我们不需要考虑密钥的安全传输问题。
AES加密
AES(高级加密标准)是一种广泛使用的对称加密算法,提供了强大的安全性和较高的性能。我们推荐使用AES-256-GCM模式,它不仅提供加密功能,还有验证加密完整性的能力,确保数据的安全性和完整性。
Java中使用AES加密敏感数据
以下是一个简单的例子,展示了如何在Java中使用AES算法加密和解密数据:
- 生成密钥:首先,需要生成一个密钥。在实际应用中,应该安全地存储这个密钥,不应硬编码在代码中。
- 加密数据:使用密钥加密敏感信息。
- 解密数据:当需要访问原始数据时,使用相同的密钥进行解密。
Java
public class AESGCMEncryptionExample {
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
private static final int AES_KEY_SIZE = 256; // AES-256
private static final int GCM_NONCE_LENGTH = 12; // 12 bytes IV
private static final int GCM_TAG_LENGTH = 16; // 128 bits authentication tag
public static void main(String[] args) throws Exception {
// 生成AES密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(AES_KEY_SIZE);
SecretKey secretKey = keyGenerator.generateKey();
// 生成GCM的IV
byte[] iv = new byte[GCM_NONCE_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
// 加密
String sensitiveData = "Sensitive Data to Encrypt";
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec);
byte[] encryptedBytes = cipher.doFinal(sensitiveData.getBytes());
String encryptedData = Base64.getEncoder().encodeToString(encryptedBytes);
System.out.println("Encrypted data: " + encryptedData);
// 解密
cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
String decryptedData = new String(decryptedBytes);
System.out.println("Decrypted data: " + decryptedData);
}
}
在这个示例中,我们使用了AES-256-GCM模式进行加密和解密。请注意,IV应该对每次加密都是唯一的,并且在解密时需要相同的IV和密钥。因此,实际应用中,通常需要将IV与加密数据一起存储,但要确保IV不被加密。
此外,由于使用了GCM模式,无需手动添加消息认证码(MAC)或数字签名来确保数据完整性,因为GCM模式已经提供了这种保护。不过,需要注意的是,重复使用相同的IV和密钥对不同的数据进行加密会严重损害安全性,因此每次加密时使用新的随机IV是非常重要的。
加密服务如何设计?
- 加密服务设计:设计一个加密服务,用于加密和解密数据。每次加密都应生成新的随机密钥和初始化向量,并将它们存储在安全的地方。
- 数据库存储:数据库中存储脱敏后的明文、密文和加密ID。加密ID用于在需要解密时检索正确的密钥和初始化向量。
- 使用AAD:附加认证数据(AAD)用于加密过程,增加了一个额外的安全层,即使密文和加密密钥被泄露,没有AAD也无法解密数据。
下面是一个简化的数据加密服务架构图,展示了如何处理和存储敏感数据(如姓名和身份证号)的流程。这个架构包括了应用服务器、加密服务、数据库和客户端之间的交互:
- 客户端(用户) :用户通过客户端应用提交需要加密的敏感数据(如姓名和身份证号)。
- 应用服务 :
- 接收来自客户端的敏感数据。
- 将数据发送到加密服务进行加密。
- 接收加密数据和加密ID,并将它们存储在数据库中。
- 对于需要解密的请求,应用服务器将从数据库获取加密数据和加密ID,并请求加密服务进行解密。
- KMS服务 :
- 负责敏感数据的加密和解密操作。
- 每次加密时生成新的密钥和初始化向量(IV),并将它们与加密ID一起存储在kms中。
- 使用加密ID检索相应的密钥和IV进行解密。
- 业务数据库 :
- 存储脱敏的数据和加密数据。
- 保存与加密数据相关的加密ID,但不存储加密密钥或IV。
- 密钥数据库 :
- 存储密钥和初始化向量(IV),每个加密操作都有唯一的密钥和IV。
- 加密ID用于关联加密数据和其对应的密钥及IV。
安全注意事项
- 密钥和IV不应与加密数据一起存储在同一个数据库中,以防止数据库泄露时暴露所有必要的解密信息。
- 加密服务应该独立于应用服务器,以减少应用服务器被攻破时对加密系统的潜在影响。
- 所有敏感数据的传输应通过安全通道进行,例如使用HTTPS。
- 定期轮换密钥,并确保旧密钥的安全废弃,以减少长期使用同一密钥可能带来的风险。