当前位置: 移动技术网 > IT编程>移动开发>Android > Android使用KeyStore对数据进行加密的示例代码

Android使用KeyStore对数据进行加密的示例代码

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

朱桦年龄,热舞诱惑,杨晓波不雅图

谈到 android 安全性话题,android developers 官方网站给出了许多很好的建议和讲解,涵盖了存储数据、权限、网络、处理凭据、输入验证、处理用户数据、加密等方方面面

密钥的保护以及网络传输安全 应该是移动应用安全最关键的内容。android 提供大量用来保护数据的加密算法,例如 cipher 类中提供了 aes 和 rsa 算法,再例如安全随机数生成器 securerandom 给 keygenerator 提供了更加可靠的初始化参数,避免离线攻击等等。

而如果需要存储密钥以供重复使用,android 提供了 keystore 等可以长期存储和检索加密密钥的机制,android keystore 系统特别适合于存储加密密钥。”androidkeystore” 是 keystore 的一个子集,存进 androidkeystore 的 key 将受到签名保护,并且这些 key 是存在系统里的,而不是在 app 的 data 目录下,依托于硬件的 keychain 存储,可以做到 private key 一旦存入就无法取出,总之,每个 app 自己创建的 key,别的应用是访问不到的。

keystore 提供了两个能力:

有了这两个能力,我们的密钥保护就变得很容易了,你只需要:

在应用安装后第一次运行时,生成一个随机密钥,并存入 keystore

当你想存储一个数据,便从 keystore 中取出之前生成的随机密钥,对你的数据进行加密,加密完成后,已完成加密的数据可以随意存储在任意地方,比如 sharepreferences,此时即使它被他人读取到,也无法解密出你的原数据,因为他人取不到你的密钥

当你需要拿到你的原数据,只需要从 sharepreferences 中读取你加密后的数据,并从 keystore 取出加密密钥,使用加密密钥对 “加密后的数据” 进行解密即可

其中加密算法可以使用 cipher aes 来保证安全性,不要使用自己创造的加密算法。

这就是使用 keystore 的一整套流程,另外 keystore 还可以用来做数据签名和签名验证,就像一个黑匣子一样,具体可以自行搜索了解。

keystore 适于存储运行时生产获取到的数据,比如运行时,用户输入的密码,或者服务端传下来的 token,但无法用于存储我们需要预设在 app 内的 api key / secret,对于这类需要预设的固定密钥,我将介绍一种十分安全、难破解的保护方式。

加密:

public string encryptstring(string needencryptword, string alias) {
    if(!"".equals(alias)&&!"".equals(needencryptword)){
      if (build.version.sdk_int >= build.version_codes.jelly_bean_mr2) {
        initkeystore(alias);
      }
      string encryptstr="";
      byte [] vals=null;
      try {
        keystore.privatekeyentry privatekeyentry = (keystore.privatekeyentry)keystore.getentry(alias, null);
//      rsapublickey publickey = (rsapublickey) privatekeyentry.getcertificate().getpublickey();
        if(needencryptword.isempty()) {
//        toast.maketext(this, "enter text in the 'initial text' widget", toast.length_long).show();
          return encryptstr;
        }

//      cipher incipher = cipher.getinstance("rsa/ecb/pkcs1padding", "androidopenssl");
        cipher incipher = cipher.getinstance("rsa/ecb/pkcs1padding");
//      incipher.init(cipher.encrypt_mode, publickey);
        incipher.init(cipher.encrypt_mode, privatekeyentry.getcertificate().getpublickey());

        bytearrayoutputstream outputstream = new bytearrayoutputstream();
        cipheroutputstream cipheroutputstream = new cipheroutputstream(
            outputstream, incipher);
        cipheroutputstream.write(needencryptword.getbytes("utf-8"));
        cipheroutputstream.close();

        vals = outputstream.tobytearray();
      } catch (exception e) {
        e.printstacktrace();
      }
      return base64.encodetostring(vals, base64.default);
    }
    return "";
  }

解密:

public string decryptstring(string needdecryptword, string alias) {
    if(!"".equals(alias)&&!"".equals(needdecryptword)){
      if (build.version.sdk_int >= build.version_codes.jelly_bean_mr2) {
        initkeystore(alias);
      }
      string decryptstr="";
      try {
        keystore.privatekeyentry privatekeyentry = (keystore.privatekeyentry)keystore.getentry(alias, null);
//      rsaprivatekey privatekey = (rsaprivatekey) privatekeyentry.getprivatekey();

//      cipher output = cipher.getinstance("rsa/ecb/pkcs1padding", "androidopenssl");
        cipher output = cipher.getinstance("rsa/ecb/pkcs1padding");
//      output.init(cipher.decrypt_mode, privatekey);
        output.init(cipher.decrypt_mode, privatekeyentry.getprivatekey());
        cipherinputstream cipherinputstream = new cipherinputstream(
            new bytearrayinputstream(base64.decode(needdecryptword, base64.default)), output);
        arraylist<byte> values = new arraylist<>();
        int nextbyte;
        while ((nextbyte = cipherinputstream.read()) != -1) {
          values.add((byte)nextbyte);
        }

        byte[] bytes = new byte[values.size()];
        for(int i = 0; i < bytes.length; i++) {
          bytes[i] = values.get(i).bytevalue();
        }

        decryptstr = new string(bytes, 0, bytes.length, "utf-8");
      } catch (exception e) {
        e.printstacktrace();
      }
      return decryptstr;
    }
    return "";
  }

,我已经将加密解密封装进了工具类,并对android 7.0的兼容也处理了

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网