XKeyboard - on-screen keyboard






4.87/5 (21 votes)
XKeyboard eliminates the threat of keyloggers by allowing the user to enter a password by clicking on buttons displayed on an on-screen keyboard.
Introduction
The company where I work has a number of products where user is prompted for a password or other type of security code. The recent $420 million scam involving keylogger spooked everybody, so we started looking at alternative technologies to secure access to sensitive data. Although some of these technologies are quite expensive, it occurred to me that there was a cheap alternative to keyboard entry that would be simple to implement: an on-screen keyboard, where user enters a password by clicking on keys that are displayed on a virtual keyboard. The easiest way to explain is to show you what I mean:


XKeyboard Features
XKeyboard offers following features:-
All keyboard characters - The two Shift buttons are toggle buttons
implemented using my
CXButtonXP
class. This allows access to all characters available on a real keyboard, including special characters. For ease of use, Shift keys on real keyboard also cause the XKeyboard keys to be shifted. -
Show plain text - The user can display plain text of password:
- Minimum/maximum password length - You can specify how long password must be.
-
Most recently used (MRU) passwords - You can specify a list of passwords that have
been recently used. A password that is similar to any of the passwords in list
will be rejected. The virtual function
CheckMRUPasswords()
allows you to customize algorithm used to determine similarity. -
Dialog timeout - You can specify a timeout for dialog, which will force it to close
after timeout expires. This will prevent possibility of leaving dialog open, with
a password in edit control. In case of timeout, dialog returns code
IDABORT
. - Read-only edit control - You can specify that edit control should be read-only. If not read-only, user may enter a password by typing on real keyboard, which somewhat defeats the purpose.
- Upper/lower case - You can specify to convert password to upper or lower case, or leave it unchanged.
-
Special characters - You can specify that password should include special
characters, digits, or just alphanumeric characters. The virtual function
CheckSpecial()
allows you to customize algorithm used to determine whether password contains special characters. - String resources - all messages displayed by XKeyboard are contained in string resources.
-
Spacebar - You can specify to display spacebar. Not displaying spacebar
means that spaces will not be allowed in password (even if edit control
is not read-only). When spacebar is not displayed, the dialog is resized:
CXKeyboard Implementation Notes
As you can see from code, there is nothing special about XKeyboard. It is implemented as a dialog with buttons for usual keyboard keys. Pressing either Shift key toggles upper/lower case (and in this case, also toggles the special characters to "shifted" character).One decision I made was to not use a checkbox button (in "push-like" mode). I didn't like the way button behaved on XP with theming - when you push it, it immediately pops back to display a non-pushed state, until you move the cursor off button, when it displays a pushed state. So I used my new XButtonXP control instead.
XKeyboard uses two timers; one timer is used if there is timeout set, and the other timer is used to check if shift keys on real keyboard are pressed. Pressing either real shift key works just as you would expect - as long as real shift key is held down, XKeyboard shows shifted character set. When real shift key is released, XKeyboard shows unshifted character set.
CXKeyboard API
TheCXKeyboard
API includes:
GetPassword() | Returns the password |
SetPassword() | Sets the edit control with password |
GetShowText() | Returns state of Show Text checkbox |
SetShowText() | Sets state of Show Text checkbox |
GetShowSpacebar() | Returns TRUE if spacebar is visible |
SetShowSpacebar() | Sets visibility of spacebar (TRUE = visible) |
GetSpecial() | Returns enum value of special character setting |
SetSpecial() | Sets special character enum value |
GetMinLength() | Returns minimum length of a password |
SetMinLength() | Sets minimum length of password |
GetMaxLength() | Returns minimum length of a password |
SetMaxLength() | Sets minimum length of password |
GetCase() | Returns enum value of case setting |
SetCase() | Sets case enum value |
SetMRUPasswords() | Sets MRU password list |
ClearMRUPasswords() | Clears MRU password list |
GetTimeout() | Returns timeout value in seconds |
SetTimeout() | Sets timeout value in seconds; 0 = no timeout |
GetReadOnly() | Returns read-only state of edit control |
SetReadOnly() | Sets read-only state of edit control (TRUE = read-only) |
CheckSpecial() | Virtual function that returns TRUE if password contains a special character |
CheckMRUPasswords() | Virtual function that returns TRUE if password is in MRU list |
How to use
To integrate CXKeyboard
into your app, you first need to add following files to your project:
- XKeyboard.cpp
- XKeyboard.h
- XKeyboardRes.h
- XKeyboard.rc
- XButtonXP.cpp
- XButtonXP.h
- XThemeHelper.cpp
- XThemeHelper.h
- OddButton.cpp
- OddButton.h
- MemDC.h
You also need to add XKeyboard.rc to your project's rc file - go
to View | Resource Includes... and in bottom listbox, scroll down to end.
Insert #include "XKeyboard.rc"
right before #endif
:
Next, include header file XKeyboard.h in appropriate project files.
Now you are ready to start using CXKeyboard
.
Compiler Prerequisites
XKeyboard requires the Platform SDK to compile. If you get a compile error aboutDFCS_HOT
being
undefined, you should include the following line in stdafx.h, before any header file includes:
#define WINVER 0x0500 // needed by XButtonXP
Calling XKeyboard
The demo app shows how to call XKeyboard:// array of "most recently used" passwords CStringArray sa; sa.Add(_T("qwer")); sa.Add(_T("asdf")); sa.Add(_T("zxcv")); CPoint point; GetCursorPos(&point); CXKeyboard dlg(point.x, point.y-247); dlg.SetShowText(m_bShowText); dlg.SetMRUPasswords(sa); int n = _ttoi(m_strMinLength); if (n <= 0) n = 1; dlg.SetMinLength(n); dlg.SetMaxLength(_ttoi(m_strMaxLength)); dlg.SetTimeout(_ttoi(m_strTimeout)); dlg.SetSpecial((CXKeyboard::SPECIAL_CHARACTERS)m_nSpecial); dlg.SetShowSpacebar(m_bShowSpacebar); dlg.SetCase((CXKeyboard::XKEYBOARD_CASE)m_nCase); dlg.SetPassword(m_strPassword); //dlg.SetReadOnly(TRUE); int rc = dlg.DoModal(); if (rc == IDOK) { m_strPassword = dlg.GetPassword(); m_bShowText = dlg.GetShowText(); GetDlgItem(IDC_STATUS)->SetWindowText(m_strPassword); } else if (rc == IDABORT) { GetDlgItem(IDC_STATUS)->SetWindowText(_T("Dialog timed out")); } else { GetDlgItem(IDC_STATUS)->SetWindowText(_T("Dialog cancelled by user")); }
Other On-Screen Keyboard Implementations
There is a Microsoft on-screen keyboard (Programs | Accessories | Accessibility) that is shipped with Win2k and XP. Microsoft licensed this product from Madentec Limited.Click-N-Type is a freeware on-screen keyboard that is very popular.
Both of these products are available only as standalone executables, although the Madentec site mentions that an SDK is available.
Revision History
Version 1.0 - 2005 April 4
- Initial public release
Usage
This software is released into the public domain. You are free to use it in any way you like, except that you may not sell this source code. If you modify it or extend it, please to consider posting new code here for everyone to share. This software is provided "as is" with no expressed or implied warranty. I accept no liability for any damage or loss of business that this software may cause.