diff options
Diffstat (limited to 'src/Otp.NET/KeyGeneration.cs')
-rw-r--r-- | src/Otp.NET/KeyGeneration.cs | 42 |
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) |