Java存储安全流程规整
密码存储规范
密码加密要求
// ✅ 正确:使用bcrypt进行密码哈希 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); String hashedPassword = encoder.encode(rawPassword); boolean matches = encoder.matches(rawPassword, hashedPassword); // ❌ 错误:禁止使用MD5/SHA-1/SHA-256直接存储 // ❌ 错误:禁止自定义加密算法 // ❌ 错误:禁止明文存储
加盐策略
- 使用随机生成的盐值(每个密码独立)
- 盐值长度至少16字节
- 盐值与密码哈希一同存储
敏感数据加密存储
字段级加密
// 使用AES-256-GCM进行字段加密
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class FieldEncryptionUtil {
private static final String ALGORITHM = "AES/GCM/NoPadding";
private static final int GCM_IV_LENGTH = 12;
private static final int GCM_TAG_LENGTH = 16;
private static SecretKeySpec deriveKey(String masterKey) {
// 使用PBKDF2派生密钥
// 实际生产中应从密钥管理系统获取
}
}
数据库列加密
@Column(name = "credit_card")
@ColumnTransformer(
read = "AES_DECRYPT(credit_card, :encryptionKey)",
write = "AES_ENCRYPT(?, :encryptionKey)"
)
private String creditCardNumber;
密钥管理规范
密钥存储位置
- ❌ 禁止:硬编码在代码中
- ❌ 禁止:存储在配置文件(application.properties)
- ✅ 推荐:使用密钥管理服务(AWS KMS, Azure Key Vault)
- ✅ 推荐:使用环境变量+加密存储
- ✅ 推荐:使用HashiCorp Vault
密钥轮换策略
public class KeyRotationScheduler {
@Scheduled(cron = "0 0 3 * * ?") // 每天凌晨3点
public void rotateKeys() {
// 1. 生成新密钥
// 2. 使用双缓冲区策略(旧密钥继续解密已有数据)
// 3. 渐进式重新加密(后台任务逐步重加密旧数据)
// 4. 确认所有数据迁移完成后,移除旧密钥
}
}
数据传输安全
HTTPS强制要求
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requiresChannel()
.anyRequest().requiresSecure() // 强制HTTPS
.and()
.headers()
.httpStrictTransportSecurity()
.maxAgeInSeconds(31536000)
.includeSubDomains(true)
.preload(true);
}
}
API加密传输
@RestController
@RequestMapping("/api/v1/secure")
public class SecureApiController {
@PostMapping("/encrypted-data")
public ResponseEntity<?> receiveEncryptedData(
@EncryptedRequestBody SecureData data) {
// 使用自定义注解自动解密
return ResponseEntity.ok().build();
}
}
安全存储检查清单
代码审查要点
- [ ] 所有密码使用bcrypt/scrypt/Argon2
- [ ] 敏感数据使用AES-256-GCM加密
- [ ] 密钥不硬编码,从安全服务获取
- [ ] 敏感数据缓存及时清理
- [ ] 日志中不输出敏感信息
安全扫描工具
<!-- Maven配置安全扫描插件 -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>8.0.2</version>
<configuration>
<failBuildOnCVSS>7</failBuildOnCVSS>
<formats>
<format>HTML</format>
<format>JSON</format>
</formats>
</configuration>
</plugin>
数据生命周期管理
数据分类存储
public enum DataClassification {
PUBLIC, // 公开数据
INTERNAL, // 内部数据
CONFIDENTIAL, // 机密数据
RESTRICTED // 严格受限数据
}
@Entity
public class SensitiveCustomerData {
@DataClassification(level = DataClassification.RESTRICTED)
private String ssn; // 社会保障号
@DataClassification(level = DataClassification.CONFIDENTIAL)
private String email;
}
数据清理策略
@Component
public class DataRetentionPolicy {
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点
public void purgeExpiredData() {
// 根据数据分类执行不同的保留策略
// 对敏感数据进行安全删除(覆写+删除)
// 确保数据库物理删除而非软删除
}
}
异常处理安全
异常信息过滤
@ControllerAdvice
public class SecureExceptionHandler {
@ExceptionHandler(DataAccessException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponse handleDataAccessException(DataAccessException e) {
// ❌ 禁止:返回堆栈跟踪
// ❌ 禁止:返回SQL异常详情
// ✅ 安全做法:记录日志,返回通用错误消息
logger.error("Database access error", e);
return new ErrorResponse("Internal server error", "ERR-500");
}
}
审计日志规范
敏感操作记录
@Aspect
@Component
public class SecurityAuditAspect {
@Around("@annotation(Auditable)")
public Object auditSecurityEvent(ProceedingJoinPoint pjp) {
// 记录:
// - 操作时间
// - 操作用户
// - 操作类型(查询/修改/删除)
// - 操作对象
// - 操作结果
// ❌ 禁止记录敏感数据明文
}
}
依赖安全
依赖版本管理
<!-- 使用Spring Boot BOM统一管理版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.10</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 及时更新已知漏洞的依赖 -->
<properties>
<log4j2.version>2.20.0</log4j2.version>
<jackson.version>2.14.2</jackson.version>
</properties>
定期更新策略
- 每月检查依赖漏洞报告
- 严重漏洞在24小时内修复
- 保持第三方依赖在安全版本范围内
备份安全
备份加密
# 备份时使用GPG加密 gpg --encrypt --recipient backup-team@company.com backup.sql
备份存储规范
- 备份数据加密存储
- 备份权限最小化原则
- 异地备份存储
- 定期恢复测试(至少每季度一次)
十一、安全配置示例
完整的Spring Boot安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ComprehensiveSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.and()
.and()
.headers()
.contentSecurityPolicy("script-src 'self'")
.and()
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
.and()
.featurePolicy("camera 'none'; microphone 'none'")
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint())
.accessDeniedHandler(accessDeniedHandler());
}
}
规范涵盖了Java应用中数据存储安全的主要方面,建议在项目开发过程中严格执行,并通过定期的安全审计确保持续合规。