为了提高账号的安全性和保护用户的隐私,出身了许多其他的认证办法,OTP 便是个中的一种。
二、OTP先容一次性密码(One Time Password,简称OTP),又称 动态密码 或 单次有效密码,是指打算器系统或其他数字设备上只能利用一次的密码,有效期为只有一次登录会话或交易。OTP 避免了一些与传统基于(静态)密码认证干系系的缺陷;一些实现还纳入了双成分认证,确保单次有效密码须要访问一个人有的某件事物(如内置 OTP 打算器的小钥匙挂件设备)以及一个人知道的某件事物(如 PIN)。
让我们分开来先容下,不同实现办法的事理。
4.1 HOTP实现事理HOTP 利用哈希算法和韶光戳来天生具有时效性的一次性密码。HOTP 的实现事理紧张包括以下几个方面:
秘钥天生:在利用 HOTP 进行身份验证之前,须要天生一个与客户端预共享的密钥 K。该密钥可以通过安全随机数天生器天生,并保存在做事端和客户端中。韶光戳天生:做事端和客户端都有一个计数器 C,每次进行身份验证时,客户端会向做事端发送计数器的值,做事端会将该值与自己掩护的计数器值进行比较。为了防止重放攻击,还可以通过韶光戳天生器天生一个 T 值,客户端和做事端各自独立地天生 T 值,并将 T 值与计数器稠浊后作为 HMAC-SHA1 函数的输入。HMAC-SHA1 打算:客户端和做事端利用相同的密钥 K 和经由稠浊的 T 值和计数器 C,分别打算 HMAC-SHA1 哈希值 H1 和 H2。HOTP 利用的 HMAC-SHA1 算法具有防修改性和伪随机性,担保了打算结果的不可预测性和安全性。动态密码天生:根据打算出的哈希值 H1 或 H2,取其末了 4 位(或其他固定位数),并进行截断、整形和模运算等操作,得到一个 6 位的一次性密码。这个密码是具有时效性的,只有在当前韶光段内有效。验证流程:客户端将天生的一次性密码发送给做事端,做事端基于相同的打算办法和密钥,打算出一次性密码,并与客户端发送的密码进行比较。如果验证通过,则认为该客户正直当。4.2 TOTP实现事理与 HOTP 不同的是,TOTP 利用的不是计数器,而是韶光戳作为输入进行哈希打算。TOTP 的实现事理紧张包括以下几个方面:
秘钥天生:在利用 TOTP 进行身份验证之前,须要天生一个与客户端预共享的密钥 K。这个密钥可以通过安全随机数天生器天生,并保存在做事端和客户端中。韶光戳天生:客户端和做事端都有一个韶光戳 T0,在 T0 的根本上每隔一段韶光(比如 30 秒)天生一个新的韶光戳 T,并将其转换为整型格式。HMAC-SHA1 打算:客户端和做事端利用相同的密钥 K 和当前韶光戳 T,分别打算 HMAC-SHA1 哈希值 H1 和 H2。HMAC-SHA1 算法具有防修改性和伪随机性,担保了打算结果的不可预测性和安全性。动态密码天生:根据打算出的哈希值 H1 或 H2,取其末了 4 位(或其他固定位数),并进行截断、整形和模运算等操作,得到一个 6 位的一次性密码。这个密码是具有时效性的,只有在当前韶光段内有效。验证流程:客户端将天生的一次性密码发送给做事端,做事端基于相同的打算办法和密钥,打算出一次性密码,并与客户端发送的密码进行比较。如果验证通过,则认为该客户正直当。4.3 CROTPCROTP 是一种利用寻衅和相应办法来进行身份验证的 OTP 机制。与 HOTP 和 TOTP 不同,它不是在客户端本地天生一次性密码,而是由做事端发起寻衅并由客户端进行相应打算。寻衅-相应 OTP 的实现事理紧张包括以下几个方面:
秘钥天生:在利用寻衅-相应 OTP 进行身份验证之前,同样须要天生一个与客户端预共享的密钥 K。这个密钥可以通过安全随机数天生器天生,并保存在做事端和客户端中。寻衅天生:做事端发起一个随机化的寻衅 C,常日为一个 64 位(或更多)长度的随机数,将其发送给客户端。相应打算:客户端收到做事端发起的寻衅后,将寻衅值和密钥 K 作为 HMAC-SHA1 函数的输入进行一次哈希打算,得到一个固定长度的哈希值 H。然后将该哈希值的末了 6 位(或其他固定位数)返回给做事端作为相应结果。验证流程:做事端利用相同的密钥 K 和当前韶光戳 T,将客户端返回的哈希值进行验证。做事端将收到的哈希值与自己打算出的 H 值进行比较,如果相同,则认为该客户正直当。五、HMACHMAC是密钥干系的哈希运算认证码(Hash-based Message Authentication Code)的缩写,是一种利用密码学中的散列函数来进行认证的一种机制。
HMAC 中所利用的单向散列函数并不仅限于一种,任何高强度的单向散列函数都可以被用于 HMAC,如果将来设计出的新的单向散列函数,也同样可以利用。利用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所布局的HMAC,分别称为HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-384、HMAC-SHA-512。
HMAC 将一个密钥 K 和一个 M 作为输入,经由一系列的哈希打算得到一个固定长度的 MAC(Message Authentication Code),并将该 MAC 用于验证的真实性或防止被修改。
5.1 HOTP中的HMACHOTP 算法中,首先须要天生一个对称密钥 K(由做事端和客户端共享),以及一个初始计数器值 C(也是由做事端和客户端共享)。然后,利用 HMAC-SHA1 算法打算一次性密码。
scss复制代码HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))
上面采取了 HMAC-SHA-1,当然也可以利用其他的散列算法。HMAC 算法得出的值位数比较多,未便应用户输入,因此须要截断(Truncate)成为一组不太长十进制数(例如6位)。打算完成之后客户端计数器 C 计数值加1。
5.2 TOTP中的HMAC与 HOTP 不同的是,TOTP 中的计数器不再是一个静态值,而是基于韶光产生的动态值。也便是公式中的 C 变革了。
六、OTP代码实现引入依赖包(Github 上一位大佬的,利用特殊大略)。
xml复制代码<dependency> <groupId>com.github.bastiaanjansen</groupId> <artifactId>otp-java</artifactId> <version>2.0.1</version></dependency>
6.1 HOTP的JAVA实现
java复制代码/ HOTP实现 /static void hotp() { // 天生密钥 byte[] secret = SecretGenerator.generate(); HOTPGenerator hotp = new HOTPGenerator.Builder(secret) // 一次性密码的长度 .withPasswordLength(6) // 散列算法 .withAlgorithm(HMACAlgorithm.SHA512) .build(); // 计数器值 int counter = 2; // 天生一次性密码 String code = hotp.generate(counter); System.out.println("hotp天生的一次性密码:" + code); // 验证一次性密码 boolean verify = hotp.verify(code, counter); System.out.println("hotp验证一次性密码结果:" + verify);}
6.2 TOTP的JAVA实现
java复制代码/ TOTP实现 /static void totp() { // 天生密钥 byte[] secret = SecretGenerator.generate(); TOTPGenerator totp = new TOTPGenerator.Builder(secret) .withHOTPGenerator(builder -> { // 一次性密码的长度 builder.withPasswordLength(6); // 散列算法 builder.withAlgorithm(HMACAlgorithm.SHA512); }) // 韶光周期 .withPeriod(Duration.ofSeconds(30)) .build(); // 天生一次性密码 String code = totp.now(); System.out.println("totp天生的一次性密码:" + code); boolean verify = totp.verify(code); System.out.println("totp验证一次性密码结果:" + verify);}
6.3 利用
让我们来调用一次看看。
java复制代码public static void main(String[] args) { hotp(); totp();}
打印如下:
arduino复制代码hotp天生的一次性密码:971935hotp验证一次性密码结果:truetotp天生的一次性密码:001566totp验证一次性密码结果:true
6.4 调试
天生otpauth。
java复制代码System.out.println(totp.getURI("issuer","account"));
大概这个样子:
ruby复制代码otpauth://totp/issuer:account?period=30&digits=6&secret=6AVUZT5NK2AUJNQT2TZK27NIEW334AYS&issuer=issuer&algorithm=SHA512
找一个二维码天生网站。
可以手机下载 Google Authenticator,扫码即可。
天生的一次性密码,可以用上边的验证代码来调试。