0. OTP一次性密码OTP是One Time Password的简写,即一次性密码。在平时生活中,我们接触一次性密码的场景非常多,比如在登录账号、找回密码,更改密码和转账操作等等这些场景,其中一些常用到的方式有:
这些场景的流程一般都是在用户提供了账号+密码的基础上,让用户再提供一个一次性的验证码来提供一层额外的安全防护。通常情况下,这个验证码是一个6-8位的数字,只能使用一次或者仅在很短的时间内可用(比如5分钟以内)。 1. HOTP基于消息认证码的一次性密码HOTP是HMAC-Based One Time Password的缩写,即是基于HMAC(基于Hash的消息认证码)实现的一次性密码。算法细节定义在RFC4226(https://tools.ietf.org/html/rfc4226),算法公式为: HOTP(Key,Counter) ,拆开是 Truncate(HMAC-SHA-1(Key,Counter)) 。
C#实现基于HMAC的OTP的代码: 1 public static string HOTP(byte[] key, byte[] counter, int length = 6)
2 {
3 var hmac = counter.ToHMACSHA1(key);
4
5 var offset = hmac[hmac.Length - 1] & 0xF;
6
7 var b1 = (hmac[offset] & 0x7F) << 24;
8 var b2 = (hmac[offset + 1] & 0xFF) << 16;
9 var b3 = (hmac[offset + 2] & 0xFF) << 8;
10 var b4 = (hmac[offset + 3] & 0xFF);
11
12 var code = b1 | b2 | b3 | b4;
13
14 var value = code % (int)Math.Pow(10, length);
15
16 return value.ToString.PadLeft(length, '0');
17 }调用一下试试看: 1 //密钥key 2 var key = "lnh_key".ToBytes(Encoding.UTF8); 3 //计数器 4 var counter = "lnh_counter".ToBytes(Encoding.UTF8); 5 //otp6=752378 6 var otp6 = SecurityHelper.HOTP(key, counter,6); 7 //otp8=49752378 8 var otp8 = SecurityHelper.HOTP(key, counter, 8); 其中key是HOTP算法需要的一个密钥(不可泄露);counter是每次生成HOTP的时候使用的计数器,使用一次就更换一个。然后就可以用来生成OTP了,第一此截取了6位,第二此截取了8位。 2. TOTP基于时间的一次性密码TOTP是Time-Based One Time Password的缩写。TOTP是在HOTP的基础上扩展的一个算法,算法细节定义在RFC6238(https://tools.ietf.org/html/rfc6238),其核心在于把HOTP中的counter换成了时间T,可以简单的理解为一个当前时间的时间戳(unixtime)。一般实际应用中会固定一个时间的步长,比如30秒,60秒,120秒等等,也就是说再这个步长的时间内,基于TOTP算法算出的OTP值是一样的。废话不多说,看看TOTP算法的核心代码: 1 public static string TOTP(byte[] key, int step = 60, int length = 6)
2 {
3 var unixTime = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
4 var counter = ((int)unixTime) / step;
5 var counterBytes = BitConverter.GetBytes(counter);
6 return HOTP(key, counterBytes, length);
7 }调用一下试试看: //密钥key
var key = "lnh_key".ToBytes(Encoding.UTF8);
//在10秒内生成,otp是一样的
for (var i = 0; i < 100; i++)
{
var otp = SecurityHelper.TOTP(key, 10, 6);
Console.WriteLine(otp);
Thread.Sleep(1000);
}![]() 3. 身份认证三要素首先解释下什么是身份认证?其实很简单,就是让对方相信你就是你。那么如何让对方相信你就是你呢?按照你能提供的信息的等级来划分,大致有如下三种信息可以证明你就是你自己:
3.1 2SV 两步验证(Two Steps Verification)两步验证现在是一个再加强认证安全方面广泛使用的一个解决方案。比如Google的2SV(https://www.google.com/landing/2step/),Microsoft的2SV(https://support.microsoft.com/zh-cn/help/12408/microsoft-account-about-two-step-verification)等等,通常的做法是当用户输入了"用户名+密码"的基础上,会让用户再提供一个一次性密码(以短信、邮件,或者动态密码生成器app的方式发放给用户)。再有比如在一些服务中需要用户额外设置的安全问题,比如“你的出生地在哪?”等等此类。 3.2 2FA双因素认证(Two Factor Authentication)2SV有个孪生兄弟2FA(双因素认证:Two Factor Authentication),那么关于2SV和2FA有什么区别呢,比如让用户在“用户名+密码”的基础上提供的额外的一次性密码,关于这个一次性密码到底是属于“你所知道的信息”还是“你所拥有的信息”呢?并没有明显的区分界限,有兴趣的可以看看这里的讨论:https://security.stackexchange.com/questions/41939/two-step-vs-two-factor-authentication-is-there-a-difference。 如果你觉得这个一次性密码属于“你所知道的信息”,那么你可以认为它是2SV;如果你觉得这个一次性密码属于“你所拥有的信息”,那么你可以认为它是2FA。 总结来说,2FA就是使用了身份认证中的2个要素。 总结 & 参考简单的介绍了下一次性密码的原理以及其应用场景,完整的代码请移步:https://github.com/linianhui/code/blob/master/src/SecurityHelper.cs 。如有错误之处,欢迎指正! 参考资料HOTP(HMAC-Based One Time Password)RFC:https://tools.ietf.org/html/rfc4226 TOTP(Time-Based One Time Password)RFC:https://tools.ietf.org/html/rfc6238 |
| 本文出处: http://www.toutiao.com/a6445846151128170765/ |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|