The simplest way is to extend your login model with an additional string for the authentication token. Then in our view we can show the QR code using: Model.EncodedSecret),Ģ56, 4, QRCodeErrorCorrectionLevel.QuiteGood)Īuthentication code and secret in hand we need to plumb it into our login procedure. Return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing)) Tag.MergeAttributes(new RouteValueDictionary(htmlAttributes)) Var url = string.Format("", size, HttpUtility.UrlEncode(data), errorCorrectionLevel.ToString(), margin) Throw new InvalidEnumArgumentException("errorCorrectionLevel", (int)errorCorrectionLevel, typeof(QRCodeErrorCorrectionLevel)) If (!Enum.IsDefined(typeof(QRCodeErrorCorrectionLevel), errorCorrectionLevel)) Throw new ArgumentOutOfRangeException("margin", margin, "Must be greater than or equal to zero.") Throw new ArgumentOutOfRangeException("size", size, "Must be greater than zero.") Public static MvcHtmlString QRCode(this HtmlHelper htmlHelper, string data, int size = 80, int margin = 4, QRCodeErrorCorrectionLevel errorCorrectionLevel = QRCodeErrorCorrectionLevel.Low, object htmlAttributes = null) This can be bundled into a HTML Helper such as: public static class QRCodeHtmlHelper We can tap into an open service offered by Google that generates QR codes for just this purpose. The QR code display is a particularly nice touch and deceptively simple to do. You should display the secret, an identifier (like and for ease of use display a QR code that they can scan directly with their authenticator. We then need to get this into the hands of our user. Usr.TwoFactorSecret = Base32Encoder.ToString(buffer) Using (var rng = RNGCryptoServiceProvider.Create()) If (String.IsNullOrEmpty(usr.TwoFactorSecret)) An example for this is: var usr = Users.GetByUsername() To generate the secret we take 10 random bytes and base32 encode them. I would recommend this Stack Overflow question as a starting point. Net does not have a Base32 encoder we need to make one ourselves or acquire one. The secret that we work against is a Base32 encoded string. Return (long)(DateTime.UtcNow - Uni圎poch).TotalSeconds / 30 If (password = GeneratePassword(secret, counter - i)) If (password = GeneratePassword(secret, counter + i)) If (password = GeneratePassword(secret))įor (int i = 1 i <= checkAdjacentIntervals i++) Public static bool IsValid(string secret, string password, Return password.ToString(new string('0', digits)) Int password = binary % (int)Math.Pow(10, digits) // 6 digits Using (var hmac = new HMACSHA1(key, true)) Var counter = BitConverter.GetBytes(iterationNumber) Public static string GeneratePassword( string secret, Return GeneratePassword(secret, GetCurrentCounter()) Public static string GeneratePassword(string secret) Public static readonly DateTime Uni圎poch = Below is a sample class that implements HOTP, TOTP and a validity check which will ensure that an incoming code is correct. The first step is implementing the HOTP and TOTP algorithms for use in our code. HOTP takes this counter, creates a HMAC hash and from this we generate our unique 6-digit authentication code. The count is then passed into the HMAC-Based One-Time Password Algorithm (HOTP) which is published under RFC 4226. The algorithm takes a known time (the start of the UNIX epoch) to act as a counter. We'll be using time-based one-time password algorithm which is an open standard published under RFC 6238. In addition, the techniques explored here will work for any authenticator that can support time based authentication. In our example we will look at using TFA using Google Authenticator in time based mode but the principles apply to whatever solution you choose to apply. Two Factor Authentication (TFA) is the process whereby we ask for another unique piece of information from a user at login that is generated using a thing that they must physically posess. To that end adding two factor authentication can help raise another barrier against malicious access to your sites. Whether this comes in the form of social engineering, poor code or user created vulnerabilities it is our job as developers to mitigate this insecurity as much as possible.
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |