【架构实战】数据加密:敏感数据的存储与传输保护

📅 2026/7/16 18:57:28
【架构实战】数据加密:敏感数据的存储与传输保护
数据加密敏感数据的存储与传输保护一、泄露后的代价2025年某医疗平台数据泄露30万条患者记录被拖走包含姓名、身份证号、手机号、病历——全部明文存储。后果罚款500万用户信任崩塌股价跌了20%。事后审查发现平台对加密的理解停留在HTTPS就够了——传输加密了但数据库里的数据是裸的。攻击者只要能进数据库所有数据一览无余。加密的正确认知HTTPS保护传输过程不保护存储数据数据库加密保护静态数据不保护传输过程两层都要做缺一不可二、加密体系全景2.1 加密类型与适用场景┌──────────────────────────────────────────────────┐ │ 数据加密体系 │ ├────────────────┬─────────────────────────────────┤ │ 传输加密 │ HTTPS/TLS客户端到服务端 │ │ │ mTLS服务间通信 │ │ │ SSH运维通道 │ ├────────────────┬─────────────────────────────────┤ │ 存储加密 │ 字段级加密身份证、密码等 │ │ │ 文件级加密附件、日志等 │ │ │ 磁盘级加密TDE/云加密 │ ├────────────────┬─────────────────────────────────┤ │ 密钥管理 │ 密钥生成、存储、轮换、销毁 │ │ │ KMS密钥管理服务 │ │ │ HSM硬件安全模块 │ └────────────────┴─────────────────────────────────┘2.2 对称加密 vs 非对称加密维度对称加密AES非对称加密RSA/ECC密钥加密解密用同一密钥公钥加密私钥解密速度极快硬件加速慢数学运算密集适用大量数据加密密钥交换、数字签名密钥分发需安全通道传密钥公钥可公开分发安全等级AES-256足够安全RSA-2048ECC-P256实战组合非对称加密交换密钥对称加密加密数据——这就是TLS和混合加密的核心思路。2.3 加密算法选择推荐算法 - 对称加密AES-256-GCM认证加密防篡改 - 非对称加密RSA-2048用于签名ECC-P256用于密钥交换 - 哈希SHA-256/SHA-512 - 密码哈希bcrypt/Argon2带盐、可调成本 - HMACSHA-256 HMAC消息认证码 不推荐/已淘汰 - DES/3DES密钥太短 - MD5/SHA-1已被攻破 - RC4存在已知弱点 - ECB模式相同明文产生相同密文不安全三、传输加密实践3.1 HTTPS/TLS配置# Nginx HTTPS安全配置 server { listen 443 ssl http2; # 证书配置 ssl_certificate /etc/ssl/certs/server.crt; ssl_certificate_key /etc/ssl/private/server.key; # TLS版本仅允许1.2和1.3 ssl_protocols TLSv1.2 TLSv1.3; # 密码套件优先ECDHE支持前向保密 ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; # HSTS强制HTTPS add_header Strict-Transport-Security max-age31536000; includeSubDomains always; # OCSP Stapling在线证书状态检查 ssl_stapling on; ssl_stapling_verify on; # 会话恢复 ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; }3.2 服务间mTLS# Istio mTLS配置服务间加密通信apiVersion:security.istio.io/v1beta1kind:PeerAuthenticationmetadata:name:defaultnamespace:productionspec:mtls:mode:STRICT# 严格模式所有通信必须加密mTLS证书管理// 服务间证书自动轮换ServicepublicclassCertificateRotationService{Scheduled(cron0 0 2 * * ?)// 每天凌晨2点检查publicvoidcheckAndRotate(){ListServiceCertificatecertscertRepo.findAll();for(ServiceCertificatecert:certs){// 证书7天内过期则提前轮换if(cert.getExpiry().isBefore(LocalDateTime.now().plusDays(7))){rotateCertificate(cert);}}}privatevoidrotateCertificate(ServiceCertificateoldCert){// 1. 向Istio/CA申请新证书CertificateRequestreqCertificateRequest.builder().serviceId(oldCert.getServiceId()).validityDays(90).build();ServiceCertificatenewCertcaClient.issueCertificate(req);// 2. 灰度部署新证书双证书并存certDeployer.deployDualCert(oldCert,newCert);// 3. 确认新证书生效后撤销旧证书certDeployer.confirmAndRevokeOld(oldCert);}}四、存储加密实践4.1 字段级加密对身份证号、手机号等敏感字段单独加密存储ServicepublicclassDataEncryptionService{AutowiredprivateKeyManagementServicekms;/** * 字段级加密 */publicStringencryptField(Stringplaintext,StringkeyId){// 1. 从KMS获取数据加密密钥DataKeydataKeykms.getDataKey(keyId);// 2. AES-256-GCM加密认证加密防篡改CiphercipherCipher.getInstance(AES/GCM/NoPadding);GCMParameterSpecspecnewGCMParameterSpec(128,dataKey.getIv());cipher.init(Cipher.ENCRYPT_MODE,dataKey.getSecretKey(),spec);byte[]ciphertextcipher.doFinal(plaintext.getBytes(UTF_8));// 3. 存储密文 密钥ID IV密钥ID用于解密时找对应密钥returnBase64.getEncoder().encodeToString(join(dataKey.getKeyId(),dataKey.getIv(),ciphertext));}/** * 字段级解密 */publicStringdecryptField(StringencryptedData){byte[]rawBase64.getDecoder().decode(encryptedData);// 1. 解析密钥ID、IV、密文StringkeyIdextractKeyId(raw);byte[]ivextractIv(raw);byte[]ciphertextextractCiphertext(raw);// 2. 从KMS获取对应密钥DataKeydataKeykms.getDataKey(keyId);// 3. AES-GCM解密GCM自带完整性校验CiphercipherCipher.getInstance(AES/GCM/NoPadding);GCMParameterSpecspecnewGCMParameterSpec(128,iv);cipher.init(Cipher.DECRYPT_MODE,dataKey.getSecretKey(),spec);returnnewString(cipher.doFinal(ciphertext),UTF_8);}}数据库表设计-- 用户表敏感字段加密存储CREATETABLEusers(idBIGINTPRIMARYKEY,usernameVARCHAR(50),-- 非敏感明文phone_encryptedTEXT,-- 手机号加密存储id_card_encryptedTEXT,-- 身份证号加密存储emailVARCHAR(100),-- 非敏感明文password_hashVARCHAR(100),-- 密码哈希bcryptencryption_key_idVARCHAR(50),-- 加密密钥IDcreated_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP);4.2 密码哈希存储ServicepublicclassPasswordService{// bcrypt密码哈希cost factor12publicStringhashPassword(Stringpassword){returnBCrypt.hashpw(password,BCrypt.gensalt(12));}// 密码验证publicbooleanverifyPassword(Stringpassword,Stringhash){returnBCrypt.checkpw(password,hash);}}密码哈希对比算法优势劣势推荐bcrypt自带盐可调成本因子不支持并行验证推荐cost10-12Argon2抗GPU/ASIC内存硬实现复杂推荐密码比赛冠军PBKDF2标准化广泛支持不抗GPU攻击可用MD5/SHA快无盐、无成本因子、快不安全禁止使用4.3 信封加密模式信封加密Envelope Encryption是云厂商推荐的加密模式数据密钥加密数据主密钥加密数据密钥。【信封加密流程】 加密 1. KMS生成数据密钥DataKey→ 明文DK 密文DK 2. 明文DK加密数据 → 密文数据 3. 密文DK 密文数据 → 一起存储 4. 明文DK立即销毁不在内存中持久化 解密 1. 取出密文DK → 请求KMS解密 → 得到明文DK 2. 明文DK解密密文数据 → 明文数据 3. 明文DK使用后立即销毁ServicepublicclassEnvelopeEncryptionService{AutowiredprivateKmsClientkmsClient;publicEncryptedDataencrypt(Stringplaintext){// 1. 请求KMS生成数据密钥GenerateDataKeyResultresultkmsClient.generateDataKey(alias/main-key,AES_256);// 2. 用明文数据密钥加密数据StringciphertextaesEncrypt(plaintext,result.getPlaintextDataKey());// 3. 销毁明文密钥只保留密文密钥result.destroyPlaintextKey();returnEncryptedData.builder().encryptedDataKey(result.getEncryptedDataKey())// 密文密钥.ciphertext(ciphertext)// 密文数据.build();}publicStringdecrypt(EncryptedDataencrypted){// 1. 请求KMS解密数据密钥StringplaintextKeykmsClient.decryptDataKey(encrypted.getEncryptedDataKey());// 2. 用明文密钥解密数据StringplaintextaesDecrypt(encrypted.getCiphertext(),plaintextKey);// 3. 使用后立即销毁明文密钥destroyKey(plaintextKey);returnplaintext;}}五、密钥管理5.1 密钥生命周期密钥生命周期 创建 → 分发 → 存储 → 使用 → 轮换 → 撤销 → 销毁 关键安全措施 - 创建KMS/HSM生成禁止人工指定密钥 - 存储密钥绝不与数据同库存储 - 使用信封加密模式数据密钥用后销毁 - 轮换主密钥每年轮换数据密钥每次加密新生成 - 撤销密钥泄露时立即撤销 - 销毁密钥退役后安全销毁不可恢复5.2 密钥轮换ServicepublicclassKeyRotationService{// 主密钥自动轮换每年Scheduled(cron0 0 0 1 1 ?)// 每年1月1日publicvoidrotateMasterKey(){StringoldKeyIdkmsClient.getCurrentMasterKeyId();// 1. 创建新主密钥StringnewKeyIdkmsClient.createMasterKey(AES_256);// 2. 设置新密钥为活跃密钥kmsClient.setActiveKey(newKeyId);// 3. 旧密钥标记为仅解密不再用于加密新数据kmsClient.setKeyState(oldKeyId,KeyState.DECRYPT_ONLY);// 4. 30天后旧密钥数据全部重新加密到新密钥scheduleReEncryption(oldKeyId,newKeyId,30);}// 批量重新加密数据publicvoidreEncryptData(StringoldKeyId,StringnewKeyId){// 查询所有使用旧密钥加密的数据ListEncryptedRecordrecordsdataRepo.findByKeyId(oldKeyId);for(EncryptedRecordrecord:records){// 用旧密钥解密 → 用新密钥重新加密StringplaintextenvelopeService.decrypt(record.getEncryptedData());EncryptedDatanewEncryptedenvelopeService.encrypt(plaintext);record.setEncryptedData(newEncrypted);record.setKeyId(newKeyId);dataRepo.save(record);}// 5. 重新加密完成后旧密钥可以安全销毁kmsClient.destroyKey(oldKeyId);}}六、踩坑实录坑点1ECB模式导致密文可推断问题使用AES-ECB加密身份证号相同身份证号产生相同密文攻击者通过密文比对可推断身份证号是否相同。解决使用AES-GCM或AES-CBCHMAC每次加密使用随机IV相同明文产生不同密文。坑点2密钥硬编码在代码中问题密钥写在配置文件或代码中代码泄露后密钥泄露。解决密钥只存在KMS/HSM中应用通过API获取密钥永不出现在代码或配置文件中。坑点3HTTPS了就安全了问题HTTPS只保护传输数据库中的数据仍为明文。解决传输加密HTTPS 存储加密字段级加密双层防护。坑点4加密后无法查询问题手机号加密后无法做模糊搜索如按号段筛选。解决方案1存储明文哈希SHA-256用于精确匹配加密原文用于还原方案2保留格式加密FPE加密后保持手机号格式可按号段筛选方案3建立加密索引表密文 → 明文哈希映射// 加密索引方案publicvoidsaveUser(Useruser){// 加密手机号StringencryptedPhoneencryptService.encryptField(user.getPhone(),phone-key);// 同时存储手机号的哈希用于搜索StringphoneHashDigestUtils.sha256Hex(user.getPhone());user.setPhoneEncrypted(encryptedPhone);user.setPhoneHash(phoneHash);// 索引字段userRepo.save(user);}// 搜索时用哈希匹配publicUserfindByPhone(Stringphone){StringphoneHashDigestUtils.sha256Hex(phone);returnuserRepo.findByPhoneHash(phoneHash);}七、选型对比方案适用场景优势劣势应用层加密高度敏感数据最灵活字段级控制开发成本高TDE透明加密数据库全量加密无需改代码DB层加密无法字段级控制云KMS云原生应用免运维自动轮换云厂商依赖自建KMS合规要求完全自主可控运维成本高HSM金融级安全硬件级密钥保护成本极高八、总结数据加密不是可选功能是安全底线。核心要点传输加密HTTPS/mTLS 存储加密字段级加密双层防护AES-256-GCM用于数据加密bcrypt/Argon2用于密码哈希信封加密模式数据密钥加密数据主密钥加密数据密钥密钥管理是加密体系的核心——密钥泄露等于加密白做密钥轮换是常态操作不是例外操作一句话总结加密两层做密钥不落地算法选主流轮换是常态。作者架构实战团队日期2026-07-16标签#数据加密 #AES #HTTPS #密钥管理 #信封加密