[信息安全] 4.一次性密码 && 身份认证三要素
在信息安全领域,一般把Cryptography称为密码,而把Password称为口令。日常用户的认知中,以及我们开发人员沟通过程中,绝大多数被称作密码的东西其实都是Password(口令),而不是真正意义上的密码。本文保持这种语义,采用密码来代指Password,而当密码和口令同时出现时,用英文表示以示区分。
0. OTP一次性密码
OTP是One Time Password的简写,即一次性密码。在平时生活中,我们接触一次性密码的场景非常多,比如在登录账号、找回密码,更改密码和转账操作等等这些场景,其中一些常用到的方式有:
- 手机短信+短信验证码;
- 邮件+邮件验证码;
- 认证器软件+验证码,比如Microsoft Authenticator App,Google Authenticator App等等;
- 硬件+验证码:比如网银的电子密码器;
这些场景的流程一般都是在用户提供了账号+密码的基础上,让用户再提供一个一次性的验证码来提供一层额外的安全防护。通常情况下,这个验证码是一个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-(Key,Counter)) 。
- Key:密钥;
- Counter:一个计数器;
- HMAC-SHA-1:基于SHA1的HMAC算法的一个函数,返回MAC的值,MAC是一个20bytes(160bits)的字节数组;
- Truncate:一个截取数字的函数,以3中的MAC为参数,按照指定规则,得到一个6位或者8位数字(位数太多的话不方便用户输入,太少的话又容易被暴力猜测到);
C#实现基于HMAC的OTP的代码:
public static string HOTP(byte[] key, byte[] counter, int length = )
{
var hmac = counter.ToHMACSHA1(key); var offset = hmac[hmac.Length - ] & 0xF; var b1 = (hmac[offset] & 0x7F) << ;
var b2 = (hmac[offset + ] & 0xFF) << ;
var b3 = (hmac[offset + ] & 0xFF) << ;
var b4 = (hmac[offset + ] & 0xFF); var code = b1 | b2 | b3 | b4; var value = code % (int)Math.Pow(, length); return value.ToString().PadLeft(length, '');
}
调用一下试试看:
//密钥key
var key = "lnh_key".ToBytes(Encoding.UTF8);
//计数器
var counter = "lnh_counter".ToBytes(Encoding.UTF8);
//otp6=752378
var otp6 = SecurityHelper.HOTP(key, counter,);
//otp8=49752378
var otp8 = SecurityHelper.HOTP(key, counter, );
其中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算法的核心代码:
public static string TOTP(byte[] key, int step = , int length = )
{
var unixTime = (DateTime.UtcNow - new DateTime(, , , , , , , DateTimeKind.Utc)).TotalSeconds;
var counter = ((int)unixTime) / step;
var counterBytes = BitConverter.GetBytes(counter);
return HOTP(key, counterBytes, length);
}
调用一下试试看:
//密钥key
var key = "lnh_key".ToBytes(Encoding.UTF8);
//在10秒内生成,otp是一样的
for (var i = ; i < 10; i++)
{
var otp = SecurityHelper.TOTP(key, 1, );
Console.WriteLine(otp);
Thread.Sleep();
}
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。如有错误之处,欢迎指正!
参考资料
OTP(One Time Password)Wiki:https://en.wikipedia.org/wiki/One-time_password
One Time Password System:https://tools.ietf.org/html/rfc2289
HOTP(HMAC-Based One Time Password) Wiki:https://en.wikipedia.org/wiki/HMAC-based_One-time_Password_Algorithm
HOTP(HMAC-Based One Time Password)RFC:https://tools.ietf.org/html/rfc4226
TOTP(Time-Based One Time Password)Wiki:https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
TOTP(Time-Based One Time Password)RFC:https://tools.ietf.org/html/rfc6238
2SV vs 2FA (1):https://security.stackexchange.com/questions/41939/two-step-vs-two-factor-authentication-is-there-a-difference
2SV vs 2FA (2):https://paul.reviews/the-difference-between-two-factor-and-two-step-authentication/
MFA/2FA(Multi Factor Authentication) Wiki:https://en.wikipedia.org/wiki/Multi-factor_authentication
示例
Google Authenticator : https://github.com/google/google-authenticator/wiki
DEMO: https://authenticator.ppl.family/
[信息安全] 4.一次性密码 && 身份认证三要素的更多相关文章
- 深入解读 ASP.NET Core 身份认证过程
长话短说:上文我们讲了 ASP.NET Core 基于声明的访问控制到底是什么鬼? 今天我们乘胜追击:聊一聊ASP.NET Core 中的身份验证. 身份验证是确定用户身份的过程. 授权是确定用户是否 ...
- Apache shiro集群实现 (三)shiro身份认证(Shiro Authentication)
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
- asp.net core 使用identityServer4的密码模式来进行身份认证(一)
IdentityServer4是ASP.NET Core的一个包含OpenID和OAuth 2.0协议的框架.具体Oauth 2.0和openId请百度. 前言本博文适用于前后端分离或者为移动产品来后 ...
- python作业设计:输入用户名密码,认证成功后显示欢迎信息,输错三次后锁定
作业需求: 1.输入用户名密码 2.认证成功后显示欢迎信息 3.输错三次后锁定实现思路: 1.判断用户是否在黑名单,如果在黑名单提示账号锁定. 2.判断用户是否存在,如果不存在提示账号不存在. 3.判 ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(三)
在前面两篇文章中,我介绍了基于IdentityServer4的一个Identity Service的实现,并且实现了一个Weather API和基于Ocelot的API网关,然后实现了通过Ocelot ...
- 重新整理 .net core 实践篇————网关中的身份签名认证[三十七]
前言 简单整理一下网关中的jwt,jwt用于授权认证的,其实关于认证授权这块https://www.cnblogs.com/aoximin/p/12268520.html 这个链接的时候就已经写了,当 ...
- influxdb数据库增加身份认证(windows)三
接上一节,增加数据库身份认证 1.修改Config配置文件auth-enabled为true 2.然后重新载入最新的config配置文件打开数据库 3.验证身份认证功能是否已打开 说明身份认证功能已打 ...
- 理解ASP.NET Core - 基于JwtBearer的身份认证(Authentication)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 在开始之前,如果你还不了解基于Cookie的身份认证,那么建议你先阅读<基于Cookie ...
- "用户增长"--快速身份认证实现用户增长的技术和产品方案
"用户增长"--快速身份认证实现用户增长的技术和产品方案 1 引言 作为一个互联网产品,用户量的增长是一个非常重要的衡量指标. 这是一个集合了销售,市场,运营,技术的综合能力. ...
随机推荐
- SQL数据库的多表查询
多表查询分为 内.外连接 外连接分为左连接(left join 或left outer join).右连接(right join 或者 right outer join).和完整外部连接 (full ...
- 从零开始理解JAVA事件处理机制(3)
我们连续写了两小节的教师-学生的例子,必然觉得无聊死了,这样的例子我们就是玩上100遍,还是不知道该怎么写真实的代码.那从本节开始,我们开始往真实代码上面去靠拢. 事件最容易理解的例子是鼠标事件:我们 ...
- Catalog Service - 解析微软微服务架构eShopOnContainers(三)
上一篇我们说了Identity Service,因为其基于IdentityServer4开发的,所以知识点不是很多,今天我们来看下Catalog Service,今后的讲解都会把不同的.重点的拿出来讲 ...
- Backbox Linux简介与配置内网IP
总体说起来,Backbox内置的工具什么的,并不是很多,但是它集成了一些用起来很棒的工具. 比如:Beef.Sqlmap.wpscan.zenmap.msf.w3af.dns嗅探等一系列工具,传说中的 ...
- idea live template高级知识, 进阶(给方法,类,js方法添加注释)
为了解决用一个命令(宏)给方法,类,js方法添加注释,经过几天的研究.终于得到结果了. 实现的效果如下: 给Java中的method添加方法: /** * * @Method : addMenu * ...
- 快速上手 Kotlin 的 11 招
本文转载自 Kotlin 公众号(KotlinX) 作者:bennyhuo 最近经常会收到一些 "用 Kotlin 怎么写" 的问题,作为有经验的程序员,我们已经掌握了一门或者多门 ...
- 为网页生成二维码(jquery.qrcode.min.js)
做网站活动页面的时候,要为每个活动生成一个二维码,虽然简单,但还是习惯记录下来. jquery.qrcode.min.js是js的一个库,主流的浏览器都支持:IE6~10, Chrome, Firef ...
- AS3批量替换文件
在做项目时,经过会遇到资源替换问题.比如配音公司,提供了一批八九百个配音MP3文件,用到后面却发现有些配音不能正常使用.可能是十几个,也可能是一两百个.只能是配音公司重新提供.因为之前的配音资源,已经 ...
- [转] DDD领域驱动设计框架分享
从去年10月份开始,学了几个月的领域驱动设计(Domain Driven Design,简称DDD).主要是学习领域驱动设计之父Eric Evans的名著:<Domain-driven desi ...
- mongodb入门笔记
mongodb作为nosql中排名第一的数据库,近年来使用的人数越来越多,作为开发人员,非常有必要了解下mongodb数据库.下面就给大家介绍下mongodb数据库的基本知识,有不对的地方欢迎指正,Q ...