summaryrefslogtreecommitdiffstats
path: root/src/Otp.NET/KeyGeneration.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Otp.NET/KeyGeneration.cs')
-rw-r--r--src/Otp.NET/KeyGeneration.cs42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/Otp.NET/KeyGeneration.cs b/src/Otp.NET/KeyGeneration.cs
index 7e5b613..543fef6 100644
--- a/src/Otp.NET/KeyGeneration.cs
+++ b/src/Otp.NET/KeyGeneration.cs
@@ -23,6 +23,9 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
+using System;
+using System.Security.Cryptography;
+
namespace OtpNet
{
/// <summary>
@@ -55,6 +58,45 @@ namespace OtpNet
return GenerateRandomKey(LengthForMode(mode));
}
+ /// <summary>
+ /// Uses the procedure defined in RFC 4226 section 7.5 to derive a key from the master key
+ /// </summary>
+ /// <param name="masterKey">The master key from which to derive a device specific key</param>
+ /// <param name="publicIdentifier">The public identifier that is unique to the authenticating device</param>
+ /// <param name="mode">The hash mode to use. This will determine the resulting key lenght. The default is sha-1 (as per the RFC) which is 20 bytes</param>
+ /// <returns>Derived key</returns>
+ public static byte[] DeriveKeyFromMaster(IKeyProvider masterKey, byte[] publicIdentifier, OtpHashMode mode = OtpHashMode.Sha1)
+ {
+ if(masterKey == null)
+ throw new ArgumentNullException("masterKey");
+ return masterKey.ComputeHmac(mode, publicIdentifier);
+ }
+
+ /// <summary>
+ /// Uses the procedure defined in RFC 4226 section 7.5 to derive a key from the master key
+ /// </summary>
+ /// <param name="masterKey">The master key from which to derive a device specific key</param>
+ /// <param name="serialNumber">A serial number that is unique to the authenticating device</param>
+ /// <param name="mode">The hash mode to use. This will determine the resulting key lenght. The default is sha-1 (as per the RFC) which is 20 bytes</param>
+ /// <returns>Derived key</returns>
+ public static byte[] DeriveKeyFromMaster(IKeyProvider masterKey, int serialNumber, OtpHashMode mode = OtpHashMode.Sha1)
+ {
+ return DeriveKeyFromMaster(masterKey, KeyUtilities.GetBigEndianBytes(serialNumber), mode);
+ }
+
+ private static HashAlgorithm GetHashAlgorithmForMode(OtpHashMode mode)
+ {
+ switch(mode)
+ {
+ case OtpHashMode.Sha256:
+ return SHA256.Create();
+ case OtpHashMode.Sha512:
+ return SHA512.Create();
+ default: //case OtpHashMode.Sha1:
+ return SHA1.Create();
+ }
+ }
+
private static int LengthForMode(OtpHashMode mode)
{
switch(mode)