在Google身份验证器应用中,您可以扫描二维码或手动输入发卡行提供的密钥。
在以下屏幕截图中,您可以看到Google Security设置中的2FA设置,显示如何通过第二种方法获取TOTP。
我的问题是:这个密钥是如何生成的?
我正在尝试使用Google身份验证器为我的网站支持2FA,我找到了很多关于如何生成QR码的参考和文档,但没有提到替代方法。
修改
为了更清楚一点,我在Grails 3 webapp中使用Google身份验证器支持2FA。我已经通过为每个用户生成一个密钥(Base32
字符串)来实现整个用户流程,为用户扫描提供QR码,并在登录时验证TOTP。我用作依赖项:
org.jboss.aerogear:aerogear-otp-java
,aerogear OTP方便地验证来自GA的TOTP的用户密钥org.grails.plugins:qrcode
,qrcode Grails plugin生成二维码我的问题是关于在Google身份验证器应用中添加新条目的两种方法: 1.扫描二维码(我身边一切都好) 2.手动键入帐户名称和字母代码(在我的第一个屏幕截图中,代码在Google安全设置中提供)
你可以看到GA for Android的解释性截图:
如何生成并提供此类代码(从第一个屏幕截图中的fzee
开始,并在第二个屏幕中为用户命名为“提供密钥”)?我确定它是在QR码中编码的相同数据字符串的编码,但我不知道哪个(不仅仅是Base32
)。
答案 0 :(得分:2)
key = secret
密钥应与您生成的密钥相同。只需打开谷歌身份验证器并手动将其添加为密钥即可对其进行测试。
在以下链接中查看文档: https://support.google.com/accounts/answer/1066447?co=GENIE.Platform%3DiOS&hl=en
答案 1 :(得分:1)
Google身份验证器设置QR代码是基于一些事情生成的,其中一个是“密钥”,因此根据您用于构建到您网站的代码库,通常首先生成“密钥”然后使用该密钥生成QR码。
如果你看一下这个node.js模块,你可以看到我在说什么
// generate base32 secret
var secret = GA.encode('base 32 encoded user secret') || GA.secret();
// get QRCode in SVG format
var qrCode = GA.qrCode('akanass', 'otp.js', secret);
https://github.com/njl07/otp.js/#qrcode-generation
这是另一个可以手动生成QR码的示例网站,
您可以提供Label, User, Key and URL
,然后生成QR码。
https://dan.hersam.com/tools/gen-qr-code.html
让我知道您尝试使用哪些代码库将其实现到您的网站中,然后我可以帮助您跟踪生成密钥的位置
答案 2 :(得分:0)
public class HomeController : Controller
{
private const string key = "key"; // any 10-12 char string for use as private key in google authenticator
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel login)
{
string message = "";
bool status = false;
//check username and password form our database here
//for demo I am going to use Admin as Username and Password1 as Password static value
if (login.Username == "sanket" && login.Password == "123")
{
status = true; // show 2FA form
message = "2FA Verification";
Session["Username"] = login.Username;
//2FA Setup
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
string UserUniqueKey = login.Username + key; //as Its a demo, I have done this way. But you should use any encrypted value here which will be unique value per user
Session["UserUniqueKey"] = UserUniqueKey;
var setupInfo = tfa.GenerateSetupCode("Sanket Security", login.Username, UserUniqueKey, 300, 300);
ViewBag.BarcodeImageUrl = setupInfo.QrCodeSetupImageUrl;
ViewBag.SetupCode = setupInfo.ManualEntryKey;
}
else
{
message = "Invalid credential";
}
ViewBag.Message = message;
ViewBag.Status = status;
return View();
}
public ActionResult MyProfile()
{
if (Session["Username"] == null || Session["IsValid2FA"] == null || !(bool)Session["IsValid2FA"])
{
return RedirectToAction("Login");
}
ViewBag.Message = "Welcome " + Session["Username"].ToString();
return View();
}
public ActionResult Verify2FA()
{
var token = Request["passcode"];
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
string UserUniqueKey = Session["UserUniqueKey"].ToString();
bool isValid = tfa.ValidateTwoFactorPIN(UserUniqueKey, token);
if (isValid)
{
Session["IsValid2FA"] = true;
return RedirectToAction("MyProfile", "Home");
token=string.Empty;
}
return RedirectToAction("Login", "Home");
}
}
}
答案 3 :(得分:0)
And View
@model _2FAGoogleAuthenticator.ViewModel.LoginModel
@{
ViewBag.Title = "Login";
}
<h2>Login</h2>
@* Here we will add 2 form, 1 for Login and another one for 2FA token verification form *@
@if (ViewBag.Status == null || !ViewBag.Status)
{
<!--Show login form here, Viewbag.Status is used for check is already veirfied from our database or not-->
<div>@ViewBag.Message</div>
<div>
@using (Html.BeginForm())
{
<div class="form-group">
<label for="Username">Username : </label>
@Html.TextBoxFor(a => a.Username, new { @class = "form-control"})
</div>
<div class="form-group">
<label for="Password">Password : </label>
@Html.TextBoxFor(a => a.Password, new { @class="form-control", type="password"})
</div>
<input type="submit" value="Login" class="btn btn-default" />
}
</div>
}
else
{
<!--Show 2FA verification form here-->
<div>@ViewBag.Message</div>
<div>
<img src="@ViewBag.BarcodeImageUrl"/>
</div>
<div>
**Manual Setup Code : @ViewBag.SetupCode**
</div>
<div>
@using (Html.BeginForm("Verify2FA","Home", FormMethod.Post))
{
<input type="text" name="passcode" />
<input type="submit" class="btn btn-success" />
}
</div>
}