为什么推荐优先使用char[]/byte[]存储敏感信息

  1. 字符串变量是不可变的。一旦分配了字符串变量,就无法更改或删除其值。因此,这些字符串可能在可能在多个位置的存储器中保持不变,持续一段时间,直到垃圾收集器正好将其移除,且由于字符串是不可变的,所以没有任何方式可以修改字符串的值,因为每次修改都将产生新的字符串。敏感数据(如密码)将作为明文在内存中暴露,无法控制其生命周期因为任何能够访问内存(memory dump内存转储)的人都能清晰的看到文本中的密码,这也是为什么你应该总是使用加密的形式而不是明文来保存密码。因为String使用常量池存储字符串,即使jdk7之后常量池移到了堆,也要在触发gc之后才能彻底清除掉内存中的敏感信息。
  2. Java官方文档《Java加密体系结构指南》 (https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#PBEEx) 建议:在对象java.lang.String 中收集和存储密码看似符合逻辑,但是需要注意的是,字符串对象是不可变的,没有任何方法可以改变(重写)或清空内容。这一特性使得字符串对象不适合存储安全敏感信息,比如用户密码。你应该使用字符数组收集和存储安全敏感信息。
  3. 建议使用专用类存储明文的敏感信息,或者,将明文敏感信息临时存储在可变数据类型(如:char[]/byte[])中,且用完后立即擦除。如果没有及时清空而由GC来清除的话,暴露窗口大约是秒这个数量级,如果能够在计算HASH后立即清除,暴露窗口大约是微秒数量级。如此简单的设计就可以降低如此多的被攻击概率,性价比是非常高的。
  4. 其他问题:通过reflection机制可以查看String的内部的内存成员,从而可以直接修改其中的数据区。但是这样的做法会有问题,内部化的String为了提高HASH速度,节省空间,值相同的字符串通常只有一个实例。
    你自己的char[],修改它是没有副作用的。但是String里的char[],很可能是多个String所共享的,你改掉它就会殃及别的String。举个例子,有一个密码是"Password",而你密码框提示密码输入的文字也是"Password",改掉第一个"Password"会把后面那个也改掉。

- 阅读剩余部分 -

ConcurrentModificationException引起的问题

现象

这是一个由ConcurrentModificationException引发的问题,先看下这段程序:

List<String> tmpList1 = new LinkedList<>();
tmpList1.add("Hello");
tmpList1.add("My");
tmpList1.add("Son");

for (String curStr : tmpList1) {
    if ("My".equals(curStr)) {
        tmpList1.remove(curStr);
    }
    System.out.printf("curStr = %s, tmpList = %s\n", curStr, tmpList1.toString());
}

- 阅读剩余部分 -

如果不小心在本地把某个本地分支A以及远端分支origin/A都删了的话...

目前可用的方法

  1. 比较可靠的方式:问下其他人本地有没有代码,idea会自动fetch,所以有比较大的可能性能找到分支A的较新状态,可以请他重新推到远端(其他git工具也有可能)。
  2. 远端分支还在的话可以考虑重新拉下来,如果本地没有额外提交的话
  3. 用git恢复分支,这种方法可行但是不一定能完全恢复

- 阅读剩余部分 -

在接口设计中,有的时候会给请求的某个字段设置一个默认值,

比如某个列表字段默认值会设置成空列表、某个字段(一般字段)设置了默认值

之前我以为前端如果不给字段传值,就会取设置的默认值,或者前端传了null,默认也会取设置的默认值。

但是实际操作了一下,结果是:

  • 前端不传该字段,字段取设置的默认值
  • 前端如果传的是null,字段则不会取默认值,接口接收到的字段值就是传过来的null

目前还不太清楚这个是否经过框架或者别的逻辑干预过的结果。

就目前的情况来理解,给某个字段赋值null是一种主动行为,因为null本身是字段可以取的值之一,如果调用方主动传了null,意味着其期望该值为null。如果期望取默认值,则可以不传该字段。

我喜欢研究技术,我喜欢学习未知的东西,渴望达到自己的技术自由。至今我都怀念研究生三年在教研室和图书馆学习数学学习机器学习和人工智能以及看论文的那些时光。

可惜自从开始工作之后每天回来都是筋疲力尽,这两年过的浑浑噩噩的。虽然也学到了很多自己看书学不到的东西,但是那种每天情不自禁的想要继续看会上次没学完的东西的感觉再也没有出现过了。这两年我也尝试着梳理过自己想要继续在什么方面学习的大纲,却少有精力真正持续实践过。

之前一直听说程序员做技术总是会面临35岁这一道坎,工作的这两年倒是没有太多实际的感受,可能是因为我的同事基本都是超过35岁的人,和他们在一起工作有时能感受到一些安心感,我遇到一些不确定的东西总是不用担心没人请教。不过最近找工作的同事还是和我说外面依然会面临这个问题。是啊,即便不考虑企业的因素,我当然也希望自己能在年轻时变得更加牛逼,但是实际往往事与愿违,人生中总是存在很多遗憾,随着时间流逝,我也能感受到越来越紧迫的追逐感。

好在我的目标依然没有变,我依然热爱技术,依然愿意投入精力追逐似乎永远没法完全追上的前沿。希望不远的将来我能实现自己的技术自由。