Time-based one-time password algorithm: Difference between revisions

Content added Content deleted
No edit summary
Line 126: Line 126:


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp>using System;
using System.Security.Cryptography;


namespace RosettaTOTP
{
public class TOTP_SHA1
{
private byte[] K;
public TOTP_SHA1()
{
GenerateKey();
}
public void GenerateKey()
{
using (RandomNumberGenerator rng = new RNGCryptoServiceProvider())
{
/* Keys SHOULD be of the length of the HMAC output to facilitate
interoperability.*/
K = new byte[HMACSHA1.Create().HashSize];
rng.GetBytes(K);
}
}
public int HOTP(UInt64 C, int digits = 6)
{
var hmac = HMACSHA1.Create();
hmac.Key = K;
hmac.ComputeHash(BitConverter.GetBytes(C));
return Truncate(hmac.Hash, digits);
}
public UInt64 CounterNow(int T1 = 30)
{
var secondsSinceEpoch = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
return (UInt64)Math.Floor(secondsSinceEpoch / T1);
}
private int DT(byte[] hmac_result)
{
int offset = hmac_result[19] & 0xf;
int bin_code = (hmac_result[offset] & 0x7f) << 24
| (hmac_result[offset + 1] & 0xff) << 16
| (hmac_result[offset + 2] & 0xff) << 8
| (hmac_result[offset + 3] & 0xff);
return bin_code;
}


private int Truncate(byte[] hmac_result, int digits)
{
var Snum = DT(hmac_result);
return Snum % (int)Math.Pow(10, digits);
}
}


class Program
{
static void Main(string[] args)
{
var totp = new TOTP_SHA1();
Console.WriteLine(totp.HOTP(totp.CounterNow()));
}
}
}
</lang>


=={{header|Go}}==
=={{header|Go}}==