数据脱敏及加解密

  • 一、前言
  • 二、数据脱敏
  • 无效化脱敏
  • 三、Base64加密
  • (一)编码规则
  • (二)对应码表
  • (三)编码原理
  • 1. 原文是3的倍数
  • 2. 原文不是3的倍数
  • (四)JavaScript代码运用
  • 1. 一般字符加密
  • 2. 中文字符加密
  • 3. 字符解密


一、前言

用户信息这一部分,则需要进行脱敏处理再进行展示(例如:电话号码、证件号、用户真实姓名等);并且在数据存储前,需要对数据进行加密再存储到数据库中,以保障用户信息安全。

二、数据脱敏

  数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。举个例子,比如常见的对姓名进行脱敏,展示为:张**或者张*三,这种属于掩码屏蔽,除此之外数据脱敏还有很多种方式(见表2-1),本文表述的是无效化方法(JavaScript)。

  • 表 2-1

脱敏方法

注释

无效化

指对敏感数据进行加密、截断或隐藏。一般会利用一些特殊字符(如:*&#等)替换真实数据,是最简单最常用的数据脱敏方法

随机值

指对敏感数据进行随机替换,比如123456替换为157490,这种方式会保留数据的原本格式

数据替换

类似于无效化和随机值方法,不过不是用特殊字符或随机值进行替换,而是用特定的值。比如所有用户的电话号码都替换为13500000000

平均值

常运用于统计类场景,针对数值型的数据。计算出数据的均值,然后使脱敏后的数据在均值范围随机分布,从而保持数据总和不变

对称加密

一种特殊的可逆的脱敏方法。通过加密密钥和算法对数据进行加密,加密后的数据与原始数据在逻辑规则上一致,使用密钥解密便可以恢复原始数据,但要注意密钥的安全性管理

偏移和取整

通过随机移位改变数字数据,在保持数据安全性的同时也保证了数据范围的大致真实性,较上述几种方法更接近真实数据,在大数据场景中能发挥重大价值

无效化脱敏

<script>
	// 信息脱敏处理
	// beginLen:开始脱敏的字符下标; endLen:结束脱敏的字符下标; str:需要脱敏的字符串; max:掩码最大的重复数量,若不传,则默认为20
	function getStr(beginLen, endLen, str, max = 20) {
		// substr(begin,length),begin:需要截取的字符串的下标,必须是数值,若为负数,则从字符串最后一位向左数;
		// length:需要截取的字符串长度,若不写此参数,则返回从开始位置到结束的所有字符
		const firstStr = str.substr(0, beginLen)
		// 结束脱敏的字符下标是否为0,为0则返回空,不为0则返回截取的字符
		const lastStr = endLen == 0 ? '' : str.substr(endLen) 
		// Math.max(x,y,z,...,n),返回x,y,z,...,n中的最大值
		// Math.abs(x),返回x的绝对值
		// Math.min(x,y,z,...,n),返回x,y,z,...,n中的最小值
		// 开始脱敏的下标 加上 结束脱敏的下标是否小于字符串总长度
		let repeatNum = Math.max(0, str.length - (beginLen + Math.abs(endLen)))
		// 若传了最大掩码重复数,则取数值小的那个
		repeatNum = Math.min(max, repeatNum)
		// 字符串复制指定次数,语法: string.repeat(count), count:设置需要重复的次数
		const middleStr = '*'.repeat(repeatNum) // 掩码要重复的数量
		return firstStr + middleStr + lastStr
	},
</script>
  • 使用一下上述函数
function init() {
	let phone1 = '13512345678';
	let phone2 = '13512345678';
	phone1 = this.getStr(3, -2, phone1); //显示前三位和后两位
	phone2 = this.getStr(1, -1, phone2, 4); //显示第一位和最后一位,且掩码数量为4
	console.log('脱敏后的数据为:'+ phone1)
	console.log('限制掩码数量脱敏后的数据为:'+ phone2)
},
打印结果为:

前端aes解密后端解密 前端数据加密解密_字符串

三、Base64加密

  Base64是最常见的用于传输8Bit字节码的编码方式之一,一种基于64个可打印字符来表示二进制数据的方法,使用的字符包括大小写字母各26个,加上10个数字,和加号+,斜杠/,一共64个字符,等号=用来作为后缀用途。Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3×8 = 4×6 = 24),然后把6Bit再添两位高位0(最左边为最高位),组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
  详解请参考百度百科:base64

(一)编码规则

  • 把每三个字节转换为四个字节
  • 每76个字符加一个换行符
  • 最后的结束符也要进行处理

(二)对应码表

前端aes解密后端解密 前端数据加密解密_数据_02

(三)编码原理

1. 原文是3的倍数

  比如现在要对字符串"123"进行加密。

  1. 将每个字符对应的ASCII码用二进制表示出来。
  2. 前端aes解密后端解密 前端数据加密解密_前端aes解密后端解密_03

  3. 将每组8字节的编码分为每组6字节
  4. 前端aes解密后端解密 前端数据加密解密_数据_04

  5. 高位补0,转换为十进制
  6. 前端aes解密后端解密 前端数据加密解密_数据_05

  7. 转换为对应的base64编码

  对照上述码表,所以“123”使用base64加密得到的密文为:“MTIz”

2. 原文不是3的倍数

  比如现在要对字符串"CSDN"进行加密。

  1. 将每个字符对应的ASCII码用二进制表示出来。
  2. 将每组8字节的编码分为每组6字节,不足6字节的在末端补0
  3. 补等号=

  前面说到,base64编码是把每三个字节转换成四个字节,所以密文的长度得是4的倍数,不够的需要用等号=补满四个字节。

  1. 高位补0,转换为十进制
  2. 转换为对应的base64编码

  对照上述码表,所以“CSDN”使用base64加密得到的密文为:“Q1NETg==”

(四)JavaScript代码运用

1. 一般字符加密
encode() {
    // base64
    let number = "123";
    let str = "CSDN";
    number = window.btoa(number)
    str = window.btoa(str)
    console.log("字符串'123'用base64加密后为:" + number)
    console.log("字符串'CSDN'用base64加密后为:" + str)
},
打印结果为:

前端aes解密后端解密 前端数据加密解密_字符串_06


可以看到和上面使用二进制运算的结果一致。

2. 中文字符加密

  特殊的,中文字符要使用base64进行加密,需要先进行转码

encode() {
    // encodeURIComponent()函数可把字符串作为 URI 组件进行编码
    // 该方法不会对ASCII字母和数字进行编码,也不会对这些ASCII标点符号进行编码: - _ . ! ~ * ' ( ) 
    let Chinese= "今天星期五";
    Chinese = window.btoa(encodeURIComponent(Chinese))
    console.log("字符串'今天星期五'用base64加密后为:" + Chinese)
},
打印结果为:

前端aes解密后端解密 前端数据加密解密_数据_07

  • 如果不转码,则会报错

前端aes解密后端解密 前端数据加密解密_前端_08

3. 字符解密

  str为需要进行解密的字符串变量。

  • 非中文字符
      window.atob(str);
  • 中文字符
      加密中文字符时需要先转码,同理,解密后也需要进行转码才能还原数据。
      window.decodeURIComponent(atob(str));