短信验证码

代码源自 Microsoft.AspNet.Identity 程序集.

 1 using System;
 2 using System.Net;
 3 using System.Security.Cryptography;
 4 using System.Text;
 5 
 6 namespace Authentication
 7 {
 8     internal static class Rfc6238AuthenticationService
 9     {
10         private static readonly DateTime _unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
11         private static readonly TimeSpan _timestep = TimeSpan.FromMinutes(3.0);
12         private static readonly Encoding _encoding = new UTF8Encoding(false, true);
13 
14         private static int ComputeTotp(HashAlgorithm hashAlgorithm, ulong timestepNumber, string modifier)
15         {
16             byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((long)timestepNumber));
17             byte[] array = hashAlgorithm.ComputeHash(ApplyModifier(bytes, modifier));
18             int num = (int)(array[array.Length - 1] & 15);
19             int num2 = (int)(array[num] & 127) << 24 | (int)(array[num + 1] & 255) << 16 |
20                        (int)(array[num + 2] & 255) << 8 | (int)(array[num + 3] & 255);
21             return num2 % 1000000;
22         }
23 
24         private static byte[] ApplyModifier(byte[] input, string modifier)
25         {
26             if (string.IsNullOrEmpty(modifier))
27             {
28                 return input;
29             }
30             byte[] bytes = _encoding.GetBytes(modifier);
31             byte[] array = new byte[checked(input.Length + bytes.Length)];
32             Buffer.BlockCopy(input, 0, array, 0, input.Length);
33             Buffer.BlockCopy(bytes, 0, array, input.Length, bytes.Length);
34             return array;
35         }
36 
37         private static ulong GetCurrentTimeStepNumber()
38         {
39             return
40                 (ulong)
41                     ((DateTime.UtcNow - _unixEpoch).Ticks /
42                      _timestep.Ticks);
43         }
44 
45         public static int GenerateCode(SecurityToken securityToken, string modifier = null)
46         {
47             if (securityToken == null)
48             {
49                 throw new ArgumentNullException("securityToken");
50             }
51             ulong currentTimeStepNumber = GetCurrentTimeStepNumber();
52             int result;
53             using (HMACSHA1 hMACSHA = new HMACSHA1(securityToken.GetDataNoClone()))
54             {
55                 result = ComputeTotp(hMACSHA, currentTimeStepNumber, modifier);
56             }
57             return result;
58         }
59     }
60 
61     internal sealed class SecurityToken
62     {
63         private readonly byte[] _data;
64         public SecurityToken(byte[] data)
65         {
66             this._data = (byte[])data.Clone();
67         }
68         internal byte[] GetDataNoClone()
69         {
70             return this._data;
71         }
72     }
73 }
View Code

 

var stampCode ="123";

var code = Rfc6238AuthenticationService.GenerateCode(new SecurityToken(Encoding.Unicode.GetBytes(stampCode)));

 

生成时需要更换种子 stampCode。

转载于:https://www.cnblogs.com/yuys/p/5234722.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值