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

2023年 10月 7日 32.1k 0

环境:SpringBoot2.6.12

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

  • 数据加密:使用加密算法对敏感数据进行加密,以确保即使数据在传输过程中被截获,也无法被解密。常见的加密算法包括对称加密算法(如AES)和非对称加密算法(如RSA)。
  • 数据脱敏:使用数据脱敏技术,将敏感数据替换为无意义或伪装的数据。例如,将真实的手机号码替换为随机生成的虚假号码,或将真实的姓名替换为随机生成的虚假姓名。
  • 访问控制:对API接口进行访问控制,只允许经过身份验证和授权的用户访问。使用身份验证令牌(如JWT)或OAuth等协议对用户进行身份验证和授权。
  • 日志记录:对API接口的访问和使用情况进行详细的日志记录,以便在发生安全事件时能够迅速发现和应对。
  • 数据传输安全:使用HTTPS协议进行数据传输,以确保数据传输过程中的安全性。
  • 数据存储安全:将敏感数据存储在加密的数据库中,并使用访问控制列表(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   ;
        /**电话*/
        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按照指定的规则进行了掩码处理

    完毕!!!

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论