Google-style security



    Google I / O 2019 has died down and it's time rewrite projects on a new architecturelearn new things. Since I am interested in the security of mobile applications, I first drew attention to the new library in the JetPack family - security-crypto . The library helps to organize data encryption correctly and at the same time protects developers from all the nuances that accompany this process.


    Historical reference


    Data encryption in Android has always generated a lot of discussion. Which algorithm to choose? What encryption mode to use? What is padding? Where to store keys? Learning all this and keeping your knowledge up to date can be difficult for the average developer. Therefore, the story most often ended in one of three scenarios:


    • copy-paste of the first solution with stackoverflow
    • search for a “suitable manual” with subsequent implementation and collection of rakes
    • activation of the “And so it will!” protocol

    As the community of android developers developed, libraries began to appear to help solve this problem. The quality of these solutions was very different: from all this variety, I can select only java-aes-crypto , which we used in Redmadrobot. A rather high-quality implementation, but there were a couple of problems with it.


    First of all, it was just string encryption. This in itself is not bad, but these strings need to be stored somewhere, in the database or SharedPreferences. So, you need to write a wrapper over the data source so that everything is encrypted on the fly (which we once did). But this is the code that needs to be supported, dragged from project to project or executed in a library for ease of use. Ultimately, this was also done, but it did not bring comfort to inquiring minds.


    Secondly, this solution did not offer anything to solve the key management problem. They could be generated, but storage completely fell on the shoulders of the developer. With all the squats around AndroidKeystore on different OS versions and devices coming from Mainland China.


    This city needs a new hero


    Everything went as usual until in the summer of 2018 I discovered that there is such a wonderful library from Google as Tink . It is quite easy to learn and protects the developer from a huge number of nuances related to cryptography. Using this library, it is almost impossible to do something wrong. Moreover, Tink takes full control of the keys and abstracts all operations with AndroidKeystore from the developer.


    But it was still just string encryption. And here Binary Preferences turned up very successfully - a library from a domestic manufacturer that I had wanted to look at for a long time. It allows you to encrypt all stored data of any algorithms - for this it was enough to write an implementation of two interfaces, KeyEncryption and ValueEncryption (for keys and values, respectively).


    As a result, we began to use these two libraries in conjunction and were happy that our code became cleaner and easier to understand.


    security-crypto



    Now Google has once again decided to meet the developers and simplify their lives in the field of encryption of stored data. Another JetPack library was announced to help with this. I was wondering what they wrote so revolutionary there, and I climbed to look for documentation (spoiler: it is not). I only found javadoc on the classes included in the library, but thanks for that too. It turned out that there are few opportunities: file encryption, SharedPreferences and working with keys.


    To test the library's functionality, I wrote a couple of snippets:


    File encryption
    val file = File(filesDir, "super_secure_file")
    val encryptedFile = EncryptedFile.Builder(file, this, "my_secret_key", EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB)
        .setKeysetAlias("my_test_keyset_alias")
        .setKeysetPrefName("keyset_pref_file")
        .build()
    val outputStream = encryptedFile.openFileOutput()
    outputStream.use {
        it.write("secret info".toByteArray())
    }

    SharedPreferences Encryption
    val encryptedPreferences = EncryptedSharedPreferences.create(
        "super_secret_preferences",
        "prefrences_master_key",
        this,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
    encryptedPreferences.edit().putString("secret", "super secret token")

    To my great surprise, everything worked the first time, and I got to see what code they wrote for this library. Having fallen into the source, I saw that this is actually a wrapper around the Tink library that we already know, and the written code is almost one-to-one as we wrote for the encrypted BinaryPreferences.


    I was very pleased that this time Google did not invent a bicycle moped, but used its own well-established practices. Let's hope that the package that came to JetPack securitywill not be limited only to this library, but will develop further.


    Demonstration of the BinaryPreferences + Tink Bundle
    Security-crypto library source code Demonstration of the security-crypto library


    Also popular now: