API接口脱敏:如何安全地处理敏感数据?
创始人
2025-07-03 02:41:03
0

环境:SpringBoot2.6.12

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

  1. 数据加密:使用加密算法对敏感数据进行加密,以确保即使数据在传输过程中被截获,也无法被解密。常见的加密算法包括对称加密算法(如AES)和非对称加密算法(如RSA)。
  2. 数据脱敏:使用数据脱敏技术,将敏感数据替换为无意义或伪装的数据。例如,将真实的手机号码替换为随机生成的虚假号码,或将真实的姓名替换为随机生成的虚假姓名。
  3. 访问控制:对API接口进行访问控制,只允许经过身份验证和授权的用户访问。使用身份验证令牌(如JWT)或OAuth等协议对用户进行身份验证和授权。
  4. 日志记录:对API接口的访问和使用情况进行详细的日志记录,以便在发生安全事件时能够迅速发现和应对。
  5. 数据传输安全:使用HTTPS协议进行数据传输,以确保数据传输过程中的安全性。
  6. 数据存储安全:将敏感数据存储在加密的数据库中,并使用访问控制列表(ACL)等技术对数据库进行访问控制。

项目中开发的API接口,可能有些接口返回的字段信息不能以明文的形式传输,这时候我们该如何进行处理呢?以下给出3中方式:

数据库层面处理

在SQL查询的时候进行处理,但这种效率不高,一般不会这样处理。如下:

SELECT
  CONCAT(LEFT( idNo, 6), '********', RIGHT (idNo, 4)) as idNo
FROM
  users where id = 7;

查询结果:

以掩码的方式处理部分数据以掩码的方式处理部分数据

数据加密处理

该种方式就是将你需要处理的字段完全通过对称加密或者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 implements ContextualSerializer {


  private Sensitive sensitive ;


  @Override
  public 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) ;
  }


  @Override
  public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property)
      throws JsonMappingException {
    sensitive = property.getAnnotation(Sensitive.class) ;
    return this ;
  }


}

该类实现了ContextualSerializer通过该类的回调方法能够用来读取当前字段上的注解信息。

public class Users {


  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+10")
  private Date birthday ;
  private Integer age ;
  private String name ;
  // 在需要处理的字段上加入上面定义的注解,这里我们也可以自定义表达式
  @Sensitive(pattern = Sensitive.Pattern.ID)
  private String idNo
}

运行效果:

idNo按照指定的规则进行了掩码处理idNo按照指定的规则进行了掩码处理

完毕!!!

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...