I am only doing this as a method to secure a third party product that does not have a native way of requesting and setting up 2FA. Essentially this creates a request that is sent to IT to have them manually add the secret key to a users profile when requested.
How should I generate a "secret" code for my two factor authentication system?
I'm using the QRCoder package to generate a nice displayable QR Code for my userbase. And it works great in the Microsoft Authenticator app, but both Authy and Google fail.
I suppose my random secret generator function is to blame?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim generator As OneTimePassword = New OneTimePassword() With {
.Secret = GenerateRandomString(16),
.Issuer = "My Site",
.Label = "My Service",
.Type = OneTimePassword.OneTimePasswordAuthType.TOTP
}
Dim payload As String = generator.ToString()
Dim qrGenerator As QRCodeGenerator = New QRCodeGenerator()
Dim qrCodeData As QRCodeData = qrGenerator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q)
Dim qrCode As QRCode = New QRCode(qrCodeData)
LiteralQRCode.Text = generator.Secret
Dim imgBarCode As New System.Web.UI.WebControls.Image()
imgBarCode.Height = 300
imgBarCode.Width = 300
Using bitMap As Bitmap = qrCode.GetGraphic(20)
Using ms As New MemoryStream()
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
Dim byteImage As Byte() = ms.ToArray()
imgBarCode.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage)
End Using
plBarCode.Controls.Add(imgBarCode)
End Using
End Sub
Public Function GenerateRandomString(ByRef iLength As Integer) As String
Dim rdm As New Random()
Dim allowChrs() As Char = "ABCDEFGHIJKLOMNOPQRSTUVWXYZ0123456789".ToCharArray()
Dim sResult As String = ""
For i As Integer = 0 To iLength - 1
sResult += allowChrs(rdm.Next(0, allowChrs.Length))
Next
Return sResult
End Function
I ended up using OtpNet and using their Base32Encode function to get what I needed.
Hopefully this will help the next person who is attempting to work on a project that isn't exactly conventional.
Dim totp = KeyGeneration.GenerateRandomKey()
Dim generator As OneTimePassword = New OneTimePassword() With {
.Secret = Base32Encoding.ToString(totp),
.Issuer = "My Site",
.Label = "My Service",
.Type = OneTimePassword.OneTimePasswordAuthType.TOTP
}