问题:char[]与String相比,有什么优胜的地方?

回答:

针对安全保密高的信息,char[]比String做得更好。因为String是不可变得,即使你修改原先的变量,实际上也是在内存中新建一个对象,原数据还是保留在内存中,等待回收。而char[]中的元素是可以更改的。这就意味着,如密码等保密信息用完之后,你可以马上修改它而不能痕迹。从而相对于String有更好的安全性。可从下面例子中看出,char[]变更内容后,仍是那个对象。而String已经不是原来的String了。

引用:

这个对比,在知乎中这个贴有非常好的回答,我把它引用在下面:

作者:知乎用户

链接:https://www.zhihu.com/question/36734157/answer/68767786

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原答案

=====================

图里说的很清楚,虽然String加载密码之后可以把这个变量扔掉,但是字符串并不会马上被GC回收,一但进程在GC执行到这个字符串之前被dump,dump出的的转储中就会含有这个明文的字符串。

那如果我去"修改"这个字符串,比如把它赋一个新值,那么是不是就没有这个问题了?

答案是否定的,因为String本身是不可修改的,任何基于String的修改函数都是返回一个新的字符串,原有的还会在内存里。

对于char[]来说,你可以在抛弃它之前直接修改掉它里面的内容,密码就不会存在了。但是如果你什么也不做直接交给gc的话,也会存在上面一样的问题。

有的大神说这个是毫无根据的扯淡

这些所谓的大神应该没有什么安全方面的常识,这非常普遍。

FAQ

======================

1. 这种做法意义有多大?

如果没有及时清空而由GC来清除的话,暴露窗口大约是秒这个数量级,如果能够在计算HASH后立即清除,暴露窗口大约是微秒数量级。如此简单的设计就可以降低如此多的被攻击概率,性价比是非常高的。

2. 如何使用反射来修改String? 和修改char[] 相比,有何区别和风险?

通过reflection机制可以查看String的内部的内存成员,从而可以直接修改其中的数据区。但是这样的做法会有问题,内部化的String为了提高HASH速度,节省空间,值相同的字符串通常只有一个实例。

你自己的char[],修改它是没有副作用的。但是String里的char[],很可能是多个String所共享的,你改掉它就会殃及别的String。举个例子,有一个密码是"Password",而你密码框提示密码输入的文字也是"Password",改掉第一个"Password"会把后面那个也改掉。

3. 如果一点明文也不想出现,应该怎么做?

为了保证"全部处理流程均无明文密码",需要底层API在给你密码之前就做了HASH,并且这个HASH算法就是你想要的那种。最好还加盐。不过这只是在用户程序方面无明文,底层获取中会不会有明文就保证不了了。

4. 有没有绝对安全策略?

安全往往是相对于攻击成本而言的,攻击收益越高,黑客就越能接受攻击成本高的方案。因此,你采取的安全策略应该与这个攻击收益相匹配。对于极其敏感和宝贵的数据来源,就需要在安全方面上下很大功夫。目前来看,没有绝对的安全,只有相对的安全。

每天一道Java题[1]的更多相关文章

  1. 每天一道Java题[3]

    问题 为什么在重写equals()方法的同时,必须重写hashCode()方法? 解答 在<每天一道Java题[2]>中,已经对hashCode()能否判断两个对象是否相等做出了解释.eq ...

  2. 每天一道Java题[11]

    题目 synchronized怎么实现线程同步?请修改<每天一道Java题[10]>中的MyRunnableThread类以解决三个线程都获取到10的问题. 解答 方法一: 采用synch ...

  3. 每天一道Java题[4]

    问题 怎么将字符串转换为int? 解答 此题看似简单,但经常出现在笔试等地方,由于大家习惯了用IDE,有什么还真未必能写出来.通常都是parseInt()方法进行转换,如下: Int n = Inte ...

  4. 每天一道Java题[6]

    题目 String字符串怎么转换为Date,Date又怎么转换成String字符串 解答 String->Date 主要用到类SimpleDateFormat及其抽象父类DateFormat中的 ...

  5. 每天一道Java题[9]

    题目 native关键字的作用是什么? 解答 首先,需了解JNI(Java Native Interface),它是连接Java平台与本地C代码的一个API. 其次,用native关键字声明的方法,是 ...

  6. 每天一道Java题[2]

    问题 可以直接根据hashCode()方法产生的值判断两个对象是否相等吗? 解答 不能!根据Wikipedia(https://en.wikipedia.org/wiki/Java_hashCode( ...

  7. 每天一道Java题[5]

    题目 String.StringBuilder.StringBuffer有什么异同? 解答 相同点:String.StringBuilder.StringBuffer都可以用来存储字符串. 不同点: ...

  8. 每天一道Java题[7]

    题目 什么是REST原则,请解释RESTful架构,以及其设计思想? 解答 REST,全称为Representation State Transfer,是一种互联网软件的架构原则.凡是满足REST原则 ...

  9. 每天一道Java题[10]

    题目 阐述创建线程最常用的两种方法及其对比. 解答 方法一:继承Thread类实现 步骤: 创建Thread类的子类,如MyThread. 重写Thread类的run()方法. 实例化MyThread ...

随机推荐

  1. 手动es6编译es5(命令行)

    package.json:"devDependencies": { "babel-cli": "^6.18.0", "babel- ...

  2. Dashboard登录成功后 RuntimeError: Unable to create a new session key.

    openstack按照官网docs部署horizon后,使用admin账号密码登录,但网页提示未知错误. 查看/var/log/httpd/error_log 提示这个:RuntimeError: U ...

  3. Struts2之Validator

    Struts2中提供了数据校验验证数据例如验证邮件.数字等.验证方式有3种:一是通过validate()方法,二是通过Xml,三是使用注解方式. 一.初始化 首先定义一个User类 package c ...

  4. 机器学习:python中如何使用朴素贝叶斯算法

    这里再重复一下标题为什么是"使用"而不是"实现": 首先,专业人士提供的算法比我们自己写的算法无论是效率还是正确率上都要高. 其次,对于数学不好的人来说,为了实 ...

  5. UNION ALL合表查询

    有时候需要连表查询数据,可以使用union all来做合表. 语法: SELECT column_name FROM table1UNION ALLSELECT column_name FROM ta ...

  6. Andorid自动读取短信验证码

    手机收到验证码短信后,程序自动识别验证码并填充验证码输入框. 思路是有了,实现的方式也有多种: 1.开启一个线程,隔一段时间就去查询收件箱是否有变化,有变化再读取出来做处理. 2.注册一个短信变化的广 ...

  7. selenium结合docker构建分布式测试环境

    selenium是目前web和app自动化测试的主要框架.对于web自动化测试而言,由于selenium2.0以后socker服务器由本地浏览器自己启动且直接通过浏览器原生API操作页面,故越来越多的 ...

  8. Object类型知识总结,你掌握了多少?

      Object类型    ECMAScript中的对象其实就是一组数据和功能的集合.对象可以通过执行new操作符后跟要创建的对象类型的名称来创建.而创建Object类型的实例并为其添加属性和(或)方 ...

  9. C# 调用C++dll出现的问题。

    问题描述: 对 PInvoke 函数“winform应用!winform应用.Form1::add”的调用导致堆栈不对称.原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配.请检查 PIn ...

  10. Extjs6(特别篇)——项目自带例子main.js拆分详解

    本文基于extjs6.0.0 一.拆分代码来看看 1.主页面main是个tab页: 写一些页面的依赖: 标明页面的controller和viewModel Ext.define('Learning.v ...