Detailed Explanation of Encryption Algorithm for Android Security Protection

  • 2021-12-13 09:30:01
  • OfStack

Directory summary Android applies the commonly used encryption algorithm MD5RSAAES

Summary

Maybe some developers or enterprises think. Our company's app, the amount of data is small, and there will be hackers who are full and have nothing to do to crack it. It's not Alipay, or other applications with a large number of users. If you think so, you can only say that you are short-sighted.

Common Encryption Algorithms for Android Applications

If the encrypted content can be restored, it can be divided into reversible encryption and irreversible encryption.

Irreversible encryption: That is to say, the encrypted data cannot be restored to the original data. For example, MD5 encrypts a password: 123456 encrypts it into afabsbfbabf437hfbbff73 (the result is not necessarily this, just an example). That is to say, the encrypted result afabsbfbabf437hfbbff73 cannot decrypt the value 123456.

Reversible encryption: Reversible encryption has a public key and a private key. Data is encrypted by the public key and decrypted by the private key. Representatives are: RSA, AES.

Symmetric encryption and asymmetric encryption: Reversible encryption is divided into symmetric encryption (encryption and decryption use the same key) and asymmetric encryption (encryption and decryption keys are separated) according to whether they use the same key for encryption and decryption

MD5

Features of MD5:

1. Compressibility: For data of any length, the calculated length of MD5 value is fixed.

2. Easiness of calculation: It is very easy to calculate MD5 value from raw data.

3. Anti-modification: If there is only one point of change in the data, the difference of MD5 will be great.

4. Strong collision resistance: It is very difficult to find an MD5 with the same MD5 calculated from the original data.

Application scenarios of MD5:

1, 1 sex verification (for example, if you download a file and don't know whether the file is downloaded, you can check it by MD5. Encrypting files is time-consuming and needs to be put into sub-threads)

2. Password storage (if you log in and register, the account password will be saved in sp, and it will be saved directly to the MD5 value of the account password. This can also prevent the server authority holder from knowing this password)

Simple Use of MD5

Write a tool class for MD5 first


package com.example.huangjialin.md5test;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Utils {

    public static String md5(String content) {
        byte[] hash = null;
        try {
            hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        StringBuilder stringBuilder = new StringBuilder(hash.length * 2);
        for (byte b: hash) {
            if ((b & 0xFF) < 0x10){
                stringBuilder.append("0");

            }
            stringBuilder.append(Integer.toHexString(b & 0xFF));

        }
        return stringBuilder.toString();
    }

}

Simply explain the above, first of all, through MessageDigest. getInstance ("MD5") to get MessageDigest this class, this class is java comes with an encryption class, and then through the call digest () method to get the encrypted byte array. The parameter passed in by this method is byte [] input, so you also need to convert the string to byte []. After getting the encrypted byte array, convert them to 16 forbidden strings, and then splice them together.

Then call directly:


/**
* MD5 Encryption 
*/
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String md5_123456abc = Utils.md5("123456abc");
        String md5_huangjialin = Utils.md5("huangjialin");
        Log.i("huangjialin","    md5_123456abc Calculated MD5 The value is:     " + md5_123456abc);
        Log.i("huangjialin","    md5_huangjialin Calculated MD5 The value is:    " + md5_huangjialin);
    }
});

Result:

09-20 15:33: 12. 208 7352-7352/com. example. huangjialin. md5ES90I/huangjialin: d5_123456abc The calculated MD5 value is: df10ef8509dc176d733d59549dbfaf

09-20 15:33: 12. 208 7352-7352/com. example. huangjialin. md5test I/huangjialin: md5_huangjialin the calculated value of MD5 is: 08e76895478c866919d7d087db0070

There is a digression here: there are many kinds of Log output logs, such as Log. i (); Log. d () and so on, but now some mobile phone manufacturers directly block the logs with lower grades, so some log outputs can be seen in some mobile phones, while some mobile phones do not. The solution is to change the OK with higher output level.

RSA

RSA is a popular asymmetric encryption now, which requires a pair of keys (public key and private key). The public key is encrypted and the private key is decrypted.

Encryption Principle of RSA

1. Two large prime numbers, P and Q, are randomly selected, P is not equal to Q, and the calculated results are as follows: N = P*Q;

2. Choose a natural number E greater than 1 and less than N. E must be coprime with (P-1) * (Q-1).

3. Calculate D: D*E = mod (P-1) * Q-1 by formula

4. Destroy P and Q

The final N, E is the public key, and D is the private key.

RSA Encryption and Decryption Steps

1. Party A generates a key pair (public key and private key, the public key is used to encrypt data, and the private key is kept by itself to decrypt data)

2. Party A uses the private key to encrypt the data, then uses the private key to sign the encrypted data, and sends these to Party B. Party B uses the public key and the signature to verify whether the decrypted data is valid, and if so, uses the public key to decrypt the data

3. Party B uses the public key to encrypt the data and sends the encrypted data to Party A. After Party A or encrypts the data, it can decrypt it through the private key.

RSA usage scenarios

Some sensitive data in the project, such as ID number, bank card, and other related information can be transmitted to the server after encryption, and the server uses the private key to decrypt.

RSA key pair generation

There are two ways to generate key pairs in RSA


/*
       Initialization KeyPairGenerator Class and get the public and private keys 
    */
    byte[] publicKeyByte;
    byte[] prvateKtyByte;

    public void getKey() {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( " RSA " );//KeyPairGenerator Class is java That specializes in generating key pairs 1 A class. 
            keyPairGenerator.initialize(1024); // Set the size of the key pair 
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();// Get the private key 
            PublicKey publicKey = keyPair.getPublic();// Get the public key 
            prvateKtyByte = privateKey.getEncoded();// Byte array corresponding to private key 
            publicKeyByte = publicKey.getEncoded(); // Byte array corresponding to public key 

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

Of course, the above method of generating key pairs is rarely used in projects, and the second method is used more often.

The second is to generate key pairs through OpenSSl tool

This way of generating key pairs requires the installation of OpenSSl. I won't say how to install it here. Here, I simply say that 1 command is needed to generate a key pair

Generate the private key using the command:

genrsa -out rsa_private_key.pem 1024

This command asks openssl to randomly generate a private key with a length of 1024

Generate a public key using a command:

rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

After the command is successful, the public key and private key will be generated in the bin directory under openSSL, and then encryption and decryption can be carried out.

Encryption


/**
     *  Encryption 
     */


    @RequiresApi(api = Build.VERSION_CODES.O)
    public byte[] encryption(String content) {
        byte[] result = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByte);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            result = cipher.doFinal(content.getBytes());
            Log.i("huangjialin", "---->  " + Base64.getEncoder().encodeToString(result));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return result;
    }

Decryption


/**
     *  Decryption 
     */

    @RequiresApi(api = Build.VERSION_CODES.O)

    public void decryption() {

        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA");
            // The private key needs to be passed through PKCS8EncodedKeySpec To read 
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(prvateKtyByte);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            // Generate private key 
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //String content = "123456";
            byte[] input = encryption("123456");
            byte[] result = cipher.doFinal(input);
            Log.i("huangjialin", "-- Decryption -->  " + new String(result));
            //Assert.assertTrue(content.equals(new String(result)));


        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }


    }

Of course, I write the above code for testing. In the real project, I have to encapsulate it and make it into a tool class to call.

AES

AES is a symmetric encryption, that is to say, AES is used for encryption and decryption, and the keys they use are all 1. AES encryption algorithm is an advanced encryption standard in cryptography, also known as Rijndael encryption method, which is a block encryption standard adopted by the US federal government. This standard is used to replace the original DES, which has been analyzed and used by many parties. At the same time, AES's algorithm has high encryption strength and high execution efficiency.

AES usage scenarios

1. Because AES is symmetric encryption, encryption and decryption all use the same key, so some sensitive data in the project need to be saved locally. You can encrypt the key with AES first. If you need to use it, you can take out the data and decrypt it again.

2. You can encrypt some sensitive data and then pass it to the server.

AES uses

The key can be obtained in this way before Android 7.0


private SecretKey generateKey(String seed) throws Exception {
        //  Get the secret key generator 
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //  Initialize by seed 
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");

        secureRandom.setSeed(seed.getBytes("UTF-8"));
        keyGenerator.init(128, secureRandom);
        //  Generate the secret key and return it 
        return keyGenerator.generateKey();
    }

However, it is not supported after Android 7.0, and Crypto is removed. Of course, Google also gives a solution to this way of obtaining keys after 7.0, but the official does not recommend this way of obtaining keys. You can see the details here. https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in. html

The official gives another way, which does not need to obtain the key, but defines the form of the password.


package com.example.huangjialin.md5test;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

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

public class MainActivity extends AppCompatActivity {
    private EditText edittext;
    private Button button, jiami, jiemi;
    private TextView textView;
    private SecretKey secretKey;
    private byte[] bytes;
    private String content = "huangjialin, I am the data to be encrypted ";
    String password = "huangji Yellow family phosphorus ";

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

        edittext = findViewById(R.id.edittext);
        button = findViewById(R.id.button);
        textView = findViewById(R.id.textview);
        jiami = findViewById(R.id.jiami);
        jiemi = findViewById(R.id.jiemi);

        Log.i("huagjialin", "-- Encrypted data -- > " + content);

        /**
         *  Get the key 
         */
       /* button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    secretKey = generateKey("huangjiain");
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });*/


        /**
         *  Encryption 
         */

        jiami.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    bytes = encrypt(content, password);
                    String str = new String(bytes);
                    Log.i("huagjialin", "-- Encrypted data -- > " + Base64.decode(str,Base64.DEFAULT));
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });

        /**
         *  Decryption 
         */

        jiemi.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    byte[] by = decrypt(bytes, password);
                    String string = new String(by);
                    Log.i("huagjialin", "-- Decrypted data -- > " + string);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


    }

    /**
     *  Another 1 Encryption forms 
     */
    private byte[] encrypt(String content, String password) throws Exception {
        //  Create AES Secret key 
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES/CBC/PKCS5PADDING");
        //  Create a cipher 
        Cipher cipher = Cipher.getInstance("AES");
        //  Initialize the encryptor 
        cipher.init(Cipher.ENCRYPT_MODE, key);
        //  Encryption 
        return cipher.doFinal(content.getBytes("UTF-8"));
    }


    /**
     *  Decryption 
     */
    private byte[] decrypt(byte[] content, String password) throws Exception {
        //  Create AES Secret key 
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES/CBC/PKCS5PADDING");
        //  Create a cipher 
        Cipher cipher = Cipher.getInstance("AES");
        //  Initialize the decrypter 
        cipher.init(Cipher.DECRYPT_MODE, key);
        //  Decryption 
        return cipher.doFinal(content);
    }

}

09-2021: 12:36. 394 15933-15933/com. example. huangjialin. md5test I/huagjialin:--Encrypted data-- > huangjialin, I am the data to be encrypted

09-2021: 12:39. 561 15933-15933/com. example. huangjialin. md5test I/huagjialin:--Encrypted data-- > [B@d62495e

09-2021: 12:41. 829 15933-15933/com. example. huangjialin. md5test I/huagjialin:-- > huangjialin, I am the data to be encrypted

These are some of the contents of several kinds of encryption that we commonly use.

The above is a detailed explanation of Android security protection of the encryption algorithm details, more information about Android security protection of the encryption algorithm please pay attention to other related articles on this site!


Related articles: