Android AES加密解密

打印 上一主题 下一主题

主题 523|帖子 523|积分 1569

 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布局:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"
  4.     xmlns:tools="http://schemas.android.com/tools"
  5.     android:layout_width="match_parent"
  6.     android:layout_height="match_parent"
  7.     android:orientation="vertical"
  8.     tools:context=".AesActivity">
  9.     <EditText
  10.         android:id="@+id/etData"
  11.         android:layout_width="match_parent"
  12.         android:layout_height="wrap_content" />
  13.     <Button
  14.         android:id="@+id/aesEncryption"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="wrap_content"
  17.         android:layout_gravity="center"
  18.         android:text="AES加密" />
  19.     <TextView
  20.         android:id="@+id/tvEncryption"
  21.         android:layout_width="match_parent"
  22.         android:layout_height="wrap_content"
  23.         android:layout_margin="5dp"
  24.         android:gravity="center" />
  25.     <Button
  26.         android:id="@+id/aesDecrypt"
  27.         android:layout_width="wrap_content"
  28.         android:layout_height="wrap_content"
  29.         android:layout_gravity="center"
  30.         android:text="AES解密" />
  31.     <TextView
  32.         android:id="@+id/tvDecrypt"
  33.         android:layout_width="match_parent"
  34.         android:layout_height="wrap_content"
  35.         android:layout_margin="5dp"
  36.         android:gravity="center" />
  37.    
  38. </LinearLayout>
复制代码
2、加密解密代码:
创建一个AesUtils类:
  1. public class AesUtils {
  2.     private static final String SHA1PRNG = "SHA1PRNG";   // SHA1PRNG 强随机种子算法
  3.     private static final String AES = "AES";   //AES 加密
  4.     private static final String CIPHERMODE = "AES/CBC/PKCS5Padding"; //AES算法/CBC模式/PKCS5Padding填充模式
  5.     /**
  6.      * 加密
  7.      */
  8.     public static String encrypt(String key, String cleartext) {
  9.         if (TextUtils.isEmpty(cleartext)) {
  10.             return cleartext;
  11.         }
  12.         try {
  13.             byte[] result = encrypt(key, cleartext.getBytes());
  14.             return parseByte2HexStr(result);
  15.         } catch (Exception e) {
  16.             e.printStackTrace();
  17.         }
  18.         return null;
  19.     }
  20.     /**
  21.     * 加密
  22.     */
  23.     public static byte[] encrypt(String key, byte[] clear) throws Exception {
  24.         byte[] raw = getRawKey(key.getBytes());
  25.         SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
  26.         Cipher cipher = Cipher.getInstance(CIPHERMODE);
  27.         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new         
  28.         byte[cipher.getBlockSize()]));
  29.         byte[] encrypted = cipher.doFinal(clear);
  30.         return encrypted;
  31.     }
  32.     /**
  33.      * 解密
  34.      */
  35.     public static String decrypt(String key, String encrypted) {
  36.         if (TextUtils.isEmpty(encrypted)) {
  37.             return encrypted;
  38.         }
  39.         try {
  40.             byte[] enc = parseHexStr2Byte(encrypted);
  41.             byte[] result = decrypt(key, enc);
  42.             return new String(result);
  43.         } catch (Exception e) {
  44.             e.printStackTrace();
  45.         }
  46.         return null;
  47.     }
  48.     /**
  49.      * 解密
  50.      */
  51.     public static byte[] decrypt(String key, byte[] encrypted) throws Exception {
  52.         byte[] raw = getRawKey(key.getBytes());
  53.         SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
  54.         Cipher cipher = Cipher.getInstance(CIPHERMODE);
  55.         cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new
  56.         byte[cipher.getBlockSize()]));
  57.         byte[] decrypted = cipher.doFinal(encrypted);
  58.         return decrypted;
  59.     }
  60.     /**
  61.      * 处理密钥
  62.      */
  63.     @SuppressLint("DeletedProvider")
  64.     public static byte[] getRawKey(byte[] seed) throws Exception {
  65.         KeyGenerator kgen = KeyGenerator.getInstance(AES);
  66.         //for android
  67.         SecureRandom sr = null;
  68.         // 在4.2以上版本中,SecureRandom获取方式发生了改变
  69.         if (android.os.Build.VERSION.SDK_INT >= 17) {
  70.             sr = SecureRandom.getInstance(SHA1PRNG, new CryptoProvider());
  71.         } else {
  72.             sr = SecureRandom.getInstance(SHA1PRNG);
  73.         }
  74.         
  75.         sr.setSeed(seed);
  76.         kgen.init(128, sr); //128bits,192bits,256bits
  77.         //AES中128位密钥,加密轮次为10轮;192位密钥,加密轮次为12轮;256位密钥,加密轮次为14轮。
  78.         SecretKey skey = kgen.generateKey();
  79.         byte[] raw = skey.getEncoded();
  80.         return raw;
  81.     }
  82.    
  83.     /**
  84.      * 将二进制转换成16进制
  85.      */
  86.     public static String parseByte2HexStr(byte buf[]) {
  87.         StringBuilder sb = new StringBuilder();
  88.         for (int i = 0; i < buf.length; i++) {
  89.             String hex = Integer.toHexString(buf[i] & 0xFF);
  90.             if (hex.length() == 1) {
  91.                 hex = '0' + hex;
  92.             }
  93.             sb.append(hex.toUpperCase());
  94.         }
  95.         return sb.toString();
  96.     }
  97.     /**
  98.      * 将16进制转换为二进制
  99.      */
  100.     public static byte[] parseHexStr2Byte(String hexStr) {
  101.         if (hexStr.length() < 1)
  102.             return null;
  103.         byte[] result = new byte[hexStr.length() / 2];
  104.         for (int i = 0; i < hexStr.length() / 2; i++) {
  105.             int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
  106.             int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
  107.                     16);
  108.             result[i] = (byte) (high * 16 + low);
  109.         }
  110.         return result;
  111.     }
  112. public static class CryptoProvider extends Provider {
  113.         public CryptoProvider() {
  114.             super("Crypto", 1.0, "HARMONY(SHA1 digest;SecureRandom;SHA1withDSA signature)");
  115.             put("SecureRandom.SHA1PRNG", "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
  116.             put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
  117.         }
  118.     }
  119. }
复制代码

3、AesActivity代码:
  1. package com.example.myapplication;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.Button;
  6. import android.widget.EditText;
  7. import android.widget.TextView;
  8. public class AesActivity extends AppCompatActivity implements View.OnClickListener {
  9.     //AES加密
  10.     private Button aesEncryption;
  11.     private TextView tvEncryption;
  12.     //AES解密
  13.     private Button aesDecrypt;
  14.     private TextView tvDecrypt;
  15.     //输入框
  16.     private EditText etData;
  17.     //加密解密的key
  18.     String key = "1234567890";
  19.     @Override
  20.     protected void onCreate(Bundle savedInstanceState) {
  21.         super.onCreate(savedInstanceState);
  22.         setContentView(R.layout.activity_aes);
  23.         initView();
  24.     }
  25.     private void initView() {
  26.         aesEncryption = findViewById(R.id.aesEncryption);
  27.         aesDecrypt = findViewById(R.id.aesDecrypt);
  28.         tvEncryption = findViewById(R.id.tvEncryption);
  29.         tvDecrypt = findViewById(R.id.tvDecrypt);
  30.         etData = findViewById(R.id.etData);
  31.         aesEncryption.setOnClickListener(this);
  32.         aesDecrypt.setOnClickListener(this);
  33.     }
  34.     @Override
  35.     public void onClick(View v) {
  36.         //要加密的字符串
  37.         String encryptData = etData.getText().toString();
  38.         switch (v.getId()) {
  39.             case R.id.aesEncryption://加密
  40.                 tvEncryption.setText(AesUtils.encrypt(key, encryptData));
  41.                 break;
  42.             case R.id.aesDecrypt://解密
  43.                 tvDecrypt.setText(AesUtils.decrypt(key, tvEncryption.getText().toString()));
  44.                 break;
  45.             default:
  46.                 break;
  47.         }
  48.     }
  49. }
复制代码
五、效果图





免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

伤心客

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表