android中使用AES加解密

来源:互联网 发布:Linux线程间的通信方式 编辑:程序博客网 时间:2024/04/28 19:43

android中使用AES加解密


今天在android项目中使用AES对数据进行加解密,遇到了很多问题,网上也找了很多资料,也不行。不过最后还是让我给搞出来了,这里把这个记录下来,不要让别人走我的弯路,因为网上绝大多数的例子都是行不通的。好了,接下来开始讲解
1、Aes工具类

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 强随机种子算法, 要区别4.2以上版本的调用方法    private static final String IV = "qws871bz73msl9x8";    private static final String AES = "AES";   //AES 加密    private static final String CIPHERMODE = "AES/CBC/PKCS5Padding";   //algorithm/mode/padding    /**     * 加密     */    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;    }    /**     * 生成随机数,可以当做动态的密钥     * 加密和解密的密钥必须一致,不然将不能解密     */    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;    }    /**     *     对密钥进行处理     */    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, "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        //AES中128位密钥版本有10个加密循环,192比特密钥版本有12个加密循环,256比特密钥版本则有14个加密循环。        SecretKey skey = kgen.generateKey();        byte[] raw = skey.getEncoded();        return raw;    }    /**     *   二进制转字符     */    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));    }    /**     * 将二进制转换成16进制     *     * @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();    }    /**     * 将16进制转换为二进制     *     * @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、mainActivity和layout文件如下:

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);    }    /**     * 加密     *     * @param view     */    public void encrypt(View view) {        String inputString = mInputET.getText().toString().trim();        if (inputString.length() == 0) {            Toast.makeText(this, "请输入要加密的内容", Toast.LENGTH_SHORT).show();            return;        }        String encryStr = Aes.encrypt(PASSWORD_STRING, inputString);        mShowInputTV.setText(encryStr);    }    /**     * 解密     *     * @param view     */    public void decrypt(View view) {        String encryptString = mShowInputTV.getText().toString().trim();        if (encryptString.length() == 0) {            Toast.makeText(this, "解密字符串不能为空", Toast.LENGTH_SHORT).show();            return;        }        String decryStr = Aes.decrypt(PASSWORD_STRING, encryptString);        mShowEncryputTV.setText(decryStr);    }}

layout文件

<?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="输入要加密的内容" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="encrypt"        android:text="点击进行ASE加密" />    <TextView        android:id="@+id/show_ase_encrypt"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:text="显示加密后的内容" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="decrypt"        android:text="点击进行ASE解密" />    <TextView        android:id="@+id/show_oringe_encrypt"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:text="显示加密后的内容" /></LinearLayout>

3、最后的效果如下:
1、是一个输入框,输入钥加密的字符串;2、点击“AES加密”按钮后生产的加密字符串;3、点击“AES解密”按钮后,对加密字符串进行解密,然后在3处看到解密后的字符串,可以看到加密字符串和解密字符串相同,所以AES加解密成功了

4、总结

  1. 要用真机测试,模拟器是不行的,具体原因没去研究;
  2. 点击获取本例的github地址
  3. 也可以通过android studio直接git下来,git地址为https://github.com/chenguo4930/AndroidAES.git
  4. 其中也还有DES、RSA的加解密demo的github地址为https://github.com/chenguo4930/EncodeDemo
    git地址为:
    https://github.com/chenguo4930/EncodeDemo.git
1 0
原创粉丝点击