当前位置: 移动技术网 > 移动技术>移动开发>Android > Android数据加密之Aes加密

Android数据加密之Aes加密

2019年07月24日  | 移动技术网移动技术  | 我要评论

前言:

项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密。 

其他几种加密方式:
 •android数据加密之rsa加密
 •android数据加密之aes加密
 •android数据加密之des加密
 •android数据加密之md5加密
 •android数据加密之base64编码算法
 •android数据加密之sha安全散列算法 

什么是aes加密?

      高级加密标准(英语:advanced encryption standard,缩写:aes),在密码学中又称rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的des,已经被多方分析且广为全世界所使用。 

接下来我们来实际看下具体怎么实现: 

对于aesutils类常量简介: 

  private final static string hex = "0123456789abcdef";
  private static final string cbc_pkcs5_padding = "aes/cbc/pkcs5padding";//aes是加密方式 cbc是工作模式 pkcs5padding是填充模式
  private static final string aes = "aes";//aes 加密
  private static final string sha1prng="sha1prng";//// sha1prng 强随机种子算法, 要区别4.2以上版本的调用方法

如何生成一个随机key?

  /*
   * 生成随机数,可以当做动态的密钥 加密和解密的密钥必须一致,不然将不能解密
   */
  public static string generatekey() {
    try {
      securerandom localsecurerandom = securerandom.getinstance(sha1prng);
      byte[] bytes_key = new byte[20];
      localsecurerandom.nextbytes(bytes_key);
      string str_key = tohex(bytes_key);
      return str_key;
    } catch (exception e) {
      e.printstacktrace();
    }
    return null;
  }

aes密钥处理 

  // 对密钥进行处理
  private 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;
  }

aes加密过程 

/*
   * 加密
   */
  public static string encrypt(string key, string cleartext) {
    if (textutils.isempty(cleartext)) {
      return cleartext;
    }
    try {
      byte[] result = encrypt(key, cleartext.getbytes());
      return base64encoder.encode(result);
    } catch (exception e) {
      e.printstacktrace();
    }
    return null;
  }

  /*
  * 加密
  */
  private static byte[] encrypt(string key, byte[] clear) throws exception {
    byte[] raw = getrawkey(key.getbytes());
    secretkeyspec skeyspec = new secretkeyspec(raw, aes);
    cipher cipher = cipher.getinstance(cbc_pkcs5_padding);
    cipher.init(cipher.encrypt_mode, skeyspec, new ivparameterspec(new byte[cipher.getblocksize()]));
    byte[] encrypted = cipher.dofinal(clear);
    return encrypted;
  }

aes解密过程 

  /*
   * 解密
   */
  public static string decrypt(string key, string encrypted) {
    if (textutils.isempty(encrypted)) {
      return encrypted;
    }
    try {
      byte[] enc = base64decoder.decodetobytes(encrypted);
      byte[] result = decrypt(key, enc);
      return new string(result);
    } catch (exception e) {
      e.printstacktrace();
    }
    return null;
  }

  /*
   * 解密
   */
  private static byte[] decrypt(string key, byte[] encrypted) throws exception {
    byte[] raw = getrawkey(key.getbytes());
    secretkeyspec skeyspec = new secretkeyspec(raw, aes);
    cipher cipher = cipher.getinstance(cbc_pkcs5_padding);
    cipher.init(cipher.decrypt_mode, skeyspec, new ivparameterspec(new byte[cipher.getblocksize()]));
    byte[] decrypted = cipher.dofinal(encrypted);
    return decrypted;
  }

二进制转字符 

 //二进制转字符
  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(hex.charat((b >> 4) & 0x0f)).append(hex.charat(b & 0x0f));
  }

测试程序: 

 list<person> personlist = new arraylist<>();
    int testmaxcount = 1000;//测试的最大数据条数
    //添加测试数据
    for (int i = 0; i < testmaxcount; i++) {
      person person = new person();
      person.setage(i);
      person.setname(string.valueof(i));
      personlist.add(person);
    }
    //fastjson生成json数据
    string jsondata = jsonutils.objecttojsonforfastjson(personlist);
    log.e("mainactivity", "aes加密前json数据 ---->" + jsondata);
    log.e("mainactivity", "aes加密前json数据长度 ---->" + jsondata.length());

    //生成一个动态key
    string secretkey = aesutils.generatekey();
    log.e("mainactivity", "aes动态secretkey ---->" + secretkey);

    //aes加密
    long start = system.currenttimemillis();
    string encrystr = aesutils.encrypt(secretkey, jsondata);
    long end = system.currenttimemillis();
    log.e("mainactivity", "aes加密耗时 cost time---->" + (end - start));
    log.e("mainactivity", "aes加密后json数据 ---->" + encrystr);
    log.e("mainactivity", "aes加密后json数据长度 ---->" + encrystr.length());

    //aes解密
    start = system.currenttimemillis();
    string decrystr = aesutils.decrypt(secretkey, encrystr);
    end = system.currenttimemillis();
    log.e("mainactivity", "aes解密耗时 cost time---->" + (end - start));
    log.e("mainactivity", "aes解密后json数据 ---->" + decrystr);

运行耗时:

 由此可见对称aes效率还是比较高的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网