Java存储安全流程规整

wen java案例 25

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安全配置:

Java存储安全流程规整

@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应用中数据存储安全的主要方面,建议在项目开发过程中严格执行,并通过定期的安全审计确保持续合规。

抱歉,评论功能暂时关闭!