API接口脱敏:如何安全地处理敏感数据?

环境:SpringBoot2.6.12
API接口脱敏是一种保护敏感数据的重要方法 。它涉及到在数据传输和存储过程中,将敏感数据替换为无意义或伪装的数据 , 以防止未经授权的访问和泄露 。下面是一些关于如何安全地处理敏感数据的方法:

  1. 数据加密:使用加密算法对敏感数据进行加密,以确保即使数据在传输过程中被截获,也无法被解密 。常见的加密算法包括对称加密算法(如AES)和非对称加密算法(如RSA) 。
  2. 数据脱敏:使用数据脱敏技术,将敏感数据替换为无意义或伪装的数据 。例如 , 将真实的手机号码替换为随机生成的虚假号码 , 或将真实的姓名替换为随机生成的虚假姓名 。
  3. 访问控制:对API接口进行访问控制,只允许经过身份验证和授权的用户访问 。使用身份验证令牌(如JWT)或OAuth等协议对用户进行身份验证和授权 。
  4. 日志记录:对API接口的访问和使用情况进行详细的日志记录,以便在发生安全事件时能够迅速发现和应对 。
  5. 数据传输安全:使用HTTPS协议进行数据传输,以确保数据传输过程中的安全性 。
  6. 数据存储安全:将敏感数据存储在加密的数据库中,并使用访问控制列表(ACL)等技术对数据库进行访问控制 。
项目中开发的API接口,可能有些接口返回的字段信息不能以明文的形式传输,这时候我们该如何进行处理呢?以下给出3中方式:
数据库层面处理在SQL查询的时候进行处理,但这种效率不高,一般不会这样处理 。如下:
SELECTCONCAT(LEFT( idNo, 6), '********', RIGHT (idNo, 4)) as idNoFROMusers where id = 7;查询结果:
API接口脱敏:如何安全地处理敏感数据?

文章插图
以掩码的方式处理部分数据
数据加密处理该种方式就是将你需要处理的字段完全通过对称加密或者HASH算法进行处理 。在写入或者查询数据的时候对敏感数据进行加密/解密处理 。示例如下:
import JAVA.sql.*;public class JdbcSensitiveDataProcess {public static void main(String[] args) {try {// 连接数据库Connection conn = DataSourceUtils.getConnection() ;// 创建Statement对象Statement stmt = conn.createStatement();// 执行查询语句ResultSet rs = stmt.executeQuery("SELECT id, name, encrypted_data FROM t_xxx");// 遍历结果集while (rs.next()) {int id = rs.getInt("id");String name = rs.getString("name");String encryptedData = rs.getString("encrypted_data");// 对加密数据进行解密处理String decryptedData = decryptData(encryptedData);// 输出解密后的数据System.out.println("ID: " + id + ", Name: " + name + ", Decrypted Data: " + decryptedData);}} catch (Exception e) {e.printStackTrace();} finally {// 关闭数据库相关资源}}// 解密数据的方法,这里只是示例,实际需要根据具体的加密算法来实现private static String decryptData(String encryptedData) {// 解密逻辑...// Cipher cipher = Cipher.getInsance(...) ;return decryptedData;}}JSON序列化时处理API接口在生成JSON字符串的时候(序列化时)将敏感信息进行掩码处理或者加密处理,接下来将详细介绍第三种方式"JSON序列化时处理" 。
JSON序列化处理脱敏使用jackson时在对对象序列化时进行敏感字段的处理,为了简单我们通过自定义注解的方式来实现该功能 。
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)// 该注解必须,不然jackson不会识别该注解@JacksonAnnotationsInside// 指定我们需要序列化字段的实现@JsonSerialize(using = SensitiveSerializer.class)public @interface Sensitive {/*** 正则表达式* @return*/String pattern() default "" ;/*** 正则表达式的第几个分组;该分组将被替换为掩码mask* @return*/int group() default 0 ;/*** 掩码* @return*/String mask() default "*" ;public interface Pattern {/**身份证*/String ID = "(\w{5})(\w+)(\w{3})" ;/**电话*/String PHONE = "(\w){3}(\w+)(\w{2})" ;/**私密*/String KEY = "(\w+)" ;}}上面的注释类都有详细的说明,不再做过多的说明 。
自定义序列化实现public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {private Sensitive sensitive ;@Overridepublic void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {String val = value ;if (sensitive != null) {String pattern = sensitive.pattern() ;int groupIndex = sensitive.group() ;String mask = sensitive.mask() ;if (pattern.length() > 0) {Pattern pa = Pattern.compile(pattern) ;Matcher matcher = pa.matcher(value) ;if (matcher.matches()) {String group = matcher.group(groupIndex) ;if (mask.length() > 0 && group.length() > 0) {val = val.replace(group, String.join("", Collections.nCopies(group.length(), mask))) ;}}}}gen.writeObject(val) ;}@Overridepublic JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)throws JsonMAppingException {sensitive = property.getAnnotation(Sensitive.class) ;return this ;}}


推荐阅读