private void TestSHA512AndAssert(Key key, int digits, DateTime time, string expected) { var otp = new TimeBasedOtpGenerator(key, digits, new SHA512HMACAlgorithm()); var result = otp.GenerateOtp(time); Assert.AreEqual(expected, result); }
public string GenerateOtpCodeForServerAccount(AccountModel model) { var serverAccount = model.ServerAccountSettings.Query().First(); var otpAccount = model.OtpAccounts.Query().First(r => r.Id == serverAccount.OtpAccountId); var totpcode = new TimeBasedOtpGenerator( new Key(otpAccount.Secret), otpAccount.Digits, new SHA1HMACAlgorithm()); return(totpcode.GenerateOtp(DateTime.UtcNow)); }
public void ValidateOtp_test_validates_with_an_empty_validity_period() { var key = Sha1ReferenceKey; var generator = new TimeBasedOtpGenerator(key, 8); var currentTime = new DateTime(2033, 5, 18, 3, 33, 20, DateTimeKind.Utc); var zeroSeconds = TimeSpan.FromSeconds(0); Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(-30), zeroSeconds), "30 seconds prior should be invalid"); Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(-01), zeroSeconds), "1 second prior should be valid (due to a 30-second precision)"); Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+00), zeroSeconds), "The exact time should be valid"); Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+01), zeroSeconds), "1 seconds after should be valid (due to a 30-second precision)"); Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(+30), zeroSeconds), "30 seconds after should be invalid"); }
public void ValidateOtp_test_validates_within_50_second_validity_period() { var key = Sha1ReferenceKey; var generator = new TimeBasedOtpGenerator(key, 8); var currentTime = new DateTime(2033, 5, 18, 3, 33, 20, DateTimeKind.Utc); var fiftySeconds = TimeSpan.FromSeconds(50); Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(-90), fiftySeconds), "90 seconds prior should be invalid"); Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(-60), fiftySeconds), "60 seconds prior should be invalid"); Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(-30), fiftySeconds), "30 seconds prior should be valid"); Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+00), fiftySeconds), "The exact time should be valid"); Assert.IsTrue(generator.ValidateOtp("69279037", currentTime.AddSeconds(+30), fiftySeconds), "30 seconds after should be valid"); Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(+60), fiftySeconds), "60 seconds after should be invalid"); Assert.IsFalse(generator.ValidateOtp("69279037", currentTime.AddSeconds(+90), fiftySeconds), "90 seconds after should be invalid"); }
public void ValidateOtp_test_validates_within_60_second_validity_period() { var key = Sha1ReferenceKey; var generator = new TimeBasedOtpGenerator(key, 8); var currentTime = new DateTime(2009, 2, 13, 23, 31, 30, DateTimeKind.Utc); var sixtySeconds = TimeSpan.FromSeconds(60); Assert.IsFalse(generator.ValidateOtp("89005924", currentTime.AddSeconds(-90), sixtySeconds), "90 seconds prior should be invalid"); Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(-60), sixtySeconds), "60 seconds prior should be valid"); Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(-15), sixtySeconds), "15 seconds prior should be valid"); Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(+00), sixtySeconds), "The exact time should be valid"); Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(+15), sixtySeconds), "15 seconds after should be valid"); Assert.IsTrue(generator.ValidateOtp("89005924", currentTime.AddSeconds(+60), sixtySeconds), "60 seconds after should be valid"); Assert.IsFalse(generator.ValidateOtp("89005924", currentTime.AddSeconds(+90), sixtySeconds), "90 seconds after should be invalid"); }
public string GenerateOtpCode(int serverAccountId, string accountName) { var model = AccountModel.GetModel(serverAccountId); var otpAccount = model.OtpAccounts.Query().FirstOrDefault(r => r.Label == accountName); if (otpAccount == null) { throw new Exception("Could not find OTP account for given name"); } var totpcode = new TimeBasedOtpGenerator( new Key(otpAccount.Secret), otpAccount.Digits, new SHA1HMACAlgorithm()); return(totpcode.GenerateOtp(DateTime.UtcNow)); }
public bool RegisterInitialOtpDevice(string linkCodeString) { var linkCode = new LinkCodeRegisterInitialOtpDevice(linkCodeString); var newKeyPair = AsymmetricCryptoUtil.GenerateKeyPair(); var apiClient = new ApiClient( linkCode.ServerHttps, linkCode.ServerHost, linkCode.ServerPort, linkCode.ServerApiVersion); var request = new ServerAPIRequestsUnauthenticated.RegisterSecondDevice { LoginRequestIdentifier = linkCode.LoginIdentifier, PublicKeyPem = newKeyPair.PublicPem, DeviceLabel = "My Test Device", DeviceType = "phone", DeviceSubtype = "testdevice" }; var response = request.GetResponse(apiClient); var apiClientAuthenticated = new ApiClient( linkCode.ServerHttps, linkCode.ServerHost, linkCode.ServerPort, linkCode.ServerApiVersion, response.ApiKey, newKeyPair.PrivatePem); var totpcode = new TimeBasedOtpGenerator(new Key(response.Secret), response.Digits, new SHA1HMACAlgorithm()) .GenerateOtp(DateTime.UtcNow); try { var confirmRequest = new ServerAPIRequests.ConfirmSecondDevice { OtpCode = totpcode }; confirmRequest.GetResponse(apiClientAuthenticated); } catch (RequestException) { MessageBox.Show(@"Unable to validate the device. Please try again."); return(false); } var serverInfo = apiClientAuthenticated.GetServerInfo(new GetServerInfoRequest()); var newServerId = AppModel.ServerAccounts.Create(new AppModels.ServerAccount { ServerIdentifier = serverInfo.ServerIdentifier }); var model = AccountModel.GetModel(newServerId); var newOtpAccountId = model.OtpAccounts.Create(new OtpAccount { Type = response.Type, Label = response.Label, Issuer = response.Issuer, Secret = response.Secret, Algorithm = response.Algorithm, Digits = response.Digits, Counter = response.Counter, Period = response.Period }); var cryptoKeyId = model.CryptoKeys.Create(new CryptoKey { OwnKey = true, Trust = true, PrivateKeyPem = newKeyPair.PrivatePem, PublicKeyPem = newKeyPair.PublicPem, PublicKeyPemHash = HashUtil.Sha256(newKeyPair.PublicPem) }); var serverAccountSettingsId = model.ServerAccountSettings.Create(new ServerAccountSetting { Identifier = serverInfo.ServerIdentifier, Label = serverInfo.ServerLabel, HttpsEnabled = linkCode.ServerHttps, Host = linkCode.ServerHost, Port = linkCode.ServerPort, ApiVersion = linkCode.ServerApiVersion, UserIdentifier = response.UserIdentifier, DeviceIdentifier = response.DeviceIdentifier, OtpAccountId = newOtpAccountId, ApiKey = response.ApiKey, EmailAddress = linkCode.EmailAddress, ApiCryptoKeyId = cryptoKeyId }); var linkedDeviceRequest = new ServerAPIRequests.GetLinkedDevice(); ServerAPIRequests.GetLinkedDevice.ResponseParams linkedDeviceResponse; linkedDeviceResponse = linkedDeviceRequest.GetResponse(apiClientAuthenticated); if (linkCode.InitiatingDevicePublicKeyPem != HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem)) { MessageBox.Show(@"Unable to verify device keys. You will need to do this manually from the desktop app."); } else { var linkedDeviceCryptoKeyId = model.CryptoKeys.Create(new CryptoKey { Trust = true, PublicKeyPem = linkedDeviceResponse.PublicKeyPem, PublicKeyPemHash = HashUtil.Sha256(linkedDeviceResponse.PublicKeyPem) }); model.ServerAccountSettings.Update(serverAccountSettingsId, new ServerAccountSetting { LinkedDeviceCryptoKeyId = linkedDeviceCryptoKeyId }); } _syncAccounts.Add(newServerId, new SyncAccounts(this, model)); _syncAccounts[newServerId].Start(); _mainForm.UpdateForm(); return(true); }
private string GetOtpWithImplicitHMAC(Key key, int digits, DateTime time) { var otp = new TimeBasedOtpGenerator(key, digits); return(otp.GenerateOtp(time)); }
public async Task <bool> CheckOneTimePassword([FromBody] OtpCodeDto otpCodeDto) { var secretkey = string.Empty; var email = string.Empty; var userId = string.Empty; if (otpCodeDto.ChannelId == "sms") { var smsUser = this._context.SmsUser.Where(smsuser => smsuser.UserName == otpCodeDto.UserName).FirstOrDefault(); if (smsUser == null) { return(false); } secretkey = smsUser.SecretKey; email = smsUser.EMail; userId = smsUser.UserId; } if (otpCodeDto.ChannelId == "directline") { var directLineUser = this._context.DirectLineUser.Where(smsuser => smsuser.UserName == otpCodeDto.UserName).FirstOrDefault(); if (directLineUser == null) { return(false); } secretkey = directLineUser.SecretKey; email = directLineUser.EMail; userId = directLineUser.UserId; } int otpDigits = 6; var secretKey = secretkey; Key key = new Key(secretKey); var secret = key.Base32; TimeBasedOtpGenerator otp = new TimeBasedOtpGenerator(key, otpDigits); var time = GetNistTime(); var tst = otp.GenerateOtp(time); Key keySecret = new Key(secretKey); time = GetNistTime(); TimeBasedOtpGenerator otp3 = new TimeBasedOtpGenerator(keySecret, otpDigits); var valid = otp.ValidateOtp(otpCodeDto.OneTimePasswordCode, time); if (valid) { var jwtoken = new JwtManager(); var expirationTime = DateTime.UtcNow.AddMinutes(59); var jwt = jwtoken.GenerateJwtToken(email, userId, 60); if (otpCodeDto.ChannelId == "sms") { _context.SmsLogin.Add(new Data.Entities.SmsLogin { UserName = otpCodeDto.UserName, ExpirationTime = expirationTime, Jwt = jwt }); _context.SaveChanges(); } if (otpCodeDto.ChannelId == "directline") { _context.DirectLineLogins.Add(new Data.Entities.DirectLineLogins { UserName = otpCodeDto.UserName, ExpirationTime = expirationTime, Jwt = jwt.ToString() }); _context.SaveChanges(); } } return(valid); }