MFA One Time Pass-code Provider v1.0.1.0

Features

Unlicensed adapter

  • OTP passcodes can be used with 25 users for free.
  • Support of ADFS CSS themes
  • Enable self-registration with QR code (using free Microsoft Authentication, Google Authentication, Symantec VIP etc. mobile apps)
  • Logs are stored in Windows application log
  • Runs on ADFS 2016 and ADFS 2019 servers

Licensed adapter

  • OTP passcodes for unlimited user accounts of licensed organization.
  • QR code encryption with AES 256-bit encryption in SQL database.
  • Text customization for adapter interface.
  • OTP account lockout feature.
  • QR code customizations. (Advanced configuration)
  • Free version notes are removed.

Release information

Version: 1.0.1.0

  • Release date 11/04/2019
  • Added QR code customizations feature for OTP code.

NOTE: This encryption is not compatible with version 1.0.0.8. If you are using encryption with previous version, after upgrade you’ll need to delete user’s encrypted secret and re-enrol users again. If you are upgrading from SecureMfaOtp adapter version which didn’t have encryption you will need to amend SQL database by executing following query (not destructive operation but backup of database is recommended.):

alter table SecureMfaOTP.dbo.secrets 
alter column secret char(48) NOT NULL; 
alter table SecureMfaOTP.dbo.secrets 
ADD failedlogoncount INT DEFAULT 0 NOT NULL,
    failedlastlogon datetime NULL,
    failedcode char(6);                                                  

Content

Deploy SecureMfaOtp adapter into AD FS farm

Preparation steps

Before you can start registering “SecureMfaOtpProvider” into your ADFS farm you must complete bellow steps

1) Download latest “SecureMfaOtpprovider” package from https://www.securemfa.com/downloads .

2) Content will be downloaded as a zip file. Extract it on the primary ADFS server into “C:\SecureMfaOtpProvider” location.

3) Within the directory you will find “CreateDatabase_SecureMfaOTP.txt”

Modify FILENAME location to reflect your sql server storage configuration. Open the script in SQL manager and execute it. This will create a new SQL database for “SecureMfaOtpprovider”

4) Within the directory update “SecureMfaOtpProvider.json”

If you are using a free license you only need to modify "sqlserver" server settings . If you will buy a license for unlimited users you will need to update "company" and "serialkey" information to unlock the app.

If you are not running your adfs servers using service account and you cannot use SQL integrated security to access database, you need to change:

"sqlintegratedsecurity": "false“ and update "sqluseraccount" and "sqluserpassword" with relevant information.

5) If you need to generate verbose logs in windows events for troubleshooting reasons change verboselog value from “false” to “true”. Please note that verbose logging can affect your servers’ performance, use it only for troubleshooting reasons. Don’t enable “verboselog” in production environments as it may reveal configuration secrets

6) Using SQL manager provision dbo access to “SecureMfaOTP” database for ADFS service account or SQL user.

Below is a sample of a SecureMfaOtpProvider.json file

{  
"company": "MyCompany",
"serialkey": "m00000000",
"sqlserver": "asqlaol1.adatum.labnet,1433",
"sqldbname": "SecureMfaOTP",
"sqlintegratedsecurity": "true",
"sqluseraccount": "",
"sqluserpassword": "",
"verboselog": "false",
"data_encryption": "false",
"encryption_passphrase": "d9GhT=7=Ox8-+LaZ",
"login_failures": "0",
"lockout_minutes" : "5",
"first_login_text": "Please configure your Authenticator Application (Microsoft Authenticator, Google Authenticator, Symantec VIP etc.) using the QR code below.",
"login_text": "Enter the passcode generated by your authenticator application."
"totp_customization": "false",
"totp_remove_user_prefix": "false",
"totp_api_endpoint": "https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=otpauth://totp/",
"totp_api_otpauth_advanced_params": "&algorithm=SHA1",
"totp_image_width_pixels": "150",
"totp_image_height_pixels": "150"
}


SecureMfaOtp adapter installation

Before a SecureMfaOtpprovider will be invoked by AD FS, it must be registered in the system. Bellow powersehll script performs the necessary installation actions including installation in the GAC, and registration in AD FS farm.

Script to install SecureMfaOtpProvider on primary ADFS node

#Open elevated PowerShell command window on your federation server and execute the following commands
#Note that if you are using federation server farm that uses Windows Internal Database, you must execute these commands on the primary federation server of the farm
#Bellow commands needs to be executed on one server in ADFS farm

#Check if windows events source for application log exist, if not create one.
if ([System.Diagnostics.EventLog]::SourceExists("Secure MFA OTP") -eq $False) {New-EventLog -LogName "Application" -Source "Secure MFA OTP"}
 
#Remove additional authentication providers from ADFS global policy and unregister SecureMfaOtpProvider
Set-AdfsGlobalAuthenticationPolicy -AdditionalAuthenticationProvider ""
unregister-AdfsAuthenticationProvider -Name “SecureMfaOtpProvider” -Confirm:$false
 
#Restart ADFS service
net stop adfssrv
net start adfssrv
 
#Remove SecureMfaOtpProvider DLL from GAC assembly
Set-location "c:\SecureMfaOtpProvider"            
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") 
$publish = New-Object System.EnterpriseServices.Internal.Publish            
$publish.GacRemove("c:\SecureMfaOtpProvider\SecureMfaOtpProvider.dll")       
 
#Add SecureMfaOtpProvider DLL to GAC assembly
Set-location "c:\SecureMfaOtpProvider"            
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")            
$publish = New-Object System.EnterpriseServices.Internal.Publish            
$publish.GacInstall("c:\SecureMfaOtpProvider\SecureMfaOtpProvider.dll")     
 
#Register SecureMfaOtpProvider addapter
$typeName = “SecureMfaOtpProvider.AuthenticationAdapter, SecureMfaOtpProvider, Version=1.0.1.0, Culture=neutral, PublicKeyToken=f818a38c51378814, processorArchitecture=MSIL”
Register-AdfsAuthenticationProvider -TypeName $typeName -Name “SecureMfaOtpProvider” -ConfigurationFilePath 'C:\SecureMfaOtpProvider\SecureMfaOtpProvider.json'
 
#Restart ADFS service
net stop adfssrv
net start adfssrv
 
#Add SecureMfaOtpProvider as additional authentication provider in ADFS
Set-AdfsGlobalAuthenticationPolicy -AdditionalAuthenticationProvider "SecureMfaOtpProvider"    

If you have more servers in ADFS farm execute following script on remaining nodes

Script to install SecureMfaOtpProvider on other ADFS nodes

#Open elevated PowerShell command window on your federation server and execute the following commands
#Note that you don't need to register DLL on ADFS proxy servers

#Check if windows events source for application log exist, if not create one.
if ([System.Diagnostics.EventLog]::SourceExists("Secure MFA OTP") -eq $False) {New-EventLog -LogName "Application" -Source "Secure MFA OTP"}

#Remove SecureMfaOtpProvider DLL from GAC assembly
Set-location "c:\SecureMfaOtpProvider"            
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") 
$publish = New-Object System.EnterpriseServices.Internal.Publish            
$publish.GacRemove("c:\SecureMfaOtpProvider\SecureMfaOtpProvider.dll")       
 
#Add SecureMfaOtpProvider DLL to GAC assembly
Set-location "c:\SecureMfaOtpProvider"            
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")            
$publish = New-Object System.EnterpriseServices.Internal.Publish            
$publish.GacInstall("c:\SecureMfaOtpProvider\SecureMfaOtpProvider.dll")     
 
#Restart ADFS service
net stop adfssrv
net start adfssrv
 
#List all authentication providers
Get-AdfsAuthenticationProvider | select name 

Verification

To verify if “SecureMfaOtpProvider” has been installed successfully.

1) Open the AD FS Management Snapin (from Server Manager Tools menu)

2) Click Authentication Policies at left

3) In the center pane, under Multi-Factor Authentication, click the blue Edit link to the right of Global Settings.

4) Under Select additional authentication methods at the bottom of the page, check if “Time Based OTP Authentication Provider” is selected.


Application

When you will login into your ADFS application which requires multifactor authentication first time user will see QR coder which can be scanned with any authenticator which is based on RFC6238 ( a Time-Based One-Time Password (TOTP) Algorithm). This algorithm is used in Google's Authenticator, Microsoft Authenticator, Symantec VIP and potentially in many other time-based authenticators.

Below is print screen of SecureMFA OTP provider.

After user’s successful logon using OTP code, QR code will never be displayed unless user’s account is deleted from “Secrets” table in SQL or “logon” value is updated to 0

User Lockouts

This feature only works for licensed adapters. If you set “login_failures” more than a zero in SecureMFA database you will see failed user authentication attempts. When user reaches “failedlogoncount” number of attempts set in “login_failures” value user’s account will be locked out for a period of time set in "lockout_minutes" . If you want to disable this feature you must set “login_failures” to zero. All values are configured in SecureMfaOtpProvider.json file.

SecureMfaOtpProvider.json config settings to enable 5 min lockouts for 15 failed OTP passcode attemps :

"login_failures": "15"
"lockout_minutes" : "5" 

Encryption

Encryption only works for licensed adapters. AES 256-bit encryption is created with AesManaged class in the System.Security.Cryptography module: This class uses Windows CryptoAPI (CAPI) which uses FIPS-compliant .NET Assemblies. The cipher mode is Cipher Block Chaining (CBC). The passphrase can be configured in configuration file and it is recommended to be between 16-18 random characters. It is salted with 16 bytes string, zero padding and 4 key iterations. Full documentation on “AesManaged .NET class” can be found in Microsoft documentation for “System.Security.Cryptography.AesManaged“ constructors)

SecureMfaOtpProvider.json config settings to enable encryption:

"data_encryption": "true"
"encryption_passphrase": "d9GhT=7=Ox8-+LaZ"

When it is enabled your secret code is encrypted in Database and it looks like bellow.

Theme customizations

Licensed clients can customize adapter text which is presented to the users during logon. You can use some simple html code like links to provide users with self-service portal links etc. Text is configured in configuration file “SecureMfaOtpProvider.json” .

SecureMfaOtpProvider.json config settings for text customization:

"first_login_text": "Please configure your Authenticator Application (Microsoft Authenticator, Google Authenticator, Symantec VIP etc.) using the QR code below."
"login_text": "Enter the passcode generated by your authenticator application."


QR code customizations

Licensed clients can customize QR code generated text and set advanced features for Authenticator software. QR image is presented to the user during first logon and allows to enrol user’s Authenticator device to generate OTP codes for the user. With customization settings enabled you can change QR code generator endpoint from Google API (which is default QR code generator for SecureMFA OTP adapter) to any other vendor or internal QR service. Any advance settings specified in QR customizations must be supported by OTP Authenticator software. Some OTP Authenticator software do not support QR codes with advance settings, some of them will ignore settings like SHA256 passphrase encryption on the client etc. Most popular Authenticator software defaults to SHA1 encryption.

To enable customization set:

"totp_customization": "true"

Endpoint for QR generator API is specified under "totp_api_endpoint" value. (NOTE, it is only used by client computer to access, most likely user’s browser will need to access this endpoint to retrieve QR image). It must be specified with all mandatory parameter values in URL which are required by a vendor. Only vendors who specifies TOTP settings under “otpauth://totp/” configuration will work. It must support following format: otpauth://[TYPE]/[KEY NAME]?secret=[KEY SECRET, BASE 32]&issuer=[ISSUER] . All those settings will be generated by SecureMFA OTP adapter and amended into API endpoint URL. Issuer and Label information will come from licensed company name. Not licensed adapters will show www.securemfa.com as issuer information.

"totp_api_endpoint": "https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=otpauth://totp/"

Any advance settings which are supported by QR generator and client authenticator software must be specified under bellow setting. Set all required parameters separated by & symbol.

"totp_api_otpauth_advanced_params": "&algorithm=SHA1"

More details on advanced QR configuration can be found HERE

Bellow settings specifies HTML image size which will be displaying QR code, it must not be smaller than a size setting used in QR endpoint URL. It is recommended to match values.

"totp_image_width_pixels": "150",
"totp_image_height_pixels": "150"

If you need to hide user’s account prefix information as additional security feature on client’s device. Set “totp_remove_user_prefix” in json config file to be “true”

Bellow pictures shows how it looks with enabled and disabled user’s prefix on Authenticator’s screen.

"totp_remove_user_prefix": "true"

"totp_remove_user_prefix": "false"

Below is a sample of json configuration file which will work with qrserver.com API. It is another free QR image generator service available on the internet.

"totp_customization": "true",
"totp_remove_user_prefix": "true",
"totp_api_endpoint": "http://api.qrserver.com/v1/create-qr-code/?size=150x150&ecc=L&data=otpauth://totp/”
"totp_api_otpauth_advanced_params": "&algorithm=SHA1",
"totp_image_width_pixels": "150",
"totp_image_height_pixels": "150" 

Final URL for API endpoint to the user is unique. Below is a sample how properly formatted URL for QR image will look like: