iphone如何备份份Google Authenticator

详解Google Authenticator工作原理
发表于 08:28|
摘要:Google Authenticator是谷歌推出的一款动态口令工具,旨在解决大家Google账户遭到恶意攻击的问题。那么,Authenticator采用了哪些算法?又是如何实现的?且看本文技术解读。
【编者按】Google Authenticator是谷歌推出的一款动态口令工具,旨在解决大家Google账户遭到恶意攻击的问题,在手机端生成动态口令后,在Google相关的服务登陆中除了用正常用户名和密码外,需要输入一次动态口令才能验证成功,此举是为了保护用户的信息安全。那么,Authenticator采用了哪些算法?又是如何实现的?且看本文技术解读。
很多手机用户会使用
(谷歌身份认证)来生成认证令牌,与传统单因子密码不同,其采用的是更安全的双因子(2FA
)认证。FA是指结合密码以及实物(信用卡、SMS手机、令牌或指纹等生物标志)两种条件对用户进行认证的方法。只需要在手机上安装如此高大上的密码生成应用程序,就可以生成一个随着时间变化的一次性密码,用于帐户验证,而且这个应用程序不需要连接网络即可工作。
实际上Google Authenticator采用的算法是TOTP(Time-Based One-Time Password基于时间的一次性密码),其核心内容包括以下三点:
一个共享密钥(一个比特序列);
当前时间输入;
一个签署函数。
共享密码用于在手机端上建立账户。密码内容可以是通过手机拍照二维码或者手工输入,并会被进行base32加密。
手工密码的输入格式如下:
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
包含该令牌的二维码的内容是一个URL:
otpauth://totp/Google%?secret=xxxx&issuer=Google
时间输入(当前时间)
输入的时间值来自于手机本身,一旦我们获得密钥后,就无需与服务器再进行通信了。但是最重要一点是务必确保手机上的时间是正确的,因为往后的步骤服务器会多次重复使用之前得到的时间值,服务器只会认准这个值。进一步说,服务器会比对所有提交的令牌以确认哪一个是你输入并提交的。
签署所使用的方法是HMAC-SHA1。HMAC的全称是Hash-based message authentication
code(哈希运算消息认证码),以一个密钥和一个消息为输入,生成一个消息摘要作为输出,这里以SHA1作为消息输入。使用HMAC的原因是:只有用户本身知道正确的输入密钥,因此会得到唯一的输出。其算法可以简单表示为:
hmac = SHA1(secret + SHA1(secret + input))
事实上,TOTP是HMAC-OTP(基于HMAC的一次密码生成)的超集,区别是TOTP以当前时间作为输入,而HMAC-OTP以自增计算器作为输入,该计数器使用时需要进行同步。
首先,要进行密钥的base32加密。虽然谷歌上的密钥格式是带空格的,不过base32拒绝空格输入,并只允许大写。所以要作如下处理:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
第二步要获取当前时间值,这里使用的是函数,或者可以用纪元秒。
input = CURRENT_UNIX_TIME()
在Google Authenticator中,input值拥有一个有效期。因为如果直接根据时间进行计算,结果将时刻发生改变,那么将很难进行复用。Google Authenticator默认使用30秒作为有效期(时间片),最后input的取值为从Unix
epoch(日 00:00:00)来经历的30秒的个数。
input = CURRENT_UNIX_TIME() / 30
最后一步是进行HMAC-SHA1运算
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
input = CURRENT_UNIX_TIME() / 30
hmac = SHA1(secret + SHA1(secret + input))
至此,2FA所需的两个因子都已准备就绪了。但是HMAC运算后的结果会是20字节即40位16进制数,应该没有人会愿意每次都输入这么长的密码。我们需要的是常规6位数字密码!
要实现这个愿望,首先要对20字节的SHA1进行瘦身。我们把SHA1的最后4个比特数(每个数的取值是0~15)用来做索引号,然后用另外的4个字节进行索引。因此,索引号的操作范围是15+4=19,加上是以零开始,所以能完整表示20字节的信息。4字节的获取方法是:
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
然后将它转化为标准的32bit无符号整数(4 bytes = 32 bit):
large_integer = INT(four_bytes)
最后再进行7位数(1百万)取整,就可得到6位数字了:
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000
这也是我们最后要的目标结果,整个过程总结如下:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
input = CURRENT_UNIX_TIME() / 30
hmac = SHA1(secret + SHA1(secret + input))
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000
我在这里准备了一个完整可执行的GO语言程序,感兴趣的朋友请点击点击
进行查看。
英文出自:
(责编/夏梦竹)
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章google authenticator 谷歌身份验证器
时间: 17:06:26
&&&& 阅读:581
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&How to add extra security to your MVC web application, using two factor authentication.
What is Two Factor Authentication?
is a way to authenticate users using two of the three valid authentication factors: something the user knows (password, PIN, etc), something the user has (smart card, phone, ATM card, etc.), and something the user is (biometric data, including figerprints). In the case of this article, we will be using something the user knows, a password, and something the user has, a smartphone.&
What is Google Authenticator?&
is a software based two-factor authentication token. It is available on iOS, Android, and BlackBerry operating systems. It provides a 6 digit, time or counter based number that acts as the 2nd factor for our two factor authentication.
describing Google Authenticator.&
How does it work?&
Google Authenticator implements the algorithms defined in
and . The first is a counter based implementation of two-factor authentication. The second is a time-based implementation. First, the server and the user agree on a secret key to use as the seed value for the hashing function. The user can type in this key to Google Authenticator or use a QR code to automatically set up your application. Then Google Authenticator uses one of the above algorithms to generate a code to be entered during authentication. Your server will then use the same algorithm and secret key to check the code. Once the secret key has been agreed on, the only data passing between the client and your server will be the 6-digit key generated by the Google Authenticator application. At no time does any of this data pass through Google‘s servers.&
Counter Based One Time Password Generation
To generate a one-time password, we need three pieces of information, the secret key, the counter number, and the number of digits the output should be. Since we are using Google Authenticator, we are limited to 6 digits.&
Here is the full GeneratePassword method:
Hide & Copy Code
public static string GeneratePassword(string secret, long iterationNumber, int digits = 6)
byte[] counter = BitConverter.GetBytes(iterationNumber);
if (BitConverter.IsLittleEndian)
Array.Reverse(counter);
byte[] key = Encoding.ASCII.GetBytes(secret);
HMACSHA1 hmac = new HMACSHA1(key, true);
byte[] hash = puteHash(counter);
int offset = hash[hash.Length - 1] & 0
int binary =
((hash[offset] & 0x7f) && 24)
| ((hash[offset + 1] & 0xff) && 16)
| ((hash[offset + 2] & 0xff) && 8)
| (hash[offset + 3] & 0xff);
int password = binary % (int)Math.Pow(10, digits);
Let‘s go through what we are doing. First, we convert the iteration number to a byte[], which can be hashed using the
hash method. The iteration number should be incremented on the client and server every time authentication succeeds. We use the managed HMAC-SHA-1 hashing method available from the
class. Next we compute the hash for the current value of the counter. The next part of the code extracts the binary value of a 4 byte integer, then shrinks it to the number of digits required. That‘s it. The entire algorithm in 25 lines.
has a good example and description of what is happening, which I will copy and paste here:
Hide & Shrink
& Copy Code
Example of HOTP Computation for Digit = 6
The following code example describes the extraction of a dynamic
binary code given that hmac_result is a byte array with the HMAC-
SHA-1 result:
int offset
hmac_result[19] & 0
int bin_code = (hmac_result[offset]
& 0x7f) && 24
| (hmac_result[offset+1] & 0xff) && 16
| (hmac_result[offset+2] & 0xff) &&
| (hmac_result[offset+3] & 0xff) ;
SHA-1 HMAC Bytes (Example)
-------------------------------------------------------------
| Byte Number
-------------------------------------------------------------
|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|
-------------------------------------------------------------
| Byte Value
-------------------------------------------------------------
|1f|86|98|69|0e|02|ca|16|61|85|50|ef|7f|19|da|8e|94|5b|55|5a|
-------------------------------***********----------------++|
* The last byte (byte 19) has the hex value 0x5a.
* The value of the lower 4 bits is 0xa (the offset value).
* The offset value is byte 10 (0xa).
* The value of the 4 bytes starting at byte 10 is 0x50ef7f19,
which is the dynamic binary code DBC1.
* The MSB of DBC1 is 0x50 so DBC2 = DBC1 = 0x50ef7f19 .
* HOTP = DBC2 modulo 10^6 = 872921.
We treat the dynamic binary code as a 31-bit, unsigned, big-endian
the first byte is masked with a 0x7f.
We then take this number modulo 1,000,000 (10^6) to generate the 6-
digit HOTP value 872921 decimal.
Time Based One Time Password Generation
defines the time based implementation of the one time password generation. Time based one time password generation builds on the counter based approach above. It is exactly the same, except it automatically defines the counter based on intervals of time since the
UTC). Technically, the RFC allows for any start date and time interval, but Google Authenticator requires the Unix epoch and a 30 second time interval. What this means is that we can get the current one-time-password using only the secret key. Here is how:
Hide & Copy Code
public static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static string GetPassword(string secret)
long counter = (long)(DateTime.UtcNow - UNIX_EPOCH).TotalSeconds / 30;
return HashedOneTimePassword.GeneratePassword(secret, counter);
As you can see, we are just getting the number of 30 second intervals since the Unix epoch and using that as our counter value. This means that the clock on both the client and the server need to be kept in sync with each other. This is commonly done with the .
How do I put it to use?
Well, now we have covered how the code works, the next question is how do you use it? I have created some extra overloads for the GetPassword method for time-based generation, and added an IsValid method.
Hide & Copy Code
public static bool IsValid(string secret, string password, int checkAdjacentIntervals = 1)
if (password == GetPassword(secret))
for (int i = 1; i &= checkAdjacentI i++)
if (password == GetPassword(secret, GetCurrentCounter() + i))
if (password == GetPassword(secret, GetCurrentCounter() - i))
IsValid helps a little with clock skew by checking adjacent intervals for the password as well. This can help improve user experience a lot, because it doesn‘t require the clocks to be perfectly aligned.&
Create the MVC Web Application
Create a new MVC 3 Web Application using the "New Project" wizard in Visual Studio 2010. Be sure to select "Internet" application in the wizard. This will create the default Account controller and views needed for forms authentication.
Create the TwoFactorProfile Class
Next we create a Profile class that inherits from . This will store the 2 factor secret for a given user.
Hide & Shrink
& Copy Code
public class TwoFactorProfile : ProfileBase
public static TwoFactorProfile CurrentUser
return GetByUserName(Membership.GetUser().UserName);
public static TwoFactorProfile GetByUserName(string username)
return (TwoFactorProfile)Create(username);
public string TwoFactorSecret
return (string)base["TwoFactorSecret"];
base["TwoFactorSecret"] =
Modify the web.config
Modify the &system.web&&profile& element to inherit from the TwoFactorProfile class we just created:
Hide & Copy Code
&profile inherits="TwoFactorWeb.TwoFactorProfile"&
Modify AccountController
We need to modify AccountController in a few places. First, the Register action needs to be modified to send the user to the ShowTwoFactorSecret page, so they can set up their Google Authenticator. In the Register action, modify the RedirectToAction from:
Hide & Copy Code
return RedirectToAction("Index", "Home");
Hide & Copy Code
return RedirectToAction("ShowTwoFactorSecret", "Account");
Next we create the ShowTwoFactorSecret action:
Hide & Shrink
& Copy Code
[Authorize]
public ActionResult ShowTwoFactorSecret()
string secret = TwoFactorProfile.CurrentUser.TwoFactorS
if (string.IsNullOrEmpty(secret))
byte[] buffer = new byte[9];
using (RandomNumberGenerator rng = RNGCryptoServiceProvider.Create())
rng.GetBytes(buffer);
This just generates a new random 10 character secret, then shows it to the user in Base32 encoded format, which is how Google Authenticator expects the user to enter it. Feel free to create your secret any way you want, but it needs to be at least 10 characters or Google Authenticator will complain.
Finally, we change the LogOn action to check the code provided by the user to ensure it is valid. Our new LogOn action is below:
Hide & Shrink
& Copy Code
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
if (ModelState.IsValid)
if (Membership.ValidateUser(model.UserName, model.Password))
var profile = TwoFactorProfile.GetByUserName(model.UserName);
if (profile != null && !string.IsNullOrEmpty(profile.TwoFactorSecret))
if (TimeBasedOneTimePassword.IsValid(profile.TwoFactorSecret, model.TwoFactorCode))
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length & 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
return Redirect(returnUrl);
return RedirectToAction("Index", "Home");
ModelState.AddModelError("", "The two factor code is incorrect.");
ModelState.AddModelError("", "The two factor code is incorrect.");
ModelState.AddModelError("", "The user name or password provided is incorrect.");
Modify AccountModels
To make the new LogOn and ShowTwoFactorSecret actions work, we need to add a field to the LogOnModel class:
Hide & Copy Code
[Required]
[Display(Name = "Google Authenticator Code")]
public string TwoFactorCode {
and create our new TwoFactorSecret class:
Hide & Copy Code
public class TwoFactorSecret
public string EncodedSecret {
Modify the LogOn.cshtml View
Now we modify the LogOn view to add the new TwoFactorCode field the user needs to enter:
Hide & Copy Code
&div class="editor-label"&
@Html.LabelFor(m =& m.TwoFactorCode)
&div class="editor-field"&
@Html.TextBoxFor(m =& m.TwoFactorCode)
@Html.ValidationMessageFor(m =& m.TwoFactorCode)
Create the ShowTwoFactorSecret View
Finally, we create the ShowTwoFactorSecret view:&
Hide & Copy Code
@model TwoFactorWeb.Models.TwoFactorSecret
ViewBag.Title = "ShowTwoFactorSecret";
&h2&Show Two Factor Secret&/h2&
Add the code below to Google Authenticator:
@Html.QRCode(string.Format("otpauth://totp/MY_APP_LABEL?secret={0}", Model.EncodedSecret))
@Model.EncodedSecret
As you can see, we show an image of a QR code the user can scan and we also show the secret as a string the user can manually enter. The format of the QR code is defined .
See the result
After registering as a new user in the web application, you should see a screen like the following:
At this point, you should scan the QR code with the Google Authenticator app, or enter the code below the QR code manually:
Now, when you log in, you should see a new field to enter your "Google Authenticator Code":
Just enter the current 6-digit code on the Google Authenticator screen for your application:
If you entered your username, password and code correctly, you should be able to log in.标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/taogulao/p/4546585.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!52被浏览16584分享邀请回答34 条评论分享收藏感谢收起

我要回帖

更多关于 如何从icloud恢复备份 的文章

 

随机推荐