Google Authenticator:将其与您自己的Java身份验证服务器配合使用
Google Authenticator主要用于通過(guò)兩因素身份驗(yàn)證訪問(wèn)Google服務(wù)。 但是,您可以利用Google Authenticator生成基于時(shí)間的密碼,以供您的服務(wù)器進(jìn)行認(rèn)證。 這樣的服務(wù)器的實(shí)現(xiàn)在Java中非常簡(jiǎn)單,您可以從Google Authenticator PAM模塊的源代碼中獲得啟發(fā)。 在這篇博客文章中,我們將在Java類中簡(jiǎn)單介紹一下TOTP算法。
生成密鑰
- 為了生成密鑰,我們將使用隨機(jī)數(shù)生成器填充所需大小的字節(jié)數(shù)組。 在這種情況下,我們想要:
- 16個(gè)字符的Base32編碼密鑰:由于x字節(jié)的Base32編碼生成8x / 5個(gè)字符,因此我們將10個(gè)字節(jié)用作密鑰。
一些臨時(shí)代碼(使用Google的行話)。
// Allocating the buffer byte[] buffer =new byte[secretSize + numOfScratchCodes * scratchCodeSie];// Filling the buffer with random numbers. // Notice: you want to reuse the same random generator // while generating larger random number sequences. new Random().nextBytes(buffer);現(xiàn)在我們要提取對(duì)應(yīng)于密鑰的字節(jié),并使用Base32編碼對(duì)其進(jìn)行編碼。 我正在使用Apache Common Codec庫(kù)來(lái)獲取編解碼器實(shí)現(xiàn):
// Getting the key and converting it to Base32 Base32 codec = new Base32(); byte[] secretKey = Arrays.copyOf(buffer, secretSize); byte[] bEncodedKey = codec.encode(secretKey); String encodedKey = new String(bEncodedKey);將密鑰加載到Google Authenticator中
您可以手動(dòng)將密鑰加載到Google Authenticator中,或生成QR條碼以使應(yīng)用程序從中加載密鑰。 如果要使用Google服務(wù)生成QR條碼,則可以使用以下代碼生成相應(yīng)的URL:
public static String getQRBarcodeURL(String user,String host,String secret) {String format = "https://www.google.com/chart?chs=200x200&chld=M%%7C0&cht=qr&chl=otpauth://totp/%s@%s%%3Fsecret%%3D%s";return String.format(format, user, host, secret); }驗(yàn)證碼
現(xiàn)在,我們已經(jīng)生成了密鑰,并且我們的用戶可以將其加載到他們的Google Authenticator應(yīng)用程序中,我們需要驗(yàn)證生成的驗(yàn)證碼所需的代碼。 這是RFC 6238中指定的算法的Java實(shí)現(xiàn):
private static boolean check_code(String secret,long code,long t)throws NoSuchAlgorithmException,InvalidKeyException {Base32 codec = new Base32();byte[] decodedKey = codec.decode(secret);// Window is used to check codes generated in the near past.// You can use this value to tune how far you're willing to go. int window = 3;for (int i = -window; i <= window; ++i) {long hash = verify_code(decodedKey, t + i);if (hash == code) {return true;}}// The validation code is invalid.return false; }private static int verify_code(byte[] key,long t)throws NoSuchAlgorithmException,InvalidKeyException {byte[] data = new byte[8];long value = t;for (int i = 8; i-- > 0; value >>>= 8) {data[i] = (byte) value;}SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1");Mac mac = Mac.getInstance("HmacSHA1");mac.init(signKey);byte[] hash = mac.doFinal(data);int offset = hash[20 - 1] & 0xF;// We're using a long because Java hasn't got unsigned int.long truncatedHash = 0;for (int i = 0; i < 4; ++i) {truncatedHash <<= 8;// We are dealing with signed bytes:// we just keep the first byte.truncatedHash |= (hash[offset + i] & 0xFF);}truncatedHash &= 0x7FFFFFFF;truncatedHash %= 1000000;return (int) truncatedHash; }結(jié)論
現(xiàn)在,您可以使用Google Authenticator應(yīng)用程序,并使用它為您的用戶生成基于時(shí)間的密碼,并根據(jù)您自己的身份驗(yàn)證服務(wù)器進(jìn)行身份驗(yàn)證。
如您所見(jiàn),所需的代碼非常簡(jiǎn)單,并且所有必需的加密功能均由運(yùn)行時(shí)本身提供。 唯一的麻煩是處理Java中的簽名類型。 請(qǐng)享用!
參考: Google身份驗(yàn)證器:在The Gray Blog上與我們的JCG合作伙伴 Enrico Crisostomo一起在您自己的Java身份驗(yàn)證服務(wù)器上使用 。
相關(guān)文章 :
- Android Google Maps教程
- Google地圖的開(kāi)放替代品
- Java中的Google ClientLogin實(shí)用程序
- JBoss 4.2.x Spring 3 JPA Hibernate教程
- Spring MVC3 Hibernate CRUD示例應(yīng)用程序
- GWT Spring和Hibernate進(jìn)入數(shù)據(jù)網(wǎng)格世界
- GWT 2 Spring 3 JPA 2 Hibernate 3.5教程
翻譯自: https://www.javacodegeeks.com/2011/12/google-authenticator-using-it-with-your.html
總結(jié)
以上是生活随笔為你收集整理的Google Authenticator:将其与您自己的Java身份验证服务器配合使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在银行如何给孩子存钱?
- 下一篇: 无需重新部署Eclipse和Tomcat