Today, using AES to encrypt and decrypt data in the Android project, I encountered a lot of problems, and I found a lot of information on the Internet, too. But in the end, let me get it out, record this here, don't let others take my detour, because most of the examples on the Internet will not work. Okay, let's start to explain
1. Aes tools
package com.example.cheng.aesencrypt;
import android.text.TextUtils;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/ **
* class description here
*
* @author cheng
* @version 1.0.0
* @since 2016-11-02
* /
public class Aes {
private static final String SHA1PRNG = "SHA1PRNG"; // SHA1PRNG strong random seed algorithm, to distinguish the calling method of 4.2 and above
private static final String IV = "qws871bz73msl9x8";
private static final String AES = "AES"; // AES encryption
private static final String CIPHERMODE = "AES / CBC / PKCS5Padding"; // algorithm / mode / padding
/ **
* Encrypt
* /
public static String encrypt (String key, String cleartext) {
if (TextUtils.isEmpty (cleartext)) {
return cleartext;
}
try {
byte [] result = encrypt (key, cleartext.getBytes ());
return parseByte2HexStr (result);
} catch (Exception e) {
e.printStackTrace ();
}
return null;
}
/ **
* Encrypt
* /
public static byte [] encrypt (String key, byte [] clear) throws Exception {
byte [] raw = getRawKey (key.getBytes ());
SecretKeySpec skeySpec = new SecretKeySpec (raw, AES);
Cipher cipher = Cipher.getInstance (CIPHERMODE);
cipher.init (Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec (new byte [cipher.getBlockSize ()]));
byte [] encrypted = cipher.doFinal (clear);
return encrypted;
}
/ **
* Decrypt
* /
public static String decrypt (String key, String encrypted) {
if (TextUtils.isEmpty (encrypted)) {
return encrypted;
}
try {
byte [] enc = parseHexStr2Byte (encrypted);
byte [] result = decrypt (key, enc);
return new String (result);
} catch (Exception e) {
e.printStackTrace ();
}
return null;
}
/ **
* Decrypt
* /
public static byte [] decrypt (String key, byte [] encrypted) throws Exception {
byte [] raw = getRawKey (key.getBytes ());
SecretKeySpec skeySpec = new SecretKeySpec (raw, AES);
Cipher cipher = Cipher.getInstance (CIPHERMODE);
cipher.init (Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec (new byte [cipher.getBlockSize ()]));
byte [] decrypted = cipher.doFinal (encrypted);
return decrypted;
}
/ **
* Generate random numbers, which can be used as dynamic keys
* The encryption and decryption keys must be the same, otherwise it will not be decrypted
* /
public static String generateKey () {
try {
SecureRandom secureRandom = SecureRandom.getInstance (SHA1PRNG);
byte [] key = new byte [20];
secureRandom.nextBytes (key);
return toHex (key);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace ();
}
return null;
}
/ **
* Process the key
* /
public static byte [] getRawKey (byte [] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance (AES);
// for android
SecureRandom sr = null;
// In the version above 4.2, the acquisition method of SecureRandom has changed
if (android.os.Build.VERSION.SDK_INT> = 17) {
sr = SecureRandom.getInstance (SHA1PRNG, "Crypto");
} else {
sr = SecureRandom.getInstance (SHA1PRNG);
}
// for Java
// secureRandom = SecureRandom.getInstance (SHA1PRNG);
sr.setSeed (seed);
kgen.init (128, sr); // 256 bits or 128 bits, 192bits
// The 128-bit key version in AES has 10 encryption cycles, the 192-bit key version has 12 encryption cycles, and the 256-bit key version has 14 encryption cycles.
SecretKey skey = kgen.generateKey ();
byte [] raw = skey.getEncoded ();
return raw;
}
/ **
* Binary to character
* /
public static String toHex (byte [] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer (2 * buf.length);
for (int i = 0; i <buf.length; i ++) {
appendHex (result, buf [i]);
}
return result.toString ();
}
private static void appendHex (StringBuffer sb, byte b) {
sb.append (IV.charAt ((b >> 4) & 0x0f)). append (IV.charAt (b & 0x0f));
}
/ **
* Convert binary to hexadecimal
*
* @param buf
* @return
* /
public static String parseByte2HexStr (byte buf []) {
StringBuilder sb = new StringBuilder ();
for (int i = 0; i <buf.length; i ++) {
String hex = Integer.toHexString (buf [i] & 0xFF);
if (hex.length () == 1) {
hex = '0' + hex;
}
sb.append (hex.toUpperCase ());
}
return sb.toString ();
}
/ **
* Convert hexadecimal to binary
*
* @param hexStr
* @return
* /
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;
}
}
2. The mainActivity and layout files are as follows:
package com.example.cheng.aesencrypt;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private EditText mInputET;
private TextView mShowEncryputTV;
private TextView mShowInputTV;
private static final String PASSWORD_STRING = "12345678";
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
mInputET = (EditText) findViewById (R.id.ase_input);
mShowEncryputTV = (TextView) findViewById (R.id.show_oringe_encrypt);
mShowInputTV = (TextView) findViewById (R.id.show_ase_encrypt);
}
/ **
* Encrypt
*
* @param view
* /
public void encrypt (View view) {
String inputString = mInputET.getText (). ToString (). Trim ();
if (inputString.length () == 0) {
Toast.makeText (this, "Please enter the content to be encrypted", Toast.LENGTH_SHORT) .show ();
return;
}
String encryStr = Aes.encrypt (PASSWORD_STRING, inputString);
mShowInputTV.setText (encryStr);
}
/ **
* Decrypt
*
* @param view
* /
public void decrypt (View view) {
String encryptString = mShowInputTV.getText (). ToString (). Trim ();
if (encryptString.length () == 0) {
Toast.makeText (this, "Decryption string cannot be empty", Toast.LENGTH_SHORT) .show ();
return;
}
String decryStr = Aes.decrypt (PASSWORD_STRING, encryptString);
mShowEncryputTV.setText (decryStr);
}
}
layout file
<? xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
xmlns: tools = "http://schemas.android.com/tools"
android: id = "@ + id / activity_main"
android: layout_width = "match_parent"
android: layout_height = "match_parent"
android: gravity = "center_vertical"
android: orientation = "vertical"
android: paddingBottom = "@ dimen / activity_vertical_margin"
android: paddingLeft = "@ dimen / activity_horizontal_margin"
android: paddingRight = "@ dimen / activity_horizontal_margin"
android: paddingTop = "@ dimen / activity_vertical_margin"
tools: context = "com.example.cheng.aesencrypt.MainActivity">
<EditText
android: id = "@ + id / ase_input"
android: layout_width = "match_parent"
android: layout_height = "wrap_content"
android: hint = "Enter the content to be encrypted" />
<Button
android: layout_width = "wrap_content"
android: layout_height = "wrap_content"
android: onClick = "encrypt"
android: text = "Click to encrypt ASE" />
<TextView
android: id = "@ + id / show_ase_encrypt"
android: layout_width = "match_parent"
android: layout_height = "wrap_content"
android: layout_marginTop = "10dp"
android: text = "Show encrypted content" />
<Button
android: layout_width = "wrap_content"
android: layout_height = "wrap_content"
android: onClick = "decrypt"
android: text = "Click to decrypt ASE" />
<TextView
android: id = "@ + id / show_oringe_encrypt"
android: layout_width = "wrap_content"
android: layout_height = "wrap_content"
android: layout_marginTop = "10dp"
android: text = "Show encrypted content" />
</ LinearLayout>
3. The final effect is as follows:
1), is an input box, enter the key encrypted string;
2). The encrypted string produced after clicking the "AES encryption" button;
3) After clicking the "AES decryption" button, decrypt the encrypted string, and then see the decrypted string at 3, you can see that the encrypted string and the decrypted string are the same, so AES encryption and decryption is successful
4. Summary
If you want to test with a real device, the simulator will not work, the specific reason has not been studied;
Click to get the github address of this example:
You can also directly git down through android studio, the git address is https://github.com/chenguo4930/AndroidAES.git
There are also DES, RSA encryption and decryption demo github address https://github.com/chenguo4930/EncodeDemo
The git address is: https://github.com/chenguo4930/EncodeDemo.git
The above is the entire content of this article. I hope it will be helpful for everyone's learning and I hope you can support the Yunqi community.