0
votes

I am thinking about using ChaCha20-Poly1305 to encrypt/decrypt a password (I need to encrypt/decrypt cannot only hash). But, to use this algorithm we are required to use a Secret Key. However, this is a problem because I am encrypting/decrypting the user's password on their device, so in my DB I just store their encrypted password.

The problem with it, is if the user uninstall my app from their phone or change to a new phone, I would need the same secret key to be able to decrypt the user's password again.

My question is: How do I safely transfer and store this secret key ?

Also, please let me know if you have better alternatives for my problem, such as different encryption algorithm or methods.

Here is a code example with the SecretKey object that I've mentioned:

package com.javainterviewpoint;

import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class ChaCha20Poly1305Example
{
    static String plainText = "This is a plain text which will be encrypted by ChaCha20 Poly1305 Algorithm";

    public static void main(String[] args) throws Exception
    {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("ChaCha20");
        keyGenerator.init(256);

        // Generate Key
        SecretKey key = keyGenerator.generateKey();

        System.out.println("Original Text  : " + plainText);

        byte[] cipherText = encrypt(plainText.getBytes(), key);
        System.out.println("Encrypted Text : " + Base64.getEncoder().encodeToString(cipherText));

        String decryptedText = decrypt(cipherText, key);
        System.out.println("DeCrypted Text : " + decryptedText);

    }

    public static byte[] encrypt(byte[] plaintext, SecretKey key) throws Exception
    {
        byte[] nonceBytes = new byte[12];

        // Get Cipher Instance
        Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
        
        // Create IvParamterSpec
        AlgorithmParameterSpec ivParameterSpec = new IvParameterSpec(nonceBytes);

        // Create SecretKeySpec
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "ChaCha20");

        // Initialize Cipher for ENCRYPT_MODE
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);

        // Perform Encryption
        byte[] cipherText = cipher.doFinal(plaintext);

        return cipherText;
    }

    public static String decrypt(byte[] cipherText, SecretKey key) throws Exception
    {
        byte[] nonceBytes = new byte[12];

        // Get Cipher Instance
        Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");

        // Create IvParamterSpec
        AlgorithmParameterSpec ivParameterSpec = new IvParameterSpec(nonceBytes);
                
        // Create SecretKeySpec
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "ChaCha20");

        // Initialize Cipher for DECRYPT_MODE
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);

        // Perform Decryption
        byte[] decryptedText = cipher.doFinal(cipherText);

        return new String(decryptedText);
    }
}
1
Why not simply have them re-enter their password whenever they install or re-install your app?President James K. Polk

1 Answers

0
votes

For symmetric encryption and decryption, a best practice is use a MASTER KEY which is fixed string or has a fixed algorithm which just you know how to generate it. You must use this MASTER KEY for encryption and decryption all other keys (name WORKING KEYS) to encrypt/decrypt real data.

If your device has a secure area which you can save your keys safely, you must inject master key on it by another device or by communicating with a server. If it has not, you are in RISK for disclosing keys.

However, if you are the only programmer of the app, you can use a fixed algorithm to generate MASTER key. For example hash(xor( of 1c1c1c with the ID of the device. Now, the device can send a request for getting working keys (by sending its id and mac-block which is encrypted by master key) to a server and you give back the right working keys.

This scenario use in payments by ISO-8583.