java AES encryption in Android

1 foreword

In java development, encryption is still a very common requirement. There are two common encryption methods: symmetric encryption and asymmetric encryption, which use different encryption and decryption keys. The detailed encryption principle will not be discussed here. AES encryption is widely used in Java

2 AES symmetric encryption

AES encryption is a kind of symmetric encryption, that is, the encryption and decryption keys are the same. In Android, encryption using AES is as follows:

/**
 * @author Created by qiyei2015 on 2017/12/13.
 * @version: 1.0
 * @email: 1273482124@qq.com
 * @description:
 */
public class AES {

    private static final String TAG = AES.class.getSimpleName();


    /**
     * Generate secret key
     * @param rules Build rule
     * @return
     */
    private static SecretKeySpec generateSecretKey(String rules){
        try {
            //1. Construct key generator, specified as AES algorithm, case insensitive
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            //2. Initialize the key generator according to the rules to generate a 128 bit random source, according to the incoming byte array
            // Pay attention to the way of generating random numbers, otherwise errors may be reported in Android system
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", new CryptoProvider());
            secureRandom.setSeed(rules.getBytes("utf-8"));
            keygen.init(128,secureRandom);
            //3. Generate the original symmetric key
            SecretKey originalKey = keygen.generateKey();
            //4. Get the byte array of the original symmetric key
            byte [] raw = originalKey.getEncoded();
            //5. Generate AES key according to byte array
            SecretKeySpec key = new SecretKeySpec(raw, "AES");
            return key;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * AES encryption
     * @param rules rule
     * @param plainText Plaintext
     * @return Encrypted ciphertext
     */
    public static byte[] encrypt(String rules,String plainText){
        if (TextUtils.isEmpty(rules)){
            return null;
        }
        if (plainText == null || plainText.length() == 0){
            return null;
        }
        try {
            SecretKeySpec key = generateSecretKey(rules);
            if (key != null){
                //1. AES self cipher according to the specified algorithm
                Cipher cipher = Cipher.getInstance("AES");
                //2. Initialize the cipherer. The first parameter is the encryption mode or decrypt mode operation. The second parameter is the KEY used
                cipher.init(Cipher.ENCRYPT_MODE, key);
                //3. Encryption
                byte [] byteEncode = cipher.doFinal(plainText.getBytes("utf-8"));
                return byteEncode;
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * AES Decrypt
     * @param rules rule
     * @param encryptText ciphertext
     * @return Decrypted plaintext
     */
    public static byte[] decrypt(String rules,byte[] encryptText){
        if (TextUtils.isEmpty(rules)){
            return null;
        }
        if (encryptText == null || encryptText.length == 0){
            return null;
        }

        try {
            SecretKeySpec key = generateSecretKey(rules);
            if (key != null){
                //6. AES self cipher according to the specified algorithm
                Cipher cipher = Cipher.getInstance("AES");
                //7. Initialize the cipherer. The first parameter is the encryption mode or decrypt mode operation. The second parameter is the KEY used
                cipher.init(Cipher.DECRYPT_MODE, key);
                //8. Decryption
                byte [] byteDecode = cipher.doFinal(encryptText);
                return byteDecode;
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * Convert binary to hexadecimal
     * @param buffer Binary array
     * @return Hexadecimal string
     */
    public static String parseByte2HexStr(byte buffer[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buffer.length; i++) {
            String hex = Integer.toHexString(buffer[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * Convert hex to binary
     * @param hexStr Hexadecimal string
     * @return Binary array
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1){
            return null;
        }
        byte[] result = new byte[hexStr.length()/2];
        for (int i = 0;i< hexStr.length()/2; i++) {
            int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
            int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

}
/**
 * @author Created by qiyei2015 on 2017/12/16.
 * @version: 1.0
 * @email: 1273482124@qq.com
 * @description:
 */
public class CryptoProvider extends Provider {

    public CryptoProvider() {
        super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
        put("SecureRandom.SHA1PRNG",
                "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
        put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
    }

}

Generally speaking, we will encapsulate the encrypted and decrypted interfaces, so the encapsulated interfaces are as follows:

/**
 * @author Created by qiyei2015 on 2017/12/13.
 * @version: 1.0
 * @email: 1273482124@qq.com
 * @description: Encryption Manager
 */
public class EncryptManager {

    private static final String TAG = AES.class.getSimpleName();

    /**
     * encryption
     * @param rules Encryption rules
     * @param plainText Clear text before encryption
     * @return Encrypted ciphertext hexadecimal string
     */
    public static String encrypt(String rules,String plainText){
        if (TextUtils.isEmpty(plainText) || TextUtils.isEmpty(rules)){
            return null;
        }
        byte[] encryptResult = AES.encrypt(rules,plainText);
        if (encryptResult != null){
            return AES.parseByte2HexStr(encryptResult);
        }
        return null;
    }

    /**
     * Decrypt
     * @param rules
     * @param encryptText Encrypted ciphertext hexadecimal string
     * @return Clear text before encryption
     */
    public static String decrypt(String rules,String encryptText){
        if (TextUtils.isEmpty(encryptText) || TextUtils.isEmpty(rules)){
            return null;
        }
        byte[] decryptResult = AES.decrypt(rules,AES.parseHexStr2Byte(encryptText));
        if (decryptResult != null){
            try {
                return new String(decryptResult,"utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}

In addition, in the actual development, the encryption and decryption rules need to do special processing to prevent decompilation from being found. If it is a fixed rule, you can consider putting it in the so library to prevent decompilation.

3 encryption example

Here is an example of AES encryption and decryption:

public class EncryptActivity extends AppCompatActivity {


    private EditText mEditTextRules;

    private EditText mEditTextContent;

    private TextView mTextViewResult;

    private Button mButton1;

    private Button mButton2;

    String encryptResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_encrypt);

        mEditTextRules = (EditText) findViewById(R.id.edt1);
        mEditTextContent = (EditText) findViewById(R.id.edt2);

        mTextViewResult = (TextView) findViewById(R.id.tv2);

        mButton1 = (Button) findViewById(R.id.btn1);
        mButton2 = (Button) findViewById(R.id.btn2);

        mButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                encryptResult = EncryptManager.encrypt(mEditTextRules.getText().toString(),mEditTextContent.getText().toString());
                mTextViewResult.setText("Encryption result:" + encryptResult);
            }
        });

        mButton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String result = EncryptManager.decrypt(mEditTextRules.getText().toString(),encryptResult);
                mTextViewResult.setText("Encryption result:" + encryptResult
                        + "\n\n" + "Decryption result:" + result);
            }
        });

    }
}

The operation effect of the program is as follows:

Source code reference:
https://github.com/qiyei2015/EssayJoke SDK encrypt section

Tags: Java Android SHA1 Apache

Posted on Sat, 02 May 2020 07:56:31 -0700 by phpconnect