Bài viết hôm nay mình tiếp tục hướng dẫn các bạn, cách bảo mật ứng dụng đăng nhập 2 lớp 2FA (Multi-factor Authentication) trên C# winform.

Dưới đây, là hình ảnh demo ứng dụng:

Tiếp đến các bạn scan mã qrcode trên.

Nó sẽ hiển thị cho các bạn mã OTP gồm 6 số để các bạn thực hiện đăng nhập 2FA.

Nó sẽ hiện thị số như hình bên dưới.

Source code c# đầy đủ:

using OtpNet;
using QRCoder;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media.Imaging;

namespace OTP_Microsoft_Auth
{
    public partial class Form1 : Form
    {
        readonly QRCodeGenerator qrGenerator = new QRCodeGenerator();
        const int DEFAULT_STEP = 30;
        public Form1()
        {
            InitializeComponent();
            txtAppName.Focus();
            txtAppName.Text = "Demo2FA Auth";
            txtIssuer.Text = "Thảo meo - Laptrinhvb.net";
            txtSecret.Text = Base32Encoding.ToString(KeyGeneration.GenerateRandomKey(20));
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void txtSecret_TextChanged(object sender, EventArgs e)
        {
            if (txtAppName.Text != "" && txtIssuer.Text != "" && txtSecret.Text != "")
            {
                var qrCodeUri = $"otpauth://totp/{Uri.EscapeDataString(txtAppName.Text)}?secret={txtSecret.Text}&issuer={Uri.EscapeDataString(txtIssuer.Text)}";

                using (var qrCodeData = qrGenerator.CreateQrCode(qrCodeUri, QRCodeGenerator.ECCLevel.Q))
                {
                    using (var qrCode = new QRCode(qrCodeData))
                    {
                        var qrCodeImage = qrCode.GetGraphic(20);

                        using (var memory = new MemoryStream())
                        {
                            qrCodeImage.Save(memory, ImageFormat.Bmp);
                            memory.Position = 0;
                            var bitmapImage = new Bitmap(memory);
                            pictureBox1.Image = bitmapImage;
                        }
                    }

                }

            }
        }

        private void txtVerify_Click(object sender, EventArgs e)
        {
            var totp = new Totp(Base32Encoding.ToBytes(txtSecret.Text));

            var isValidTotpCode = totp.VerifyTotp(txtCodeOTP.Text, out long timeStepMatched, new VerificationWindow(previous: 1, future: 1));

            var now = DateTime.UtcNow;
            var step = Math.Floor((now - new DateTime(1970, 1, 1)).TotalSeconds / DEFAULT_STEP);

            lblCode1.Text = $"{totp.ComputeTotp(now.AddSeconds(-DEFAULT_STEP))}{Environment.NewLine}({step - 1})";
            lblCode2.Text = $"{totp.ComputeTotp(now)}{Environment.NewLine}({step})";
            lblCode3.Text = $"{totp.ComputeTotp(now.AddSeconds(DEFAULT_STEP))}{Environment.NewLine}({step + 1})";


            if (isValidTotpCode)
            {
               
                MessageBox.Show($"Valid TOTP Code (step: {timeStepMatched})!");
            }
            else
            {
                MessageBox.Show("Invalid TOTP Code");
            }
        }

    
    }
}

Loading

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *