当前位置: 首页 > 编程语言 > C#

C#中基于HMAC的一次性密码(RFC4226-HOTP)Share

时间:2023-04-10 20:36:48 C#

C#中基于HMAC的一次性密码(RFC4226-HOTP)数字/字符不区分大小写一次性密码过期。我的源码是http://tools.ietf.org/html/rfc4226#section-5首先是参数C定义的8字节计数器值,移动因子。这个计数器必须在HOTP生成器(客户端)和HOTP验证器(服务器)之间同步。K客户端和服务器之间的共享秘密;每个HOTP生成器都有一个不同且唯一的秘密K。T节流参数:服务器将在T次不成功的身份验证尝试后拒绝来自用户的连接。然后我们有生成HOTP的算法由于HMAC-SHA-1计算的输出是160位,我们必须将这个值截断为用户可以轻松输入的值。HOTP(K,C)=Truncate(HMAC-SHA-1(K,C))然后,我们定义Truncate为String=String[0]...String[19]设OffsetBits为String的低4位[19]Offset=StToNum(OffsetBits)//0<=OffSet<=15让P=String[OffSet]...String[OffSet+3]返回P的最后31位然后提供一个6位HOTP的例子以下代码示例描述了在给定hmac_res的情况下提取动态二进制代码ult是一个包含HMAC-SHA-1结果的字节数组:intoffset=hmac_result[19]&0xf;intbin_code=(hmac_result[offset]&0x7f)<<24|(hmac_result[offset+1]&0xff)<<16|(hmac_result[offset+2]&0xff)<<8|(hmac_result[offset+3]&0xff);我宁愿不知所措,试图将其转换为有用的C#代码以生成一次性密码已经有了创建过期HMAC的代码,如下所示:byte[]hashBytes=alg.ComputeHash(Encoding.UTF8.GetBytes(input));byte[]result=newbyte[8+hashBytes.Length];hashBytes.CopyTo(结果,8);BitConverter.GetBytes(expireDate.Ticks).CopyTo(结果,0);我只是不确定如何从那里转到上述算法中建议的6位数字。你有两个问题:如果你正在生成字母数字,你不符合RFC-此时,你可以简单地获取任何N个字节并将它们转换为十六进制字符串并获得字母数字。或者,如果您想要a-z和0-9,请将它们转换为36。RFC的第5.4节为您提供了用于设置Digit参数的标准HOTP计算(注意Digit是C、K和T)。如果你选择忽略这部分,你不需要转换你的代码-只需使用你想要的。您的“结果”字节数组仅在散列后的前8个字节中填充了到期时间。如果截断为6个字母数字,则不会将它们与散列部分一起收集,那么您根本无法计算它。“伪造”或重放也很容易-将秘密散列一次,然后将你想要的任何标记放在你面前-而不是真正的一次性密码。请注意,RFC中的参数C旨在满足过期窗口,应在计算哈希码之前将其添加到输入中。对于任何感兴趣的人,我确实想出了一种方法来为我的一次性密码设置有效期。这样做的方法是使用创建的时间到分钟(忽略秒、毫秒等)。获取值后,使用DateTime的tick作为计数器或变量C。otpLifespan是我的HOTP生命周期,otpLifespan分钟。DateTimecurrent=newDateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,DateTime.Now.Hour,DateTime.Now.Minute,0);for(intx=0;xmyexpirationHOTPextendsself'sdigitalHOTP,它有一个静态验证方法,检查长度,确保它是数字,验证是否使用校验和,最后将传入的hotp与生成的进行比较。唯一的缺点是每次验证即将过期的hotp时最坏的情况是检查n+1个HOTP值,其中n是以分钟为单位的生命周期。文档中描述RFC4226的Java代码示例非常漂亮简单的C#过程。我真正需要重写的唯一部分是哈希方法。privatestaticbyte[]HashHMACSHA1(byte[]keyBytes,byte[]text){HMACalg=newHMACSHA1(keyBytes);returnalg.ComputeHash(文本);我希望这可以帮助其他人尝试生成一次性密码。这段代码应该能满足你的要求:以上是C#学习教程分享的全部内容:C#中基于HMAC的一次性密码(RFC4226–HOTP),如果对大家有用需要进一步了解C#学习教程,希望大家多多关注---publicclassUniqueId{publicstaticstringGetUniqueKey(){intmaxSize=6;//无论你想要什么长度char[]chars=newchar[62];串一个;a="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";char[]chars=newchar[a.Length];字符=a.ToCharArray();int大小=最大大小;字节[]数据=新字节[1];RNGCryptoServiceProvidercrypto=newRNGCryptoServiceProvider(););尺寸=最大尺寸;数据=新字节[大小];crypto.GetNonZeroBytes(数据);StringBuilderresult=newStringBuilder(size);foreach(bytebindata){result.Append(chars[b%(chars.Length-1)]);}返回结果.ToString();}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: