public void Given_AnEmptyIssuer_When_GetAuthenticatorRegistrationDataIsCalled_Then_AnArgumentExceptionIsThrown( String issuer) { ITotpProvider provider = new TotpProvider(); Assert.Throws <ArgumentException>(() => provider.GetAuthenticatorRegistrationData("ACCOUNTNAME", issuer)); }
public void GenerateSpecificHMacSha1Totp() { var seed = "werredsxsgfhtdfsde"; seed = seed.Trim(); var currentTime = (uint)AuthenticatorApp.Timestamp.UnixTimeStamp.GetCurrentUnixTimestampSeconds(); long T0 = 0; long X = 30; var T = (currentTime - T0) / X; var steps = T.ToString("X").ToUpper(); while (steps.Length < 16) { steps = "0" + steps; } var timeString = steps; var data = TotpProvider.GenerateTotp(Base32.Base32ToHex(seed), timeString, 6, TotpProvider.MacAlgorithmEnum.HmacSha1); Assert.AreEqual(GenerateTotpMicrosoft(TotpProvider.StringToByteArray(Base32.Base32ToHex(seed)), timeString, 6), data); }
public void Given_AnEmptyAccountName_When_GetAuthenticatorRegistrationDataIsCalled_Then_AnArgumentExceptionIsThrown( String accountName) { ITotpProvider provider = new TotpProvider(); Assert.Throws <ArgumentException>(() => provider.GetAuthenticatorRegistrationData(accountName, "ISSUER")); }
public void Given_ATimeBeforeUnixEpoch_When_GetCodeAtSpecificTimeIsCalled_Then_AnArgumentExceptionIsThrown( String time) { ITotpProvider provider = new TotpProvider(); Assert.Throws <ArgumentException>(() => provider.GetCodeAtSpecificTime("SECRETKEY", DateTimeOffset.Parse(time, CultureInfo.InvariantCulture))); }
public void Given_AnEmptySecretKey_When_GetCodeAtSpecificTimeIsCalled_Then_AnArgumentExceptionIsThrown( String secretKey) { ITotpProvider provider = new TotpProvider(); Assert.Throws <ArgumentException>(() => provider.GetCodeAtSpecificTime(secretKey, DateTimeOffset.Parse("2019-09-16", CultureInfo.InvariantCulture))); }
public void CalcHmacSha256Scenario1Desktop() { var result = TotpProvider.HmacSha(TotpProvider.MacAlgorithmEnum.HmacSha256, _encoding.GetBytes(Key), _encoding.GetBytes(Text)); var hexString = String.Join("", result.Select(a => a.ToString("x2"))); Assert.AreEqual(HMacSha256Expected, hexString); }
public void Given_AnEmptyCode_When_ValidateCodeIsCalled_Then_AnArgumentExceptionIsThrown( String code) { ITotpProvider provider = new TotpProvider(); Assert.Throws <ArgumentException>(() => provider.ValidateCode("SECRET", code, DateTimeOffset.Parse("2019-09-16 15:44:09 +02:00", CultureInfo.InvariantCulture))); }
private async Task confirmTotpSetup() { var totpProvider = new TotpProvider(Convert.FromBase64String(totpSetup.secret)); var resp = await client.PostAsJsonAsync("/a/auth/confirm2fa", new TwoFactorConfirmRequest { otpcode = totpProvider.getCode() }); resp.EnsureSuccessStatusCode(); }
public void Given_AnEmptySecretKey_When_GetAuthenticatorRegistrationDataIsCalled_Then_ANewSecretKeyIsGenerated( String secretKey) { ITotpProvider provider = new TotpProvider(); var result = provider.GetAuthenticatorRegistrationData("ACCOUNT_NAME", "ISSUER", secretKey); Assert.NotNull(result); Assert.False(String.IsNullOrWhiteSpace(result.SecretKey)); }
public void Given_AValidSecretKey_When_GetAuthenticatorRegistrationDataIsCalled_Then_ResultContainsTheEncodedSecretKey( String secretKey, String expected) { ITotpProvider provider = new TotpProvider(); var result = provider.GetAuthenticatorRegistrationData("ACCOUNT_NAME", "ISSUER", secretKey); Assert.NotNull(result); Assert.Equal(expected, result.ManualRegistrationKey); }
public void Given_AnIncorrectCode_When_ValidateCodeIsCalled_Then_InvalidResultIsReturned( String secret, String time, String code) { ITotpProvider provider = new TotpProvider(); var result = provider.ValidateCode(secret, code, DateTimeOffset.Parse(time, CultureInfo.InvariantCulture)); Assert.False(result); }
public void Given_AValidCodeAndValidTime_When_GetCodeAtSpecificTimeIsCalled_Then_TheCorrectCodeAndReminderIsReturned( String secret, String time, String expectedCode, int expectedRemainingSeconds) { ITotpProvider provider = new TotpProvider(); var result = provider.GetCodeAtSpecificTime(secret, DateTimeOffset.Parse(time, CultureInfo.InvariantCulture), out var remaining); Assert.Equal(expectedCode, result); Assert.Equal(TimeSpan.FromSeconds(expectedRemainingSeconds), remaining); }
public void Given_ACodeThatWouldBeCorrectXSecondsInTheFuture_When_ValidateCodeIsCalledWithoutTolerance_Then_InvalidResultIsReturned( String secret, String time, String code) { ITotpProvider provider = new TotpProvider(); var result = provider.ValidateCode(secret, code, DateTimeOffset.Parse(time, CultureInfo.InvariantCulture), TimeSpan.Zero); Assert.False(result); }
public async Task canLoginTwoFactor() { await confirmTotpSetup(); var totpProvider = new TotpProvider(Convert.FromBase64String(totpSetup.secret)); // attempt a 2fa login var resp = await client.PostAsJsonAsync("/a/auth/login2fa", new LoginRequestTwoFactor { username = username, password = AccountRegistrar.TEST_PASSWORD, otpcode = totpProvider.getCode() }); resp.EnsureSuccessStatusCode(); }
public static string GenerateTotpMicrosoft(byte[] keyBytes, string time, int returnDigits) { var array = TotpProvider.StringToByteArray(time); var array2 = TotpProvider.HmacSha(TotpProvider.MacAlgorithmEnum.HmacSha1, keyBytes, array); var num = (int)(array2[array2.Length - 1] & 15); var num2 = (int)(array2[num] & 127) << 24 | (int)(array2[num + 1] & 255) << 16 | (int)(array2[num + 2] & 255) << 8 | (int)(array2[num + 3] & 255); var text = (num2 % DigitsPower[returnDigits]).ToString(); while (text.Length < returnDigits) { text = "0" + text; } return(text); }
public void Given_ACodeThatWasCorrectXSecondsAgo_When_ValidateCodeIsCalledWithToleranceX_Then_ValidResultIsReturned( String secret, String time, String code, int toleranceInSeconds) { ITotpProvider provider = new TotpProvider(); var result = provider.ValidateCode(secret, code, DateTimeOffset.Parse(time, CultureInfo.InvariantCulture), TimeSpan.FromSeconds(toleranceInSeconds)); Assert.True(result); }
public void Given_CorrectRegistrationData_When_GetAuthenticatorRegistrationDataIsCalledWithoutAccountNamePrefixing_Then_TheCorrectUriIsReturned( String secretKey, String issuer, String accountName, String expectedQrCode) { ITotpProvider provider = new TotpProvider(); var result = provider.GetAuthenticatorRegistrationData(accountName, issuer, secretKey, false); Assert.NotNull(result); Assert.Equal(secretKey, result.SecretKey); Assert.Equal(accountName, result.AccountName); Assert.Equal(issuer, result.Issuer); Assert.Equal(expectedQrCode, result.QrCodeUri); }
public TwoFactorSetupModule(SContext serverContext) : base("/auth", serverContext) { Get <SetupTwoFactor>("/setup2fa", async(req, res) => { // check if two-factor ALREADY enabled if (currentUser.totpEnabled) { // otp is already enabled res.StatusCode = (int)HttpStatusCode.Conflict; return; } // we generate a new TOTP secret var seed = StringUtils.secureRandomString(TotpProvider.TOTP_SECRET_LENGTH); var seedBytes = Hasher.sha256(seed); currentUser.totp = seedBytes; serverContext.userManager.updateUser(currentUser); // return the seed await res.respondSerialized(new TotpSetupResponse { secret = Convert.ToBase64String(seedBytes) }); return; }); Post <ConfirmTwoFactor>("/confirm2fa", async(req, res) => { var validatedReq = await this.validateRequest <TwoFactorConfirmRequest>(req, res); if (!validatedReq.isValid) { return; } var confirmReq = validatedReq.request; // use TOTP provider to check code var provider = new TotpProvider(currentUser.totp); if (provider.verify(confirmReq.otpcode)) { // totp confirmed, enable totp and lock serverContext.userManager.setupTotpLock(currentUser, credential.token); res.StatusCode = (int)HttpStatusCode.OK; return; } res.StatusCode = (int)HttpStatusCode.Unauthorized; return; }); }
public void CalcHmacSha1Scenario1Desktop() { // Please refer to wikipedia for the test data: // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256.29 const string key = ""; const string text = ""; try { TotpProvider.HmacSha(TotpProvider.MacAlgorithmEnum.HmacSha1, _encoding.GetBytes(key), _encoding.GetBytes(text)); } catch (InvalidOperationException) { Assert.IsTrue(true); } }
/// <summary> /// Generate TOTP(HMacSha1) from test time /// </summary> /// <param name="time">Time</param> /// <returns>TOTP</returns> public string GenerateTotpHMacSha1FromTime(long time) { // Seed for HMAC-SHA1 - 20 bytes const string seed = "3132333435363738393031323334353637383930"; long T0 = 0; long X = 30; var T = (time - T0) / X; var steps = T.ToString("X").ToUpper(); while (steps.Length < 16) { steps = "0" + steps; } return(TotpProvider.GenerateTotp(seed, steps, "8", TotpProvider.MacAlgorithmEnum.HmacSha1)); }
/// <summary> /// Generate TOTP(HMacSha256) from test time /// </summary> /// <param name="time">Time</param> /// <returns>TOTP</returns> private static string GenerateTotpHMacSha256FromTime(long time) { // Seed for HMAC-SHA256 - 32 bytes const string seed32 = "3132333435363738393031323334353637383930" + "313233343536373839303132"; const long t0 = 0; const long x = 30; var T = (time - t0) / x; var steps = T.ToString("X").ToUpper(); while (steps.Length < 16) { steps = "0" + steps; } return(TotpProvider.GenerateTotp(seed32, steps, "8", TotpProvider.MacAlgorithmEnum.HmacSha256)); }
public void Given_ASecretKeyAndValidTime_When_GetValidCodesForPeriodIsCalled_Then_AValidCodeRangeIsReturned( String secret, String time, int pastToleranceSeconds, int futureToleranceSeconds, params String[] expectedCodes) { var provider = new TotpProvider(); var result = provider.GetValidCodesForPeriod(secret, DateTimeOffset.Parse(time, CultureInfo.InvariantCulture), TimeSpan.FromSeconds(pastToleranceSeconds), TimeSpan.FromSeconds(futureToleranceSeconds)) .ToArray(); Assert.Collection(result, expectedCodes .Select <String, Action <String> >(expected => code => Assert.Equal(expected, code)) .ToArray()); }
public AuthModule(SContext context) : base("/auth", context) { Post <CreateUser>("/create", async(req, res) => { var validatedCreateReq = await this.validateRequest <RegisterRequest>(req, res); if (!validatedCreateReq.isValid) { return; } var createReq = validatedCreateReq.request; // attempt to register user try { // register the user var user = serverContext.userManager.registerUser(createReq); serverContext.log.writeLine($"registered user {user.username}", Logger.Verbosity.Information); var token = serverContext.userManager.issueRootToken(user.id); // Return user details res.StatusCode = (int)HttpStatusCode.Created; await res.respondSerialized(new AuthedUserResponse { user = new AuthenticatedUser(user), token = token }); } catch (UserManagerService.UserAlreadyExistsException) { res.StatusCode = (int)HttpStatusCode.Conflict; return; } }); Post <LoginUser>("/login", async(req, res) => { var login = await validateAndCheckPassword <LoginRequest>(req, res); if (login.isValid) { // check two-factor if (login.user.totpEnabled) { // require login with otp code, but creds were good res.StatusCode = (int)HttpStatusCode.FailedDependency; return; } // issue a new token var token = serverContext.userManager.issueRootToken(login.user.id); // return user details res.StatusCode = (int)HttpStatusCode.OK; await res.respondSerialized(new AuthedUserResponse { user = new AuthenticatedUser(login.user), token = token }); } }); Post <LoginTwoFactor>("/login2fa", async(req, res) => { var login = await validateAndCheckPassword <LoginRequestTwoFactor>(req, res); if (login.isValid) { // this route is not to be used unless two factor is enabled if (!login.user.totpEnabled) { res.StatusCode = (int)HttpStatusCode.PreconditionFailed; return; } // use TOTP provider to check code var provider = new TotpProvider(login.user.totp); if (!provider.verify(login.request.otpcode)) { res.StatusCode = (int)HttpStatusCode.Unauthorized; return; } // issue a new token var token = serverContext.userManager.issueRootToken(login.user.id); // return user details res.StatusCode = (int)HttpStatusCode.OK; await res.respondSerialized(new AuthedUserResponse { user = new AuthenticatedUser(login.user), token = token }); } }); Post <DeleteUser>("/delete", async(req, res) => { var login = await validateAndCheckPassword <LoginRequest>(req, res); if (login.isValid) { // delete the account serverContext.userManager.deleteUser(login.user.id); // return success indication res.StatusCode = (int)HttpStatusCode.NoContent; return; } }); }
public void Given_AnIssuerWithColon_When_GetAuthenticatorRegistrationDataIsCalled_Then_AnArgumentExceptionIsThrown() { ITotpProvider provider = new TotpProvider(); Assert.Throws <ArgumentException>(() => provider.GetAuthenticatorRegistrationData("ACCOUNTNAME", "ISS:UER")); }