欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android数据加密之Aes加密

程序员文章站 2024-03-05 08:29:12
前言: 项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密。  其他几种加密方式:  ...

前言:

项目中除了登陆,支付等接口采用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);

运行耗时:

Android数据加密之Aes加密

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

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