使用谷歌身份验证器为系统添加动态密码验证

最近公司项目需要用到动态密码登陆,寻找多种解决方案,最后确认使用谷歌身份验证器(Google身份验证器、Google Authenticator) 。

其他备选的方案有国内厂家提供的动态密钥硬件(类似网易将军令)、微软提供的类似谷歌身份验证器的解决方案(找的相关资料不多,如果有谁知道的请留言)

 

用谷歌身份验证器的原因:

  • 客户端为APP,有安卓和IOS ,  IOS端在App Store 可以搜索下载。
  • C#有封装好的相关类可用  (Nuget中搜索 Google Authenticator 即可)
  • 客户使用复杂度不高(扫码建立、手动输入建立)

先说逻辑及相关流程,后面贴代码

  •  密钥说明
    • 密钥A: 作为密钥种子
    • 密钥B:使用密钥种子+使用者账号组成(也可以系统为每个账号生成一个密钥B,而不需要密钥A,但需要每个账号都储存这个密钥B,使用种子+账号的方式可以不用存储)
    • 密钥C:使用密钥B 调用谷歌的加密方法,得到APP端可输入的密钥
  • 使用说明
    • 在账户管理,或者个人中心,勾选是否登陆使用动态验证码,点击【生成密钥按钮】 调用CreateCode方法,产生密钥C显示,且out 的ImgContent 可以直接放在img的html标签的src属性显示成对应的二维码图片
    • 客户使用APP扫描或输入相关的账号和密钥,APP就会开始每30秒自动刷新生成一个6位的动态验证码
    • 客户在登陆时,系统使用 当前登录账号 +动态密码 调用ValidateCode 验证是否正确

 

APP端

第三方DLL引用(Nuget)及版本

 

核心代码如下:

    /// <summary>
    /// 谷歌身份验证器
    /// </summary>
    public class GoogleAuthor
    {
        //加密种子  密钥A
        private static string baseKey = "qwertyuiopasdfghjkl";

        /// <summary>
        /// 创建密钥  (若修改登陆账号,则相关加密解密需要重新绑定)
        /// </summary>
        /// <param name="Account_No">系统用户登陆账号</param> 
        /// <param name="ImgContent">返回img图片内容,包含账号和密钥信息,用户可用app扫描</param>
        /// <returns>返回用户输入客户端用的密钥字符串</returns>
        public static string CreateCode(string Account_No, out string ImgContent)
        {
            string scKey = baseKey + Account_No.Replace(" ", "");//加密密钥  密钥B
            ImgContent = "";  
            Google.Authenticator.TwoFactorAuthenticator tf = new Google.Authenticator.TwoFactorAuthenticator();
            //生成客户端需要输入的密钥 密钥C
            var sc = tf.GenerateSetupCode("System", Account_No.Replace(" ",""), scKey, false, 300); 
            ImgContent = sc.QrCodeSetupImageUrl; //data:image/png;base64  开头的图片字符串。可以直接展示。
            //sc.ManualEntryKey   客户端需要输入的密钥
            return sc.ManualEntryKey; 
        }

        /// <summary>
        /// 验证动态码
        /// </summary>
        /// <param name="Account_No">账号</param>
        /// <param name="CodeStr">动态码</param>
        /// <returns>true: 验证正确  false:验证错误</returns>
        public static bool ValidateCode(string Account_No, string CodeStr )
        {
            Google.Authenticator.TwoFactorAuthenticator tf = new Google.Authenticator.TwoFactorAuthenticator();
            string scKey = baseKey + Account_No.Replace(" ", ""); 
            return tf.ValidateTwoFactorPIN(scKey, CodeStr); //不用时间, 自动默认时间偏移正负5
        }
    }

 

posted @ 2020-09-30 08:57  写代码让我快乐  阅读(3095)  评论(0编辑  收藏  举报