From a06022ba1e92a7589d6bcc0d0054e8453247c3f8 Mon Sep 17 00:00:00 2001 From: Eugene Fox Date: Sun, 13 Jun 2021 19:11:10 +0300 Subject: [PATCH] Version 1.2.1 (#18) - Fixed generated secret length - Fixed URI encoding issues in `OTPConfiguration.GetUri()` --- .../Models/OTPConfigurationUnitTest.cs | 53 +++++++++---------- SimpleOTP/Helpers/SecretGenerator.cs | 2 +- SimpleOTP/Models/OTPCode.cs | 2 +- SimpleOTP/Models/OTPConfiguration.cs | 6 +-- SimpleOTP/SimpleOTP.csproj | 6 +-- 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/SimpleOTP.Test/Models/OTPConfigurationUnitTest.cs b/SimpleOTP.Test/Models/OTPConfigurationUnitTest.cs index ad34ac6..4a2ca9b 100644 --- a/SimpleOTP.Test/Models/OTPConfigurationUnitTest.cs +++ b/SimpleOTP.Test/Models/OTPConfigurationUnitTest.cs @@ -1,4 +1,4 @@ -// ------------------------------------------------------------ +// ------------------------------------------------------------ // Copyright ©2021 Eugene Fox. All rights reserved. // Code by Eugene Fox (aka XFox) // @@ -29,7 +29,7 @@ namespace SimpleOTP.Test.Models var testId = config.Id; System.Diagnostics.Debug.WriteLine(testId); Uri uri = config.GetUri(); - Assert.AreEqual($"otpauth://totp/FoxDev+Studio:eugene@xfox111.net?secret={config.Secret}&issuer=FoxDev+Studio", uri.AbsoluteUri); + Assert.AreEqual($"otpauth://totp/FoxDev%20Studio:eugene@xfox111.net?secret={config.Secret}&issuer=FoxDev%20Studio", uri.AbsoluteUri); } /// @@ -39,9 +39,9 @@ namespace SimpleOTP.Test.Models public void TestFullLinkGenerator() { OTPConfiguration config = OTPConfiguration.GetConfiguration("otpauth://totp/FoxDev%20Studio:eugene@xfox111.net?secret=ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH&issuer=FoxDev%20Studio%20Issuer&algorithm=SHA512&digits=8&period=10"); - Assert.AreEqual($"otpauth://totp/FoxDev+Studio:eugene@xfox111.net?secret=ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH&issuer=FoxDev+Studio+Issuer&algorithm=SHA512&digits=8&period=10", config.GetUri().AbsoluteUri); + Assert.AreEqual($"otpauth://totp/FoxDev%20Studio:eugene@xfox111.net?secret=ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH&issuer=FoxDev%20Studio%20Issuer&algorithm=SHA512&digits=8&period=10", config.GetUri().AbsoluteUri); config.Type = Enums.OTPType.HOTP; - Assert.AreEqual($"otpauth://hotp/FoxDev+Studio:eugene@xfox111.net?secret=ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH&issuer=FoxDev+Studio+Issuer&algorithm=SHA512&digits=8&counter=0", config.GetUri().AbsoluteUri); + Assert.AreEqual($"otpauth://hotp/FoxDev%20Studio:eugene@xfox111.net?secret=ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH&issuer=FoxDev%20Studio%20Issuer&algorithm=SHA512&digits=8&counter=0", config.GetUri().AbsoluteUri); } /// @@ -64,28 +64,27 @@ namespace SimpleOTP.Test.Models OTPConfiguration config = OTPConfiguration.GetConfiguration("ESQVTYRM2CWZC3NX24GRRWIAUUWVHWQH", "FoxDev Studio", "eugene@xfox111.net"); string imageStr = await config.GetQrImage(); Assert.AreEqual( - "data:image/png;base64,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", imageStr); + "data:image/png;base64,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", imageStr); } } -} \ No newline at end of file +} diff --git a/SimpleOTP/Helpers/SecretGenerator.cs b/SimpleOTP/Helpers/SecretGenerator.cs index bc19d68..3ddc982 100644 --- a/SimpleOTP/Helpers/SecretGenerator.cs +++ b/SimpleOTP/Helpers/SecretGenerator.cs @@ -27,7 +27,7 @@ namespace SimpleOTP.Helpers if (length > 160 || length < 128) throw new ArgumentOutOfRangeException(nameof(length), "Invalid key length. It should belong to [128-160] bits span"); - byte[] key = new byte[length]; + byte[] key = new byte[length / 8]; new Random().NextBytes(key); return Base32Encoder.Encode(key); diff --git a/SimpleOTP/Models/OTPCode.cs b/SimpleOTP/Models/OTPCode.cs index dbf0ed6..12e634a 100644 --- a/SimpleOTP/Models/OTPCode.cs +++ b/SimpleOTP/Models/OTPCode.cs @@ -48,4 +48,4 @@ namespace SimpleOTP.Models public string GetCode(string formatter = "000000") => Code.ToString(formatter); } -} +} \ No newline at end of file diff --git a/SimpleOTP/Models/OTPConfiguration.cs b/SimpleOTP/Models/OTPConfiguration.cs index d8214ff..3d6ebae 100644 --- a/SimpleOTP/Models/OTPConfiguration.cs +++ b/SimpleOTP/Models/OTPConfiguration.cs @@ -177,10 +177,10 @@ namespace SimpleOTP.Models /// Valid OTP AUTH URI. public Uri GetUri() { - string path = $"otpauth://{Type}/{HttpUtility.UrlEncode(IssuerLabel)}"; + string path = $"otpauth://{Type}/{IssuerLabel}"; if (!string.IsNullOrWhiteSpace(AccountName)) path += $":{AccountName}"; - path += $"?secret={Secret}&issuer={HttpUtility.UrlEncode(Issuer)}"; + path += $"?secret={Secret}&issuer={Issuer}"; if (Algorithm != Algorithm.SHA1) path += $"&algorithm={Algorithm}"; if (Digits != 6) @@ -225,4 +225,4 @@ namespace SimpleOTP.Models return imageString; } } -} +} \ No newline at end of file diff --git a/SimpleOTP/SimpleOTP.csproj b/SimpleOTP/SimpleOTP.csproj index ea53c4d..d34c40c 100644 --- a/SimpleOTP/SimpleOTP.csproj +++ b/SimpleOTP/SimpleOTP.csproj @@ -12,7 +12,7 @@ SimpleOTP SimpleOTP - 1.2.0 + 1.2.1 .NET library for TOTP/HOTP implementation on server (ASP.NET) or client (Xamarin) side Eugene Fox FoxDev Studio @@ -22,8 +22,8 @@ https://github.com/XFox111/SimpleOTP en-US otp;totp;dotnet;hotp;authenticator;2fa;mfa;security;oath - - Expanded support to .NET Standard 2.1 and .NET Core 3.1 -- Fixed some documentation typos (https://github.com/XFox111/SimpleOTP/issues/14) + - Fixed generated secret length +- Fixed URI encoding issues in 'OTPConfiguration.GetUri()'