This is an app to authenticate users via their cell phone, by decrypting a one-time password encrypted by the server using a public key. The app is usable for any web service that implements this method of authentication.
(See the github tracker for more information on how to implement this authentication on server-side)
The app can be used with unlimited number of relying parties, as the same public key is used with all parties. Once the app is enrolled, the app generates a device-specific keypair that is present for the whole lifetime of the app (until its uninstalled). Updating the app won't erase the key however.
Github Tracker: https://github.com/sebastiannielsen/QRSA
Prerequisites for running the app:
1. The phone must support hardware based storage. This is a storage that uses a "Security Chip" inside the phone, making it impossible to copy the key off the phone.
2. The store must be initialized. Sometimes its possible to initialize the store by setting up a PIN lock screen, and then just generating a key. Removing the lock screen will usually keep the key, unless the key properties was setup to require lock screen.
3. In some cases, a secure lock screen MUST be used. This is dependent on phone model.
4. The secure chip inside phone, must support operations based on 2048 bit RSA/ECB/PKCS1.5
5. In some cases, a rooted phone may permanently disable the security chip for security reasons.
To enroll, you must launch the URL qrsa://e from a browser or similiar. You can also enroll via a callback URL, by using qrsa://u. To use u, you must first append a "s" if you want to use HTTPS, or anything else for HTTP. Then the whole URL to be called, WITHOUT the scheme, in URLSafe Base64 format. The public key will be appended to end of URL. If the device is incompatible, it will return INCOMPATIBLE_DEVICE and its your responsibility to return a meaningful error message to the user.
To authenticate, you launch the url qrsa://s or qrsa://c followed by URLSafe Base64 encoded data of the RSA public key encrypted text in the format PADDING::OTP::MESSAGE::HASH::PADDING. The "s" action is designed for scanned events and will show as OTP text on screen. The "c" action is designed for click events. The difference is that click events will cause the OTP code to be put in the user's clipboard instead, so the user immediately can proceed to pasting the code inside the OTP field.
HASH is constructed by creating a md5 out of OTP + MESSAGE + OTP, where + denotes string concatenation. This HASH protects against some rough forms of malleability attacks on the encrypted text. The sandwiched construction prevents a attacker from moving the separator between OTP and MESSAGE.
Note that the screenshots of the app has been intentionally censored to prevent trademark and/or copyright infringements (UI of android and other apps are copyright protected), as the interaction in the app is provided via a dialog box that appear on top of the calling app that caused the authentication to happen.
If there is any issues on the app, you can find example code and more instructions on the public GitHub page, as this app is Open Source.
Also, feel free to create any issues in the public github tracker.