All Projects → RedMadRobot → Pinkman

RedMadRobot / Pinkman

Licence: mit
PINkman is a library to help implementing an authentication by a PIN code in a secure manner. The library derives hash from the user's PIN using Argon2 function and stores it in an encrypted file. The file is encrypted with the AES-256 algorithm in the GCM mode and keys are stored in the AndroidKeystore.

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to Pinkman

Halite
High-level cryptography interface powered by libsodium
Stars: ✭ 933 (+1481.36%)
Mutual labels:  authentication, argon2
Fullstack Apollo Express Postgresql Boilerplate
💥 A sophisticated GraphQL with Apollo, Express and PostgreSQL boilerplate project.
Stars: ✭ 1,079 (+1728.81%)
Mutual labels:  authentication
React Redux Registration Login Example
React + Redux - User Registration and Login Tutorial & Example
Stars: ✭ 1,011 (+1613.56%)
Mutual labels:  authentication
Visa
Easy third party authentication (OAuth 2.0) for Flutter apps.
Stars: ✭ 50 (-15.25%)
Mutual labels:  authentication
Privacyidea
🔐 multi factor authentication system (2FA, MFA, OTP Server)
Stars: ✭ 1,027 (+1640.68%)
Mutual labels:  authentication
Laravel5.7 Vue Cli3 Boilerplate
Boilerplate / Starter kit. Laravel 5.7, Vue CLI 3 — Authentication with Email Verification. REST API.
Stars: ✭ 52 (-11.86%)
Mutual labels:  authentication
Matrixauth
High-performance lightweight distributed permission system. 高性能轻量级分布式权限系统。
Stars: ✭ 41 (-30.51%)
Mutual labels:  authentication
Login Fire
An element that allows simple configuration of multiple provider login for firebase
Stars: ✭ 58 (-1.69%)
Mutual labels:  authentication
Sudo pair
Plugin for sudo that requires another human to approve and monitor privileged sudo sessions
Stars: ✭ 1,077 (+1725.42%)
Mutual labels:  authentication
Django Unifi Portal
Authenticate Unifi WiFi Guests with Django
Stars: ✭ 50 (-15.25%)
Mutual labels:  authentication
Fake Auth
A fake auth service for prototyping authentication flows
Stars: ✭ 50 (-15.25%)
Mutual labels:  authentication
Unchained
Secure password hashers for Go compatible with Django
Stars: ✭ 46 (-22.03%)
Mutual labels:  argon2
Keyring
Keyring is an authentication framework for WordPress. It comes with definitions for a variety of HTTP Basic, OAuth1 and OAuth2 web services. Use it as a common foundation for working with other web services from within WordPress code.
Stars: ✭ 52 (-11.86%)
Mutual labels:  authentication
Node Argon2
Node.js bindings for Argon2 hashing algorithm
Stars: ✭ 1,008 (+1608.47%)
Mutual labels:  argon2
Next Authentication
Authentication & Authorization library for the Next.js framework
Stars: ✭ 55 (-6.78%)
Mutual labels:  authentication
Pal
Pragmatic Authentication Library
Stars: ✭ 41 (-30.51%)
Mutual labels:  authentication
Authentication Server
A simple authentication service to deliver JWT with Hasura claims, based on users with multiples roles stored in a Postgres database.
Stars: ✭ 48 (-18.64%)
Mutual labels:  authentication
Django Channels React Multiplayer
turn based strategy game using django channels, redux, and react hooks
Stars: ✭ 52 (-11.86%)
Mutual labels:  authentication
Ldap Jwt
Lightweight node.js based web service that provides user authentication against LDAP server (Active Directory / Windows network) credentials and returns a JSON Web Token.
Stars: ✭ 58 (-1.69%)
Mutual labels:  authentication
Google Auth Library Nodejs
🔑 Google Auth Library for Node.js
Stars: ✭ 1,094 (+1754.24%)
Mutual labels:  authentication

PINkman

API CI Maven Central

Implementing an authentication by a PIN code is an ordinary task for a mobile applications developer. You can even think of it as some kind of boilerplate code. But it's a trap. Such tasks have a number of security gotchas. Therefore there's a high risk of implementing it in an insecure manner. Don't worry, Pinkman to the rescue!

What is it?

PINkman is a library to help implementing an authentication by a PIN code in a secure manner. The library derives hash from the user's PIN using Argon2 hash function
and stores it in an encrypted file. The file is encrypted with the AES-256 algorithm in the GCM mode and keys are stored in the AndroidKeystore.

How it works?

This library doesn't reinvent it's own cryptograhy and just stands on the shoulders of giants. Here's the description of the used technologies and their params.

Deriving a hash from a PIN code

For getting the hash, the Argon2 function is used with following params:

  • Mode: Argon2i
  • Time cost in iterations: 5
  • Memory cost in KBytes: 65 536
  • Parallelism: 2
  • Derived hash length: 128bit
Encrypted files

To store data securely, this library is using the Jetpack security library from the Android Jetpack libraries suite. That library, in turn, is using the other awesome library - Tink, so you can be sure that storing data of a PIN code is organized quite secure. Or you can verify it yourself ;)

Quick start

Add this library to your gradle config

implementation 'com.redmadrobot:pinkman:$pinkman_version'

Create an instance of the Pinkman class (use a DI please) and integrate it to your authentication logic.

val pinkman = Pinkman(application.applicationContext)

...

class CreatePinViewModel(private val pinkman: Pinkman) : ViewModel() {

    val pinIsCreated = MutableLiveData<Boolean>()

    fun createPin(pin: String) {
        pinkman.createPin(pin)

        pinIsCreated.postValue(true)
    }
}

...

class InputPinViewModel(private val pinkman: Pinkman) : ViewModel() {

    val pinIsValid = MutableLiveData<Boolean>()

    fun validatePin(pin: String) {
        pinIsValid.value = pinkman.isValidPin(pin)
    }
}

Also you can do all these things even sipmler with the UI components (PinView and PinKeyboard) supplied by this library. You need to add this dependency to use them

implementation 'com.redmadrobot:pinkman-ui:$pinkman_version' 
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.redmadrobot.pinkman_ui.PinView
        android:id="@+id/pin_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="75dp"
        app:emptyDrawable="@drawable/circle_grey"
        app:filledDrawable="@drawable/circle_red"
        app:itemHeight="22dp"
        app:itemWidth="22dp"
        app:layout_constraintBottom_toTopOf="@+id/keyboard"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:length="4"
        app:spaceBetween="28dp" />

    <com.redmadrobot.pinkman_ui.PinKeyboard
        android:id="@+id/keyboard"
        style="@style/PinkmanDefaultKeyboard"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

And integrate them with the logic written before

class CreatePinFragment : Fragment() {

    private val viewModel: CreatePinViewModel by viewModels()

    ...
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewModel.pinIsCreated.observe(viewLifecycleOwner, Observer { isCreated ->
            findNavController().popBackStack(R.id.mainFragment, false)
        })

        pin_view.onFilledListener = { viewModel.createPin(it) }
        keyboard.keyboardClickListener = { pin_view.add(it) }

    }
}

⚠️
Hash deriving operations can take significant time on some devices. In order to avoid ANR in your application you shouldn't run methods createPin(), changePin(), isValidPin() on the main thread.

This library has already provided two extensions to run these methods asynchronously. You can choose one depending on your specific needs (or tech stack).

You need to add this dependency if you prefer RxJava:

implementation 'com.redmadrobot:pinkman-rx3:$pinkman_version'

But if you're on the bleeding edge technologies, you should use a dependency with Kotlin Coroutines support:

implementation 'com.redmadrobot:pinkman-coroutines:$pinkman_version'

As a result, you'll get RxJava specific or Coroutines specific method's set:

// RxJava3
fun createPinAsync(...): Completable
fun changePinAsync(...): Completable
fun isValidPinAsync(...): Single<Boolean>

// Coroutines
suspend fun createPinAsync(...)
suspend fun changePinAsync(...)
suspend fun isValidPinAsync(...): Boolean

Feedback

In case you have faced any bugs or have any useful suggestions for improvement of this library, feel free to create an issue.

LICENSE

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].