Detailed Explanation of Encryption Algorithm for Android Security Protection
- 2021-12-13 09:30:01
- OfStack
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!