首页 > 其他分享 >顶级企业如何用数据脱敏保护用户隐私!

顶级企业如何用数据脱敏保护用户隐私!

时间:2024-11-17 19:08:55浏览次数:1  
标签:encrypt name 顶级 ShardingSphere 隐私 user 数据 脱敏

0 前言

ShardingSphere提供数据访问安全性:通过数据脱敏,完成对敏感数据的安全访问。本文介绍ShardingSphere数据脱敏功能。

数据脱敏,指对敏感信息通过脱敏规则进行数据转换,实现敏感隐私数据的可靠保护。相较传统私有化部署方案,互联网应用对数据安全要求更高,涉及范围更广。根据行业和业务场景属性,不同系统敏感信息不同,但诸如身份证号、手机号、卡号、用户姓名、账号密码等个人信息一般都需脱敏。

1 咋抽象数据脱敏?

先梳理实现数据脱敏的抽象过程。从这三维抽象数据脱敏:

  • 敏感数据存储方式
  • 敏感数据的加解密过程
  • 在业务代码中嵌入加解密的过程

针对每维,将基于 ShardingSphere 给出这框架的具体抽象过程,以便理解使用它的方法和技巧。

1.1 咋存储?

讨论点在于,是否需将敏感数据以明文存储在数据库。答案并非绝对。

① 直接密文

先考虑第一种情况。对一些敏感数据,我们显然应直接密文形式将加密后的数据存储,防止任何途径能从数据库获取明文。这类敏感数据,最典型的就是用户密码,通常采用 MD5 等不可逆加密算法,而使用这些数据的方法也只是依赖其密文形式,不涉及明文直接处理。

② 一列明文,一列密文

但对用户姓名、手机号等信息,由于统计分析等需要,显然不能直接采用不可逆加密算法,还需处理明文信息。常见地将一个字段用两列保存:

  • 一列明文
  • 一列密文

可将第一种情况看作第二种情况的特例。即第一种情况无明文列,仅密文列。ShardingSphere基于俩情况进行抽象:

  • 明文列命为 plainColumn,选填
  • 密文列命为 cipherColumn,必填

ShardingSphere 还提出一个逻辑列 logicColumn,代表一种虚拟列,只面向开发人员编程使用。

1.2 咋加解密?

数据脱敏本质上就是一种加解密技术应用场景,自然少不了对各种加解密算法和技术的封装。传统的加解密方式有两种,一种是对称加密,常见的包括 DEA 和 AES;另一种是非对称加密,常见的包括 RSA。

ShardingSphere抽象一个 ShardingEncryptor 组件封装各种加解密操作:

public interface ShardingEncryptor extends TypeBasedSPI {

    void init();

    String encrypt(Object plaintext);

    Object decrypt(String ciphertext);
}

ShardingSphere 内置 AESShardingEncryptor、MD5ShardingEncryptor具体实现。由于扩展了TypeBasedSPI接口,所以可基于微内核架构和 JDK SPI 来实现和动态加载自定义的 ShardingEncryptor。

1.3 业务代码咋嵌入数据脱敏?

显然这过程应尽量:

  • 自动化
  • 低侵入性
  • 对开发透明

我们可以通过一个具体的示例来描述数据脱敏的执行流程。假设系统中存在一张 user 表,其中包含一个 user_name 列。我们认为这个 user_name 列属于敏感数据,需要对其进行数据脱敏。那么按照前面讨论的数据存储方案,可以在 user 表中设置两个字段,一个代表明文的 user_name_plain,一个代表密文的 user_name_cipher。然后应用程序通过 user_name 这个逻辑列与数据库表进行交互:三种数据列交互方式示意图

针对这个交互过程,我们希望存在一种机制,能够自动将 user_name 逻辑列映射到 user_name_plain 和 user_name_cipher 列。同时,我们希望提供一种配置机制,能够让开发人员根据需要灵活指定脱敏过程中所采用的各种加解密算法。

ShardingSphere就提供这样的机制:

  • ShardingSphere解析应用程序传入的SQL,并依据开发提供的脱敏配置去改写SQL,实现对明文数据自动加密
  • 将加密后的密文数据存储到数据库
  • 当我们查询数据,它又从数据库取出密文,并自动解密,最终将解密后明文返给用户

ShardingSphere 提供自动化+透明化的数据脱敏过程,业务开发可像用普通数据使用脱敏数据,无需关注数据脱敏实现细节。

2 系统改造:咋实现数据脱敏?

2.1 准备数据脱敏

为演示数据脱敏,定义一个 EncryptUser 实体类,定义与数据脱敏相关的常见用户名、密码等字段,与数据库encrypt_user表列对应:

public class EncryptUser {
    //用户Id
    private Long userId;
    //用户名(密文)
    private String userName;
    //用户名(明文)
    private String userNamePlain;
    //密码(密文)
    private String pwd;
	…
}

EncryptUserMapper关于 resultMap 和 insert 语句的定义:

<mapper namespace="com.demo.repository.EncryptUserRepository">
    <resultMap id="encryptUserMap" type="com.demo.entity.EncryptUser">
        <result column="user_id" property="userId" jdbcType="INTEGER"/>
        <result column="user_name" property="userName" jdbcType="VARCHAR"/>
        <result column="pwd" property="pwd" jdbcType="VARCHAR"/>
    </resultMap> 
    <insert id="addEntity">
        INSERT INTO encrypt_user (user_id, user_name, pwd) VALUES (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR}, #{pwd,jdbcType=VARCHAR})
    </insert>
       … 
</mapper>
@Service
public class EncryptUserServiceImpl implements EncryptUserService { 
    @Autowired
    private EncryptUserRepository encryptUserRepository;

  	// 插入用户
    @Override
    public void processEncryptUsers() throws SQLException {
       insertEncryptUsers();
    }

    private List<Long> insertEncryptUsers() throws SQLException {
       List<Long> result = new ArrayList<>(10);
        for (Long i = 1L; i <= 10; i++) {
         EncryptUser encryptUser = new EncryptUser();
         encryptUser.setUserId(i);
         encryptUser.setUserName("username_" + i);
         encryptUser.setPwd("pwd" + i);
            encryptUserRepository.addEntity(encryptUser);
            result.add(encryptUser.getUserId());
        }

        return result;
    }
  
  	// 获取用户列表
    @Override
    public List<EncryptUser> getEncryptUsers() throws SQLException {
       return encryptUserRepository.findEntities();
    }
}

数据脱敏功能内嵌在sharding-jdbc-spring-boot-starter:

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0</version>
</dependency>

2.2 配置数据脱敏

整体架构和分库分表及读写分离一样,数据脱敏对外暴露的入口也是符合JDBC规范的EncryptDataSource。

ShardingSphere 提供 EncryptDataSourceFactory 完成 EncryptDataSource 对象构建:

public final class EncryptDataSourceFactory {

    DataSource createDataSource(DataSource dataSource, EncryptRuleConfiguration encryptRuleConfiguration, Properties props) {
        return new EncryptDataSource(dataSource, new EncryptRule(encryptRuleConfiguration), props);
    }
}

EncryptRuleConfiguration类包含两个 Map:

// 加解密器配置列表
private final Map<String, EncryptorRuleConfiguration> encryptors;
// 加密表配置列表
private final Map<String, EncryptTableRuleConfiguration> tables;

EncryptorRuleConfiguration集成了ShardingSphere的通用抽象类TypeBasedSPIConfiguration,包含type、properties字段:

// 类型(如MD5/AES加密器)
private final String type;
// 属性(如AES加密器用到的Key值)
private final Properties properties;

EncryptTableRuleConfiguration持有一个包含多个 EncryptColumnRuleConfiguration 的 Map,EncryptColumnRuleConfiguration 就是 ShardingSphere 对加密列的配置,包含plainColumn、cipherColumn定义:

public final class EncryptColumnRuleConfiguration {
    // 存储明文的字段
    private final String plainColumn;
    // 存储密文的字段
    private final String cipherColumn;
    // 辅助查询字段
    private final String assistedQueryColumn;
    // 加密器名字
    private final String encryptor;
}

各配置类关系,数据脱敏所需配置项:

定义数据源dsencrypt

spring.shardingsphere.datasource.names=dsencrypt 
spring.shardingsphere.datasource.dsencrypt.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.dsencrypt.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.dsencrypt.jdbc-url=jdbc:mysql://localhost:3306/dsencrypt
spring.shardingsphere.datasource.dsencrypt.username=root
spring.shardingsphere.datasource.dsencrypt.password=root

配置加密器

定义name_encryptor、pwd_encryptor加密器分别对user_name、pwd列加解密:

# 对name_encryptor使用对称加密算法AES
spring.shardingsphere.encrypt.encryptors.name_encryptor.type=aes
spring.shardingsphere.encrypt.encryptors.name_encryptor.props.aes.key.value=123456
# 对pwd_encryptor,我们则直接使用不可逆的 MD5 散列算法:
spring.shardingsphere.encrypt.encryptors.pwd_encryptor.type=md5

脱敏表配置

针对案例场景,可选择:

  • user_name列设置plainColumn、cipherColumn及encryptor属性
  • pwd列,由于不希望在数据库存储明文,所以配置cipherColumn、encryptor
spring.shardingsphere.encrypt.tables.encrypt_user.columns.user_name.plainColumn=user_name_plain
spring.shardingsphere.encrypt.tables.encrypt_user.columns.user_name.cipherColumn=user_name
spring.shardingsphere.encrypt.tables.encrypt_user.columns.user_name.encryptor=name_encryptor
spring.shardingsphere.encrypt.tables.encrypt_user.columns.pwd.cipherColumn=pwd
spring.shardingsphere.encrypt.tables.encrypt_user.columns.pwd.encryptor=pwd_encryptor

ShardingSphere提供属性开关,当底层数据库表里同时存储了明文和密文数据后,该属性开关可以决定是直接查询数据库表里的明文数据进行返回,还是查询密文数据并进行解密之后再返回:

spring.shardingsphere.props.query.with.cipher.comlum=true

2.3 执行数据脱敏

执行测试用例。先执行数据插入,下图数据表中对应字段存储加密后的密文:

这过程,ShardingSphere会把原SQL语句转换为用于数据脱敏的目标语句:

再执行查询语句并获取控制台日志:

2024-11-16 21:20:49.782  INFO 68311 --- [           main] ShardingSphere-SQL                       : Rule Type: encrypt
2024-11-16 21:20:49.782  INFO 68311 --- [           main] ShardingSphere-SQL                       : SQL: SELECT * FROM test_db.encrypt_user;
user_id: 1, user_name: test_1, pwd: 99024280cab824efca53a5d1341b9210
user_id: 2, user_name: test_2, pwd: 36ddda5af915d91549d3ab5bff1bafec
…

路由类型“encrypt”,获取的 user_name 是解密后的明文,而非数据库存储的密文,即spring.shardingsphere.props.query.with.cipher.comlum=true配置项作用。若配置项置false,就返回密文。

3 总结

数据脱敏是数据库管理和数据访问控制的一个重要话题,今天我们讲解了 ShardingSphere 在数据脱敏方面提供的技术方案,但实际上,数据脱敏的实现思路有很多,ShardingSphere 采用了一种自动化、透明化的方案完成敏感数据存储、加解密以及和应用程序之间的无缝整合。同时,今天的课程也围绕系统案例对其进行了数据库脱敏改造,我们给出了具体的配置项和执行过程。

4 实现方式集

在使用 ShardingSphere 的数据脱敏模块(Data Masking)进行数据加密时,可以通过以下几种方式设置需要加密的数据项:


1. 基于 SQL 配置规则

通过在 SQL 语句中动态添加脱敏规则配置项。例如:

ALTER TABLE user ADD COLUMN encrypted_column VARBINARY(255);

在运行时通过 SQL 的形式配置指定列的脱敏或加密规则。此方式适合临时性或动态规则配置。


2. 配置文件中静态配置

通过 YAML 或 Java 配置静态指定加密数据项。以下是 YAML 配置示例:

YAML 配置示例

encryptRule:
  tables:
    user:
      columns:
        password:
          plainColumn: plain_password
          cipherColumn: cipher_password
          encryptorName: aes_encryptor
  encryptors:
    aes_encryptor:
      type: AES
      props:
        aes-key-value: 123456abc

Java 代码配置示例

如果你使用 Java 编程动态配置规则,可以通过如下代码设置:

EncryptRuleConfiguration encryptRuleConfig = new EncryptRuleConfiguration();
EncryptColumnRuleConfiguration columnConfig = new EncryptColumnRuleConfiguration("plain_password", "cipher_password", "aes_encryptor");
encryptRuleConfig.getTables().put("user", new EncryptTableRuleConfiguration(Map.of("password", columnConfig)));

此方式适合静态规则配置,适用场景较广。


3. 在前端代码中配置脱敏规则

通过在调用 ShardingSphere Proxy 时,在前端客户端(如 JDBC 应用程序)配置脱敏规则并执行数据查询或插入操作。例如:

// 在 JDBC 中绑定加密规则
String query = "SELECT AES_ENCRYPT('plain_text', 'key') AS cipher_column;";
ResultSet rs = statement.executeQuery(query);

4. 通过 ShardingSphere 控制台配置(推荐)

在使用 ShardingSphere-UIShardingSphere-Proxy 时,直接通过其管理控制台添加或修改脱敏规则。可以实现对某些列动态指定加密规则,例如:

  • 登录控制台
  • 选择目标数据源
  • 在加密规则模块中为指定列配置 PlainColumnCipherColumn,并选择加密器(如 AES、MD5 等)

5. 动态规则加载

通过 SPI(Service Provider Interface)机制自定义脱敏规则和算法。例如,如果现有规则无法满足需求,可以实现一个自定义加密算法:

自定义加密器示例

public final class CustomEncryptAlgorithm implements EncryptAlgorithm {

    @Override
    public String encrypt(Object plaintext, Properties props) {
        // 自定义加密逻辑
        return Base64.getEncoder().encodeToString(plaintext.toString().getBytes());
    }

    @Override
    public String decrypt(String ciphertext, Properties props) {
        // 自定义解密逻辑
        return new String(Base64.getDecoder().decode(ciphertext));
    }
}

在配置中引入该算法即可。


总结

主要有以下几种方式可以设置需要加密的数据项:

  1. SQL 动态配置
  2. YAML/Java 静态配置
  3. 前端代码中直接配置
  4. ShardingSphere 控制台(UI/Proxy)配置
  5. 自定义加密规则,通过 SPI 动态加载

根据具体场景和需求选择。

关注我,紧跟本系列专栏文章,咱们下篇再续!

作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。

各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。

负责:

  • 中央/分销预订系统性能优化
  • 活动&券等营销中台建设
  • 交易平台及数据中台等架构和开发设计
  • 车联网核心平台-物联网连接平台、大数据平台架构设计及优化
  • LLM Agent应用开发
  • 区块链应用开发
  • 大数据开发挖掘经验
  • 推荐系统项目

目前主攻市级软件项目设计、构建服务全社会的应用系统。

参考:

本文由博客一文多发平台 OpenWrite 发布!

标签:encrypt,name,顶级,ShardingSphere,隐私,user,数据,脱敏
From: https://www.cnblogs.com/JavaEdge/p/18550922

相关文章

  • 隐私保护在混合现实中如何体现——从‘哋它亢’说起
    引言:什么是混合现实及其重要性混合现实(MixedReality,MR)是一种融合了虚拟与真实世界的交互技术。它通过将数字信息嵌入到用户的感知中来增强用户体验。随着技术的发展,混合现实不仅在游戏娱乐、教育和培训等领域展现出巨大潜力,在医疗、建筑、工程等多个行业也逐渐得到应用。从广......
  • 细数 AI 领域的 28 位顶级科学家
    人工智能(AI)作为一门交叉学科,吸收了计算机科学、数学、心理学、认知科学等多个领域的知识。其发展离不开许多思想家的贡献。本文将从莱布尼茨到杨立昆,逐一介绍28位对AI领域产生深远影响的科学家(名单来自《AI群星闪耀时》一书)。1.莱布尼茨(GottfriedWilhelmLeibniz)莱布尼茨......
  • 自定义注解进行数据脱敏
    前言有些时候,我们可能对输出的某些字段要做特殊的处理在输出到前端,比如:身份证号,电话等信息,在前端展示的时候我们需要进行脱敏处理,这时候通过自定义注解就非常的有用了。在Jackson中要自定义注解,我们可以通过@JacksonAnnotationsInside注解来实现,如下示例:一、自定义注解import......
  • HarmonyOS Next 分布式管理权限控制:安全与隐私
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在当今数字化时代,安全与隐私如同基石般重......
  • 同城圈子APP隐私设置指南,社交圈子源码,前端uniapp,后端PHP
    圈子系统APP-uniapp源码开源社交圈子小程序社区系统兴趣爱好同城社交社群系统同城圈子APP隐私设置因应用而异,以下为通用步骤:1、进入隐私设置打开APP,点击底部导航栏的“我的”。进入“设置”页面,选择“隐私设置”。2、隐藏位置信息在隐私设置中,找到并点击“隐藏位置”选......
  • 适用于 Mac 和 Windows 的顶级U 盘数据恢复软件
    由于意外删除或设备故障而丢失USB驱动器中的数据始终是一件令人压力很大的事情,检索该信息的最佳选择是使用优质数据恢复软件。为了让事情变得更容易,我们已经为您完成了所有研究并测试了工具,并且我们列出了最好的USB记忆棒恢复软件,这将使您有最大的机会挽救丢失的文件。顶......
  • 全球粉丝疯狂狂欢,世界顶级流行偶像组合发布新专辑
     今天,全球粉丝们疯狂狂欢!世界知名的流行偶像组合“SparkleStars”宣布他们即将发布他们最新的专辑《Unstoppable》!这支组合在音乐界拥有数百万忠实粉丝,他们的歌曲总是能在音乐榜单上获得高位,并创下了众多销售记录。 据悉,这张新专辑将包含十首全新歌曲,每一首歌曲都经过了......
  • 【云原生系列】你的数据隐私可能正在丢失
    嗨,各位朋友们!今天我们来聊聊一个在云计算领域非常热门的话题——数据隐私。随着云计算技术的迅猛发展,越来越多的数据被存储和处理在云端,那么,云服务提供商是怎么确保这些数据安全,不被滥用的呢?我们慢慢来讲。01理解云中的数据隐私首先,我们得明白什么是数据隐私。在云计算......
  • AI帮你记住所有密码,你敢把隐私交给它吗?
    数字时代的密码管理挑战在这个信息爆炸的数字时代,每个人都面临着前所未有的密码管理挑战。随着我们在网上进行越来越多的活动,从购物到社交,再到网上银行,所需的密码数量也随之激增。每个账户需要独特且复杂的组合,以避免因账户被攻破而导致的潜在风险。但复杂的密码往往难以记住......
  • 【无标题】海外媒体发稿:华尔街内参北美顶级财经的璀璨之星
    一、华尔街内参的崛起之路华尔街内参在竞争激烈的财经媒体领域走出了一条独特的崛起之路。它以专业、独立和深入的财经报道为基石,逐渐赢得了全球投资者的信赖。成立之初,华尔街内参便致力于为读者提供及时、准确的财经信息和前瞻性建议。其报道范围广泛,覆盖全球市场动态、政策......