【Java编码准则】の #01限制内存中敏感数据的生命周期
当竞争对手的应用程序与我们的应用程序执行在同一个系统上时,我们的应用程序在内存中的敏感数据是非常easy被竞争对手获取的。假设我们的应用程序符合以下几种情况之中的一个,那么竞争对手能够获取到我们应用的敏感数据:
1)应用程序使用对象来存储敏感数据,并且在对象使用完后。对象的内容没有被清除或者对象没有被垃圾回收;
2)在操作系统执行内存管理任务或者执行休眠等功能时。应用程序的内存分页将被置换到磁盘上保存;
3)持有存储了操作系统缓存或者内存中敏感数据的buffer对象(比如BufferedReader)。
4)基于反射的控制流。使得竞争对手能够使用规避措施逃过敏感变量生命周期的限制;
5)在调试信息/日志文件/环境变量或者线程和core dumps等方面泄漏了敏感数据。
包括敏感数据的内存在数据使用后没有及时清空,非常easy导致敏感数据的泄漏。
为了限制这样的风险。应用程序必须尽量减小敏感数据的生命周期。
完美的防止内存数据的泄漏要求底层操作系统和Java虚拟机的支持。比如假设将内存数据置换到磁盘上是存在安全问题的,那么一个安全的操作系统就须要禁用数据的置换和系统的休眠。
[不符合安全要求的代码演示样例]
以下代码从控制台读取用户的username和password并将password保存在一个String对象中,这导致在垃圾回收器回收String所占用的内存之前,password处于泄漏状态。
import java.io.Console;
import java.io.IOException; public class Password { public static void main(String[] args) throws IOException {
Console console = System.console();
if (console == null) {
System.out.println("No Console.");
System.exit(1);
} String username = console.readLine("Enter your user name:");
String password = console.readLine("Enter your password:");
if (!verify(username, password)) {
throw new SecurityException("Invalid Credentials");
} } // dummy verify method, always returns true
private static final boolean verify(String username, String password) {
return true;
} }
[符合安全要求的解决方式]
这个解决方式使用Console.readPassword()函数从控制台中获取password
import java.io.Console;
import java.io.IOException;
import java.util.Arrays; public class Password { public static void main(String[] args) throws IOException {
Console console = System.console();
if (console == null) {
System.out.println("No Console.");
System.exit(1);
} String username = console.readLine("Enter your user name:");
char[] password = console.readPassword("Enter your password:");
if (!verify(username, password)) {
throw new SecurityException("Invalid Credentials");
} // Clear the password
Arrays.fill(password, ' '); } // dummy verify method, always returns true
private static final boolean verify(String username, char[] password) {
return true;
} }
函数Console.readPassword()使得返回的数据是字节数组类型,而不是String对象。因此。开发人员能够在数组数据使用完了之后清空数据,这个函数同一时候禁止了password在控制台上面的显示。
[不符合安全要求的代码演示样例]
以下的代码使用BufferedReader对象包装InputStreamReader对象,这导致敏感数据能够直接在文件里读取到。
void readData() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("file")));
// read from file
String data = br.readLine();
}
BufferdReader.readLine()函数将敏感数据以String对象的形式返回,这个对象在敏感数据用完之后还会存活非常长的时间。
而BufferedReader.read(char[], int, int)函数能够将敏感数据读取到一个char数组中。只是这须要开发人员在使用完敏感数据后手动清除。类似的,假设使用BufferedReader来包装FileReader对象。也会存在相同的安全问题。
[符合安全要求的解决方式]
以下的代码使用直接分配的NIO buffer来从文件里读取敏感数据。在数据使用完后。能够马上清除它,并且敏感数据不会缓存在多个位置,仅存在于系统内存中。
void readData() {
ByteBuffer bb = ByteBuffer.allocateDirect(16*1024);
try (FileChannel rdr = (new FileInputStream("file")).getChannel()) {
while(rdr.read(bb) > 0) {
// do something with the buffer
bb.clear();
}
} catch(Throwable e) {
// Handle error
}
}
须要注意的是,必须手动清除buffer里面的数据,由于这部分数据垃圾回收器是不会进行回收的。
——欢迎转载,请注明出处 http://blog.csdn.net/asce1885 。未经本人允许请勿用于商业用途。谢谢——
【Java编码准则】の #01限制内存中敏感数据的生命周期的更多相关文章
- 【Java编码准则】の #02不要在client存储未加密的敏感信息
当构建CS模式的应用程序时,在client側存储敏感信息(比如用户私要信息)可能导致非授权的信息泄漏. 对于Web应用程序来说,最常见的泄漏问题是在client使用cookies存放server端获取 ...
- 【Java编码准则】の #13使用散列函数保存password
明文保存password的程序在非常多方面easy造成password的泄漏.尽管用户输入的password一般时明文形式.可是应用程序必须保证password不是以明文形式存储的. 限制passwo ...
- 【Java面试题】解释内存中的栈(stack)、堆(heap)和静态存储区的用法
Java面试题:解释内存中的栈(stack).堆(heap)和静态存储区的用法 堆区: 专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型 ...
- JAVA面试题:Spring中bean的生命周期
Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...
- (spring-第1回【IoC基础篇】)Spring容器中Bean的生命周期
日出日落,春去秋来,花随流水,北雁南飞,世间万物皆有生死轮回.从调用XML中的Bean配置信息,到应用到具体实例中,再到销毁,Bean也有属于它的生命周期. 人类大脑对图像的认知能力永远高于文字,因此 ...
- 简:Spring中Bean的生命周期及代码示例
(重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...
- IoC基础篇(一)--- Spring容器中Bean的生命周期
日出日落,春去秋来,花随流水,北雁南飞,世间万物皆有生死轮回.从调用XML中的Bean配置信息,到应用到具体实例中,再到销毁,Bean也有属于它的生命周期. 人类大脑对图像的认知能力永远高于文字,因此 ...
- 面试突击80:说一下 Spring 中 Bean 的生命周期?
Java 中的公共类称之为 Bean 或 Java Bean,而 Spring 中的 Bean 指的是将对象的生命周期,交个 Spring IoC 容器来管理的对象.所以 Spring 中的 Bean ...
- 深入理解Spring中bean的生命周期
[Spring中bean的生命周期] bean的生命周期 1.以ApplocationContext上下文单例模式装配bean为例,深入探讨bean的生命周期: (1).生命周期图: (2).具体事例 ...
随机推荐
- CSU 1446 Modified LCS 扩展欧几里得
要死了,这个题竟然做了两天……各种奇葩的错误…… HNU的12831也是这个题. 题意: 给你两个等差数列,求这两个数列的公共元素的数量. 每个数列按照以下格式给出: N F D(分别表示每个数列的长 ...
- Unity 性能优化(力荐)
开始之前先分享几款性能优化的插件: 1.SimpleLOD : 除了同样拥有Mesh Baker所具有的Mesh合并.Atlas烘焙等功能,它还能提供Mesh的简化,并对动态蒙皮网格进行了很好的支持. ...
- Haproxy压测
目的:测试Haproxy压测情况 环境: Ha服务器:8核16G虚机,后端6个2核4G,压测客户端3个2核4G 安装和优化: 一.Haproxy #cd /opt/soft #wget http:// ...
- quartz 添加监听器listener
全局注册,所有Job都会起作用 JobCountListener listener = new JobCountListener(); sched.getListenerManager().addJo ...
- 【Uva 1601】The Morning after Halloween
[Link]: [Description] 给你一张平面图; 最多可能有3只鬼; 给出这几只鬼的初始位置; 然后,这几只鬼有各自的终点; 每秒钟,这几只鬼能同时移动到相邻的4个格子中的一个 任意两只鬼 ...
- Android基础新手教程——1.2.1 使用Eclipse + ADT + SDK开发Android APP
Android基础新手教程--1.2.1 使用Eclipse + ADT + SDK开发Android APP 标签(空格分隔): Android基础新手教程 1.前言 这里我们有两条路能够选,直接使 ...
- HDU 1429 胜利大逃亡(续)(bfs)
胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- [c++]基类对象作为函数參数(赋值兼容规则)
编程处理教师的基本情况. 要求: 1.定义一个"person"类.用来存储及处理人的姓名.性别.年龄,成员函数自定: 2.定义"teacher"类,公有继承&q ...
- OSX: 禁止iCloud钥匙链?
自从10.9有了一个新的功能叫viewlocale=zh_CN">iCloud钥匙串的,就出现了不少的麻烦.一是在10.9.3之前.好多人出现无限循环地要求用户输入Local item ...
- ip6tables: ipv6-icmp vs icmp
ip6tables: ipv6-icmp vs icmp资料来源 https://www.jethrocarr.com/2013/02/09/ip6tables-ipv6-icmp-vs-icmp/I ...