首先AES的话是属于对称加密,在了解之前首先要清楚对称加密和非对称加密的区别,简单的用大白话来讲的话对称加密的话是使用一个秘钥进行加密和解密,而非对称加密的话就就是有一个公钥还有一个私钥,公钥负责加密私钥负责解密
对称加密和非对称加密的区别:
对称加密的话加密解密的话要知道他的秘钥,秘钥的话是不好管理的,很容易杯抓包破解。但是想对于非对称加密他的运行速度是快的。一般我们在使用VPN或者代理进行加密通信的时候,这种时候既要包住数据的保密性,又要保证不能有太大的网络波动,会选择对称加密。
非对称解密的话他安全系数比较高,公钥加密,私钥解密,导致他的运行速度比较慢。一般的话用于秘钥,证书交换等
基于adnroid 底层具体代码如下:
定义一个这样的工具类,
public class AESUtils { /** * 说明: AES256加密 * * @param stringToEncode * 明文 * @param keyString * 密钥 * @return Bses64格式密文 */ public static String AES256Encode(String stringToEncode, String keyString) throws NullPointerException { if (keyString.length() == 0 || keyString == null) { return null; } if (stringToEncode.length() == 0 || stringToEncode == null) { return null; } try { SecretKeySpec skeySpec = getKey(keyString); byte[] data = stringToEncode.getBytes("UTF8"); final byte[] iv = new byte[16]; Arrays.fill(iv, (byte) 0x00); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec); String encrypedValue = Base64.encodeToString(cipher.doFinal(data), Base64.DEFAULT); return encrypedValue; } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } return ""; } /** * * 说明 :AES256解密 * * @param text * Base64格式密文 * @param keyString * 密钥 * @return String格式明文 */ public static String AES256Decrypt(String text, String keyString) { // byte[] rawKey = getRawKey(key); if (keyString.length() == 0 || keyString == null) { return null; } if (text.length() == 0 || text == null) { return null; } try { SecretKey key = getKey(keyString); final byte[] iv = new byte[16]; Arrays.fill(iv, (byte) 0x00); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); byte[] data = Base64.decode(text, Base64.DEFAULT); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec); byte[] decrypedValueBytes = (cipher.doFinal(data)); String decrypedValue = new String(decrypedValueBytes, "UTF-8"); return decrypedValue; } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalBlockSizeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BadPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ""; } /** * * 说明 :将密钥转行成SecretKeySpec格式 * * @param password * 16进制密钥 * @return SecretKeySpec格式密钥 */ private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException { int keyLength = 256; byte[] keyBytes = new byte[keyLength / 8]; Arrays.fill(keyBytes, (byte) 0x0); byte[] passwordBytes = toByte(password); int length = passwordBytes.length < keyBytes.length ? passwordBytes.length : keyBytes.length; System.arraycopy(passwordBytes, 0, keyBytes, 0, length); SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); return key; } /** * * 说明 :随机生成一组AES密钥 * * @return 16进制AES密钥 */ @SuppressLint("DeletedProvider") public static String getRawKey() { KeyGenerator kgen = null; SecureRandom sr = null; try { kgen = KeyGenerator.getInstance("AES"); if (android.os.Build.VERSION.SDK_INT >= 17) { sr = SecureRandom.getInstance("SHA1PRNG", "Crypto"); } else { sr = SecureRandom.getInstance("SHA1PRNG"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } kgen.init(256, sr); SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); String result = bytes2Hex(raw); return result; } /** * byte数组转换为16进制字符串 * * @param bts * 数据源 * @return 16进制字符串 */ public static String bytes2Hex(byte[] bts) { String des = ""; String tmp = null; for (int i = 0; i < bts.length; i++) { tmp = (Integer.toHexString(bts[i] & 0xFF)); if (tmp.length() == 1) { des += "0"; } des += tmp; } return des; } /** * 将16进制转换为byte数组 * * @param hexString * 16进制字符串 * @return byte数组 */ private static byte[] toByte(String hexString) { int len = hexString.length() / 2; byte[] result = new byte[len]; for (int i = 0; i < len; i++) { result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue(); } return result; } }
接下来的话简单编写一个activity xml页面
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <EditText android:id="@+id/Etext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button_encrypt" android:layout_width="90dp" android:layout_height="wrap_content" android:text="加密" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@+id/Etext" android:layout_marginLeft="20dp"> </Button> <Button android:id="@+id/button_decrypt" android:layout_width="90dp" android:layout_height="wrap_content" android:text="解密" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/Etext" android:layout_marginRight="20dp"> </Button> </androidx.constraintlayout.widget.ConstraintLayout>
在MainActivity里代码如下
这里定义了一个输入框,俩个按钮,加密解密
public class MainActivity extends AppCompatActivity { private EditText Etext; private Button buttonEncrypt; private Button buttonDecrypt; private String rawKey; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { Etext = (EditText) findViewById(R.id.Etext); buttonEncrypt = (Button) findViewById(R.id.button_encrypt); buttonDecrypt = (Button) findViewById(R.id.button_decrypt); //加密 buttonEncrypt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String text = Etext.getText().toString(); rawKey = AESUtils.getRawKey(); String dispName = AESUtils.AES256Encode(text, rawKey); Etext.setText("加密数据:"+dispName); Log.i("Encrypt", "原始数据: "+text); Log.i("Encrypt", "IV随机码: "+rawKey); Log.i("Encrypt", "加密数据: "+dispName); } }); //解密 buttonDecrypt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String text = Etext.getText().toString(); String dispName = AESUtils.AES256Decrypt(text, rawKey); Etext.setText(dispName); Log.i("Decrypt", "原始数据: "+text); Log.i("Decrypt", "IV随机码: "+rawKey); Log.i("Decrypt", "加密数据: "+dispName); } }); } }
具体的话需要各位实际操作一下其实没什么难点
我爱娜娜