62,074
社区成员
发帖
与我相关
我的任务
分享
public static int OneTimePassword { set; get; }
byte[] Hmac = new HMACSHA1(***).ComputeHash(***);
int Offset = Hmac.Last() & 0x0F;
OneTimePassword = (
((Hmac[Offset + 0] & 0x7f) << 24) |
((Hmac[Offset + 1] & 0xff) << 16) |
((Hmac[Offset + 2] & 0xff) << 8) |
(Hmac[Offset + 3] & 0xff)
) % 1000000;
private void CalculateOneTimePassword() {
// Get the number of seconds since 1/1/1970 and devide them by 30 seconds.
// Thus one Timestamp unit is 30 seconds.
//获取从1970年1月1日到现在的秒数,再除以30得到一个单位为30秒的时间戳
Timestamp = Convert.ToInt64(GetUnixTimestamp() / 30);
// Convert the 64 bit integer Timestamp to a byte array (8 bytes).
// eg. ba d9 c7 02 00 00 00 00
// Then reverse them (=> 00 00 00 00 02 c7 d9 ba) and write the result to the byte array "data".
//把64位整数的时间戳转成8个字节的自己数组
var data = BitConverter.GetBytes(Timestamp).Reverse().ToArray();
// Generate the Hmac key from your password (byte array) and time (byte array).
//从你的密码(字节数组)和时间(自己数组)生成哈希运算消息认证码
Hmac = new HMACSHA1(Secret).ComputeHash(data);
// Bit-operation: Get the last 4 bits of the Hmac. The results are always equal to or between 0 and 15.
// The offset determines the area of the Hmac that is used to generate the time based password.
//位运算:得到哈希运算消息认证码的最后4个字节。结果总是等于或者在0到15之间
Offset = Hmac.Last() & 0x0F;
// The Hmac is 20 bytes long. A block of 4 bytes is used for the OneTimePassword, which changes each 30 seconds.
// 15 is the highest Offset. Therefore the last used byte is number 18 (first byte is zero based).
// The 19th (=last) byte is the Offset. More precisely the <a href="http://en.wikipedia.org/wiki/Nibble" title="Wiki Nibble Byte" target="_blank">right nibble</a> of the 19th byte is the Offset value.
// Bit masks are applied on the selected Hmac block to limit the number. The resulting bits are rotated to the left and added together.
// Basically we are looking at a manual "bit to integer" conversion.
// the result is then devided by 1,000,000 and only the remainder is taken. Consequently all results are less than 1,000,000.
// (The bit mask 0xff is useless. I guess it was used to emphasize the technique for readability purposes. 0x7f does make sense.)
//哈希运算消息认证码为20字节。OneTimePassword是一个4字节的块,每30秒改变一次。
//最高位置是15。所以最后一个字节是数字18(第一个自己是以0位基数的)。
//第19(最后)字节是结束。更精确的说第19个字节是结束值,参考 <a href="http://en.wikipedia.org/wiki/Nibble" title="Wiki Nibble Byte" target="_blank">right nibble</a>
//位掩码被于选定的哈希运算消息认证码块来限制位数。位计算结果左转并加到一起。
//基本上我们看到的是一个手工的位到整数的转换
//结果用1,000,000除,并只保留余数。因此所有的结果都小于1,000,000。
//(位掩码0xff没有什么作用。我猜用它只为了更直观的强调技术。0x7f是有用的)
OneTimePassword = (
((Hmac[Offset + 0] & 0x7f) << 24) |
((Hmac[Offset + 1] & 0xff) << 16) |
((Hmac[Offset + 2] & 0xff) << 8) |
(Hmac[Offset + 3] & 0xff)) % 1000000;
}
//这不就是自己做了个加密方式,获得密码么,而且标注了是一次性的密码,也就是说明文来源随机,不可重复
byte[] Hmac = new HMACSHA1(***).ComputeHash(***);//获取个随机的什么东西,然后将它散列了
int Offset = Hmac.Last() & 0x0F;//根据最后一个元素计算取值位置,只取0-15之间的数字
OneTimePassword = (//然后把这个元素开始的连续4个字节拿出来当个有符号int型,并计算对1000000取余数
((Hmac[Offset + 0] & 0x7f) << 24) |
((Hmac[Offset + 1] & 0xff) << 16) |
((Hmac[Offset + 2] & 0xff) << 8) |
(Hmac[Offset + 3] & 0xff)
) % 1000000;