手机谷歌验证码接收平台下载(手机谷歌验证码解决方案)

未标题-1-4 (1).png

摘要:Google Authenticator,是谷歌公司推出的一款动态令牌工具,解决账户使用时遭到的一些不安全的操作进行的“二次验证”,认证器基于RFC文档中的HOTP/TOTP算法实现 ,是一种从共享秘钥和时间或次数一次性令牌的算法。在工作中可以通过认证器方式对账户有更好的保护,但是在查阅一些资料发现适合我这样的小白文章真的很少,针对于C#的文章就更加少了,本文主要是对C#如何使用Google Authenticator进行探讨,有不足之处还请见谅。

Google Authenticator什么是认证器?怎么对接?

Google Authenticator是微软推出的一个动态密令工具,它有两种密令模式。分别是“TOTP 基于时间”、“HOTP 基于计数器”,通过手机上 简单的设置就可以设定自己独一的动态密令, 那么我们怎么将我们的程序和认证器进行对接呢?其实谷歌认证器并不是需要我们对接这个工具的API而是通过算法来决定,谷歌使用使用HMAC算法生成密令,通过基于次数或者基于时间两个模板进行计算,因此在程序中只需要使用相同的算法即可与之匹配。

TOTP 基于时间HMAC算法使用固定为HmacSHA1更新时长固定为30秒APP端输入数据维度只有两个:账户名称和base32格式的keyHOTP 基于计数器

基于计数器模式是根据一个共享秘钥K和一个C计数器进行算法计算

认证器安装

手机需要安装认证器:

Android版:安卓版下载IOS版:苹果版下载效果图控制台

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace GoogleAuthenticator

{

class Program

{

static void Main

{

long duration = 30;

string key = "[email protected]";

GoogleAuthenticator authenticator = new GoogleAuthenticator;

var mobileKey = authenticator.GetMobilePhoneKey;

while

{

Console.WriteLine;

var code = authenticator.GenerateCode;

Console.WriteLine;

Console.WriteLine;

System.Threading.Thread.Sleep;

Console.Clear;

}

}

}

}

认证器类:

using GoogleAuthorization;

using System;

using System.Security.Cryptography;

using System.Text;

namespace GoogleAuthenticator

{

public class GoogleAuthenticator

{

/// <summary>

/// 初始化验证码生成规则

/// </summary>

/// <param name="key">秘钥</param>

/// <param name="duration">验证码间隔多久刷新一次</param>

public GoogleAuthenticator

{

this.SERECT_KEY = key;

this.SERECT_KEY_MOBILE = Base32.ToString);

this.DURATION_TIME = duration;

}

/// <summary>

/// 间隔时间

/// </summary>

private long DURATION_TIME { get; set; }

/// <summary>

/// 迭代次数

/// </summary>

private long COUNTER

{

get

{

return ).TotalSeconds / DURATION_TIME;

}

}

/// <summary>

/// 秘钥

/// </summary>

private string SERECT_KEY { get; set; }

/// <summary>

/// 手机端输入的秘钥

/// </summary>

private string SERECT_KEY_MOBILE { get; set; }

/// <summary>

/// 到期秒数

/// </summary>

public long EXPIRE_SECONDS

{

get

{

return ).TotalSeconds % DURATION_TIME);

}

}

/// <summary>

/// 获取手机端秘钥

/// </summary>

/// <returns></returns>

public string GetMobilePhoneKey

{

if

throw new ArgumentNullException;

return SERECT_KEY_MOBILE;

}

/// <summary>

/// 生成认证码

/// </summary>

/// <returns>返回验证码</returns>

public string GenerateCode

{

return GenerateHashedCode;

}

/// <summary>

/// 按照次数生成哈希编码

/// </summary>

/// <param name="secret">秘钥</param>

/// <param name="iterationNumber">迭代次数</param>

/// <param name="digits">生成位数</param>

/// <returns>返回验证码</returns>

private string GenerateHashedCode

{

byte[] counter = BitConverter.GetBytes;

if

Array.Reverse;

byte[] key = Encoding.ASCII.GetBytes;

HMACSHA1 hmac = new HMACSHA1;

byte[] hash = hmac.ComputeHash;

int offset = hash[hash.Length – 1] & 0xf;

int binary =

<< 24)

| << 16)

| << 8)

| ;

int password = binary % Math.Pow; // 6 digits

return password.ToString);

}

}

}

Base32转换类:

using System;

namespace GoogleAuthorization

{

public static class Base32

{

public static byte[] ToBytes

{

if )

{

throw new ArgumentNullException;

}

input = input.TrimEnd;

int byteCount = input.Length * 5 / 8;

byte[] returnArray = new byte[byteCount];

byte curByte = 0, bitsRemaining = 8;

int mask = 0, arrayIndex = 0;

foreach

{

int cValue = CharToValue;

if

{

mask = cValue << ;

curByte = ;

bitsRemaining -= 5;

}

else

{

mask = cValue >> ;

curByte = ;

returnArray[arrayIndex++] = curByte;

curByte = );

bitsRemaining += 3;

}

}

if

{

returnArray[arrayIndex] = curByte;

}

return returnArray;

}

public static string ToString

{

if

{

throw new ArgumentNullException;

}

int charCount = Math.Ceiling * 8;

char[] returnArray = new char[charCount];

byte nextChar = 0, bitsRemaining = 5;

int arrayIndex = 0;

foreach

{

nextChar = ));

returnArray[arrayIndex++] = ValueToChar;

if

{

nextChar = ) & 31);

returnArray[arrayIndex++] = ValueToChar;

bitsRemaining += 5;

}

bitsRemaining -= 3;

nextChar = & 31);

}

if

{

returnArray[arrayIndex++] = ValueToChar;

while returnArray[arrayIndex++] = '=';

}

return new string;

}

private static int CharToValue

{

var value = c;

if

{

return value – 65;

}

if

{

return value – 24;

}

if

{

return value – 97;

}

throw new ArgumentException;

}

private static char ValueToChar

{

if

{

return ;

}

if

{

return ;

}

throw new ArgumentException;

}

}

}

总结需要注意的坑

移动端下载的认证器的秘钥key是通过base32转码得到的,而程序端是直接输入源码。

如原秘钥为[email protected]生成的base32码PBSW63RZHE3UAZTPPBWWC2LMFZRW63I=才是移动端需要输入的秘钥。

在网上找了很多资料没有发现关于C#的案例,所以在此记录一下自己遇到的坑,让更多的人能够跳过这个坑

原文地址:

https://www.cnblogs.com/easyauthor/p/22054869.html

海外精品引流脚本–最强海外引流  

官网:www.facebook18.com

唯一TG:https://t.me/Facebook181818

Facebook.png

更多海外引流脚本方案

如果你需要脚本演示、部署咨询或海外获客方案,可以通过下面入口继续查看。

官网首页 | 演示视频 | TG 在线客服 | TG 频道

相关阅读

© 版权声明
广告也精彩

相关文章