企业开发中名词解析— —加密与脱敏及部分开发规范
一、 加密与脱敏
在我们真实企业开发中,用户数据的安全性与保密性是很重要的,因此会经常涉及到对数据的加密与脱敏。那么什么是加密与脱敏呢?它们的区别又是什么呢?
1 加密
敏感数据的实际值转换为"非敏感"的值,只能通过解密还原成原始的值【双向】
2 脱敏
脱去数据的敏感性,在一个不可逆转的过程中,敏感数据的真实值被转换为虚构的,但是看起来很逼真的值,原来的值被永久改变且无法恢复【单向】
2.1 静态脱敏
对于开发、测试或者数据外发等场景,是不可能将生产上的真实数据暴露出来的,这个时候我们会
提供批量的脱敏数据。通过采样、替换等方式生成脱敏后的准真实数据库,脱敏后的数据同时保留
原有的关联关系。
2.2 动态脱敏
在生产开发时,我们有时候需要让用户看到真实的数据,而有时候又不希望某些用户看到真实数据,这个时候就需要进行动态脱敏。
对需要共享的生产数据或时效性很高的数据测试和培训场景,基于网络代理模式的动态脱敏技术,达到实时模糊化敏感数据的效果。动态脱敏可以实现对业务系统数据库中敏感数据进行透明、实时脱敏。
2.3 脱敏常见方式
- 数据替换:以虚构数据代替真实值
- 阶段、加密、隐藏或使其无效:以"无效"或*、#代替真值
- 随机化:以随机数据代替真值
- 偏移:通过随机移位改变数字数据
- 字符子链屏蔽:为特定数据创建定制屏蔽
- 限制返回行数:仅提供可用回应的一小部分子集
- 基于其它参考信息进行屏蔽:根据预定义规则仅改变部分回应内容(例:屏蔽VIP客户姓名,但显示其它客户姓名)
- 自定义处理规则:支持使用外部程序编写的自定义处理规则
3 区别
- 脱敏技术主要是为了兼顾数据安全与数据使用,采用的是专业的数据脱敏算法;而加密则是通过对数据进行编码来保护数据,检索原始值的唯一方法是使用解密密钥解码数据
- 脱敏数据仍然可以使用,但是加密数据无法使用
- 加密的主要优点在于它的可逆性,但是解密密钥存储的位置、如何存储以及确定谁具有访问权限等,会给整个安全工作增加额外的成本、故障点,加剧复杂性。同时对整个功能的性能提出了要求。
【1】数据加密:
- 数据加密不能完全从技术上保证数据的安全。严格来说,任何有权访问用户数据的人员,如数据分析人员,都有可能导致数据的泄漏
- 没有访问用户数据权限的人员,也可能存在对该数据进行分析挖掘的需求,数据的访问约束大大限制了充分挖掘数据价值的范围
- 加密工作会给项目增加额外的成本(解密密钥存储位置、如何存储及访问权限等)
【2】数据脱敏:
- 能够更好地保证数据的隐私性
- 能够保证数据的可用性
- 数据脱敏通常无法返回原始数据。测试、开发环境较为适用。
如果要返回原始数据,代价相对较大,脱敏的规则要相当大。
脱敏:在上图演示中,只是对数据如:姓名、电话号码等进行简单粗暴的脱敏处理,即改变真实数据
加密:通过加密算法进行处理,如MD5、DES加密等。
详细链接:https://www.cnblogs.com/fameg/p/9789496.html
二、开发规范
1 资源使用及异常捕获(try-with-resources)
finally块必须对资源对象、流对象进行关闭,有异常也需要做try-catch操作
"强制":JDK7以上,需要使用try-with-resources操作
1.1 try-catch-finally
我们以前的操作如下:
public class Demo01 {
public static void main(String[] args) throws FileNotFoundException {
FileReader fr = null;
try {
fr = new FileReader("D:\\javafiles\\java\\project\\test-git\\README.md");//创建FileReader对象
int i = 0;
System.out.println("文件内容如下:");
while ((i = fr.read()) != -1) {
System.out.println((char) i);//将读取内容强转为char类型
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fr != null) {
fr.close(); //关闭对象
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.2 try-with-resources
try-with-resources语句是一种声明了一种或多种资源的try语句。资源是指在程序用完了之后必须要关闭的对象。try-with-resources语句保证了每个声明了的资源在语句结束的时候都会被关闭。任何实现了java.lang.AutoCloseable接口的对象,和实现了java.io.Closeable接口的对象,都可以当做资源使用。
public class Demo01 {
public static void main(String[] args) throws FileNotFoundException {
try(FileReader fr = new FileReader("D:\\javafiles\\java\\project\\test-git\\README.md")){
int i = 0;
System.out.println("文件内容如下:");
while((i = fr.read()) != -1){
System.out.println((char) i);//将读取内容强转为char类型
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
这样的写法既简洁,又不容易出错,更不会造成资源的浪费,因为不论是否有异常发生,资源最终都会被关闭
我们也可以在一个try-with-resources语句里面声明多个资源,资源之间用分号隔开:
public class Demo01 {
public static void main(String[] args) throws FileNotFoundException {
try(
FileReader fr = new FileReader("D:\\javafiles\\java\\project\\test-git\\README.md");
InputStream is = new FileInputStream("D:\\javafiles\\java\\project\\test-git\\README.md")
){
int i = 0;
System.out.println("文件内容如下:");
while((i = fr.read()) != -1){
System.out.println((char) i);//将读取内容强转为char类型
}
System.out.println("=============");
int j = 0;
System.out.println("第二次读取:");
while((j = is.read()) != -1){
System.out.println(j);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
不论上面代码是否会报异常,FileReader与InputStream的close方法都会自动声明的相反顺序调用,保证资源正常关闭。
详情:https://www.cnblogs.com/hihtml5/p/6505317.html
2 线程池创建
线程池不能使用Executors创建,而是通过ThreadPoolExecutor的方法,这样的处理方式可以让开发人员更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors返回的线程池对象弊端如下:
1. FixedThreadPool和SingleThreadPool:
允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM
2. CachedThreadPool和ScheduledThreadPool:
允许创建的线程数为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM