开启登录二次验证

最近公司由于安全需要,某些操作需要特别的认证。一开始采用的是坚石诚信的ET99加密狗,类似于一个u盘的东西,需要插在电脑上进行认证。 刚开始还挺顺利,后来发现在谷歌内核的浏览器上并不支持,原因在于45之后谷歌彻底的移除了npapi(本来还想体验一把applet的…),当然也有折中的办法,比如让用户安装java虚拟机,本地写个java程序验证后登录, 但是需要一定的开发时间,并且操作繁琐,不予考虑。

最后把目光转向了动态口令,玩过wow的应该都用过密保卡,以前登录就是根据坐标获取密保卡上的数字再进行认证,后来升级了,手机上可以安装一个动态口令的app,效果跟现在采用的方式一样,每隔一段时间刷新口令, 口令被用过一次之后作废,一段时间没有被使用也会被认为作废,其实动态口令也略显繁琐,但安全和方便本来就是矛盾的。

坚石提供的动态口令有很多种型号,但主要分为事件型、时间型和挑战应答型的口令,事件型的顾名思义,摁一次,密码刷一次,而时间型的就跟上面的wow app的一样,每隔1min刷新一次口令。 时间型口令的原理: http://news.mydrivers.com/1/470/470829.htm 由于坚石提供了详细的文档,所以上手非常简单,这里不再赘述,唯一的坑就是口令的秘钥是他们邮件发过来的,一开始不知道,还以为拆快递的时候丢了,一上午翻了多次垃圾箱。。。。。。

至于我为什么需要动态口令

感觉现在密码登录的方式越来越不安全了,因为很多人都会选择浏览器记住密码或者自动登录,一旦做了这样的选择, 很多网站上的密码都形同虚设了,除了涉及到切身利益的一些重要步骤某些网站会短信或者邮箱验证身份之外, 其他操作都可以随意进行,而且现在很多浏览器越来越精明,选择了记住密码之后总是千方百计的帮你填充密码(可能在表单填充的时候耍了一些小花招骗过了这个版本), 尤其是chrome,居然还有查看明文密码的功能,而查看这些密码代价就是知道windows的登录密码。 因为网站上我存储了一些比较重要的东西,所以我一直在担心这样的问题,曾经想通过邮箱验证的方式来登录,但可靠性存在问题,直到最近公司采用软硬件结合的方式来 加强安全性,我才找到了一个比较适合我的方法。

由于上述方法需要通过硬件,实际使用对我来说多有不便,刚好看到了谷歌提供了一个Google Authenticator,所以鼓捣了一个android app为自己服务。

参考:
Google Authenticator for Android https://github.com/google/google-authenticator-android/
服务器端Java实现:GoogleAuth https://github.com/wstrange/GoogleAuth
wordpress的一个插件: https://wordpress.org/plugins/google-authenticator/

这里之所以提供wordpress的插件是因为GoogleAuth 可以在一段时间内同一密码可以验证通过多次,比如在30秒内有个123456的密码我可以用它登录多次,而OTP的是一次性的密码,这里wordpress插件通过记录最后一个slot来避免这种情况:

	private synchronized boolean checkCode(String secret, long code, int window) {
		long timestamp = System.currentTimeMillis();
		byte[] decodedKey = decodeSecret(secret);
		final long timeWindow = getTimeWindowFromTime(timestamp);
		for (int i = -((window - 1) / 2); i <= window / 2; ++i) {
			long slot = timeWindow + i;
			long hash = calculateCode(decodedKey, slot);
			if (hash == code) {
				if (lasttimeslot >= slot) {
					return false;
				}
				lasttimeslot = slot;
				return true;
			}
		}
		return false;
	}

最后附上一个自己的Google Authenticator : https://www.qyh.me/file/app/Authenticator.apk

还有一个值得注意的地方,虽说Google Authenticator的口令总是6位(TOTP)的,但实际的口令可能是4,5位的,例如(012345),实际口令是12345