<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      什么是兩步驗證


      ??兩步驗證,是指用戶登錄賬戶的時候,除了要輸入用戶名和密碼,還要求用戶輸入一個動態(tài)密碼,為帳戶添加了一層額外保護。這個動態(tài)密碼要么是專門的硬件,要么由用戶手機APP提供。即使入侵者竊取了用戶密碼,也會因不能使用用戶手機而無法登錄帳戶。許多游戲客戶端和網(wǎng)銀采用這種方式。以銀行為例,當用戶進行轉賬操作時,第一步輸入6位取款密碼,第二步輸入動態(tài)密碼器上數(shù)字,這個密碼器是開戶時銀行提供的硬件。


      動態(tài)密碼原理


      ??客戶端和服務器事先協(xié)商好一個密鑰K,用于一次性密碼的生成過程,此密鑰不被任何第三方所知道。此外,客戶端和服務器各有一個計數(shù)器C,并且事先將計數(shù)值同步。進行驗證時,客戶端對密鑰和計數(shù)器的組合(K,C)使用HMAC(Hash-based
      Message Authentication Code)算法計算一次性密碼,公式如下:HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))
      上面采用了HMAC-SHA-1,當然也可以使用HMAC-MD5等。HMAC算法得出的值位數(shù)比較多,不方便用戶輸入,因此需要截斷(Truncate)成為一組不太長十進制數(shù)(例如6位)。計算完成之后客戶端計數(shù)器C計數(shù)值加1。用戶將這一組十進制數(shù)輸入并且提交之后,服務器端同樣的計算,并且與用戶提交的數(shù)值比較,如果相同,則驗證通過,服務器端將計數(shù)值C增加1。如果不相同,則驗證失敗。

      業(yè)務流程

      ??如何開發(fā)這個功能呢?我們先理清它的流程:

      * 第一步:輸入常規(guī)帳號密碼,驗證成功后進入二次驗證頁面。
      * 第二步:二次驗證頁面要求用戶輸入動態(tài)密碼,用戶手機必須先通過APP綁定帳號后才能獲取動態(tài)密碼,APP推薦eagle2fa
      <http://www.eagle2fa.com/>。
      * 第三步:頁面生成二維碼,內(nèi)容是URI地址otpauth://totp/賬號?secret=密鑰
      ,用eagle2fa掃碼后綁定帳號,把密鑰保存在客戶端,如下圖所示:

      * 第四步:輸入APP上的6位數(shù)字,驗證通過進入用戶中心頁面。
      最重要的功能是生成二維碼和驗證動態(tài)密碼。
      組件選型

      googleauth是Google Authenticator的開源實現(xiàn)
      <dependency> <groupId>com.warrenstrange</groupId>
      <artifactId>googleauth</artifactId> <version>1.1.2</version> </dependency>
      zxing用于生成二維碼圖片
      <dependency> <groupId>com.google.zxing</groupId>
      <artifactId>javase</artifactId> <version>3.3.3</version> </dependency>
      也可以使用其他網(wǎng)站提供的的WEB API,譬如:
      http://qr.liantu.com/api.php?text=x x必須用UTF8編碼格式,x內(nèi)容出現(xiàn)&符號時用%26代替,換行符使用%0A
      關鍵代碼

      以下代碼演示怎么使用GoogleAuthenticator包:
      private static final GoogleAuthenticator googleAuthenticator = new
      GoogleAuthenticator(); /** * 由于只是演示,dao沒有操作數(shù)據(jù)庫,真實的場景必然要持久化 */ @Autowired
      private UserDao userDao; @PostConstruct public void init() {
      googleAuthenticator.setCredentialRepository(new ICredentialRepository() {
      @Override public String getSecretKey(String userName) { //根據(jù)帳號查詢secretKey
      return userDao.getSecretKey(userName); } @Override public void
      saveUserCredentials(String userName, String secretKey, int validationCode,
      List<Integer> scratchCodes) { //secretKey要保存在數(shù)據(jù)庫中
      userDao.saveUserCredentials(userName, secretKey); } });
      log.info("GoogleAuthenticator初始化成功"); }
      以下代碼是生成二維碼,uri的格式不能寫錯。
      // 必須按照這個格式,APP才能正常綁定 private static final String KEY_FORMAT =
      "otpauth://totp/%s?secret=%s"; /** * 生成二維碼鏈接 */ private String getQrUrl(String
      username) { //每次調用createCredentials都會生成新的secretKey GoogleAuthenticatorKey key =
      googleAuthenticator.createCredentials(username);
      log.info("username={},secretKey={}", username, key.getKey()); return
      String.format(KEY_FORMAT, username, key.getKey()); }
      以下是二次驗證方法:
      // 驗證動態(tài)密碼 username 帳號, code app上的6位數(shù)字 public boolean validCode(String
      username, int code) { return googleAuthenticator.authorizeUser(username, code);
      }
      點擊獲取完整代碼
      <https://gitee.com/cabbage/java-study-demo/tree/master/two-step-verify-demo>

      參考(部分摘抄的文字版權屬于原作者)

      https://blog.seetee.me/post/2011/google-two-step-verification/
      https://www.zhihu.com/question/20462696/answer/19670601

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          囯产精品久久久久久久久久99蜜桃 | 国产成人永久免费 | 亚洲AV无码高清 | 兔费A片免费看 | 台湾成人中文网 | 国产freexxxx性播放 | 午夜激情在线观看视频 | 三级黄带片 | 久久福利 | 男女男精品视频 |