private static int GetHashLength(OtpAlgorithm algorithm) { switch (algorithm) { case OtpAlgorithm.MD5: return(32); case OtpAlgorithm.SHA1: return(20); case OtpAlgorithm.SHA256: return(32); case OtpAlgorithm.SHA512: return(64); } throw new InvalidOperationException(); }
private static HMAC GetHMAC(OtpAlgorithm algorithm, byte[] key) { switch (algorithm) { case OtpAlgorithm.MD5: return(new HMACMD5(key)); case OtpAlgorithm.SHA1: return(new HMACSHA1(key)); case OtpAlgorithm.SHA256: return(new HMACSHA256(key)); case OtpAlgorithm.SHA512: return(new HMACSHA512(key)); } throw new InvalidOperationException(); }
public OtpAuthenticator(OtpType type, OtpAlgorithm algorithm = OtpAlgorithm.SHA1, byte[] key = null) { HMAC = GetHMAC(algorithm, key ?? GenerateKey(algorithm)); Type = type; }
public static byte[] GenerateKey(OtpAlgorithm algorithm) { return(GenerateKey(GetHashLength(algorithm))); }
public static string GetUri(OtpType type, byte[] key, string accountName, string issuer = "", OtpAlgorithm algorithm = OtpAlgorithm.SHA1, int codeLength = 6, long counter = 0, int period = 30) { StringBuilder SB = new StringBuilder(); SB.AppendFormat("otpauth://{0}/", type.ToString().ToLower()); if (!string.IsNullOrEmpty(issuer)) { SB.AppendFormat("{0}:{1}?issuer={0}&", Uri.EscapeUriString(issuer), Uri.EscapeUriString(accountName)); } else { SB.AppendFormat("{0}?", Uri.EscapeUriString(accountName)); } SB.AppendFormat("secret={0}&algorithm={1}&digits={2}&", Base32.Encode(key), algorithm, codeLength); if (type == OtpType.HOTP) { SB.AppendFormat("counter={0}", counter); } else { SB.AppendFormat("period={0}", period); } return(SB.ToString()); }