Android AES加密解密
AES算法全称Advanced Encryption Standard。它是典型的“对称加密算法”,主要作用是保证私密信息不被泄露。
一、密钥
密钥是AES算法实现加密和解密的根本,因为它对明文的加密和解密需要使用同一个密钥。
AES支持三种长度的密钥:128位,192位,256位。
二、填充
AES算法在对明文加密的时候,并不是把整个明文加密成一段密文,而是把明文拆分成一个独立的明文块,每一个明文块长度128bit,也就是说每个明文块为16个字节(每个字节8位)。
填充模式:
1、NoPadding:不做任何填充,但要求明文必须是16字节的整数倍。
2、PKCS5Padding(默认):如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字符,并且每个字节的值等于缺少的字符数。
例如明文:{1,a,3,c,5,k,6,8,l,o},缺少6个字节,则补足为{1,a,3,c,5,k,6,8,l,o,6,6,6,6,6,6}
3、ISO10126Padding:如果明文块少于16个字节,在明文块末尾补足相应数量的字节,最后一个字符值等于缺少的字数,其他字符填充随机数。
例如明文:{1,a,3,c,5,k,6,8,l,o},缺少6个字节,则可能补足为{1,a,3,c,5,k,6,8,l,o,2,i,9,q,7,6}。
三、模式
AES加密算法提供了不同的工作模式:
1、ECB模式(默认):电码本模式(Electronic Codebook Book)
2、CBC模式:密码分组链接模式(Cipher Block Chaining)
3、CTR模式:计算器模式(Counter)
4、CFB模式:密码反馈模式(Cipher FeedBack)
5、OFB模式:输出反馈模式(Output FeedBack)
四、AES-CBC模式 加密解密
1、aes_activity.xml布局:
2、加密解密代码:
创建一个AesUtils类:
public class AesUtils { private static final String SHA1PRNG = "SHA1PRNG"; // SHA1PRNG 强随机种子算法 private static final String AES = "AES"; //AES 加密 private static final String CIPHERMODE = "AES/CBC/PKCS5Padding"; //AES算法/CBC模式/PKCS5Padding填充模式 /** * 加密 */ 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; } /** * 加密 */ 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; } /** * 解密 */ 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; } /** * 解密 */ 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; } /** * 处理密钥 */ @SuppressLint("DeletedProvider") public static byte[] getRawKey(byte[] seed) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance(AES); //for android SecureRandom sr = null; // 在4.2以上版本中,SecureRandom获取方式发生了改变 if (android.os.Build.VERSION.SDK_INT >= 17) { sr = SecureRandom.getInstance(SHA1PRNG, new CryptoProvider()); } else { sr = SecureRandom.getInstance(SHA1PRNG); } sr.setSeed(seed); kgen.init(128, sr); //128bits,192bits,256bits //AES中128位密钥,加密轮次为10轮;192位密钥,加密轮次为12轮;256位密钥,加密轮次为14轮。 SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); return raw; } /** * 将二进制转换成16进制 */ public static String parseByte2HexStr(byte buf[]) { StringBuilder sb = new StringBuilder(); for (int i = 0; i3、AesActivity代码:
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class AesActivity extends AppCompatActivity implements View.OnClickListener { //AES加密 private Button aesEncryption; private TextView tvEncryption; //AES解密 private Button aesDecrypt; private TextView tvDecrypt; //输入框 private EditText etData; //加密解密的key String key = "1234567890"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_aes); initView(); } private void initView() { aesEncryption = findViewById(R.id.aesEncryption); aesDecrypt = findViewById(R.id.aesDecrypt); tvEncryption = findViewById(R.id.tvEncryption); tvDecrypt = findViewById(R.id.tvDecrypt); etData = findViewById(R.id.etData); aesEncryption.setOnClickListener(this); aesDecrypt.setOnClickListener(this); } @Override public void onClick(View v) { //要加密的字符串 String encryptData = etData.getText().toString(); switch (v.getId()) { case R.id.aesEncryption://加密 tvEncryption.setText(AesUtils.encrypt(key, encryptData)); break; case R.id.aesDecrypt://解密 tvDecrypt.setText(AesUtils.decrypt(key, tvEncryption.getText().toString())); break; default: break; } } }五、结果图