Facebook 开源数据加密库-Conceal

一.什么是Concel

Conceal是 Facebook 推出的一个用来对数据进行快速加密和认证的开发包,应用可以使用它来加密数据和大文件存储。Conceal是一套用于Android上的文件加密和鉴权的Java API,它使用OpenSSL算法的子集以及一些预先定义的选项,以便让库保持在较小的体积——目前仅有85KB大小。对于比较古老的Android设备——从Froyo到JellyBean——据Facebook表示,该库在这些设备上的性能要优于Android提供的原生支持。Conceal 和其他加密软件不同的是它提供了Smorgasbord 加密算法和选项,这不是一个一般意义上的数据加密包,只是提供一些有用的方法。

二.性能比较

Facebook 开源数据加密库-Conceal_第1张图片

上图中的基准测试,展示了在Galaxy Y终端上,对原生Android算法(ES-CTR-HMAC-SHA1)、Bouncycastle((AES-GCM)和Concea进行对比的结果l。

Google在KitKat中引入了对OpenSSL的支持,但是其中使用的默认密码流则“表现差强人意”——Facebook看来,“当使用我们的密码流(参阅BetterCipherInputStream.java文件)来替换它时,将使得默认实现能够与Conceal相媲美。”

三.简单使用

引用compile 'com.facebook.conceal:conceal:1.1.2'

'

 

// 加密    byte[] cipherText = mCrypto.encrypt(plainText, mEntity);    
   // 解密    byte[] plainText = mCrypto.decrypt(cipherText, mEntity);
   //使用秘钥链和原生库的默认实现,来创建一个新的加密对象
    Crypto crypto = new Crypto(
            new SharedPrefsBackedKeyChain(context),
            new SystemNativeCryptoLibrary());

  //检查加密功能是否可用
  //如果Android没有正确载入库,则此步骤可能失败
    if (!crypto.isAvailable()) {
        return;
    }

    OutputStream fileStream = new BufferedOutputStream(
            new FileOutputStream(file));

    //创建输出流,当数据写入流的时候进行加密,并将加密后的数据输出到文件
    OutputStream outputStream = crypto.getCipherOutputStream(
            fileStream,
            entity);

//将纯文本写入其中
    outputStream.write(plainText);
    outputStream.close();

相关问题

能不能将密文直接写入SharedPreferences中呢? 答案是可以的,但是不能简单的实用API提供的加密解密方法,那样是不行的。(以 Hello Word!为例)思路是这样的:由于加密、加密结果、解密三个操作参数都是byte,而SharedPreferences接受的参数是String类型,因此我们需要进行转换,newString(bytes, "utf-8") 和 string.getBytes("utf-8") , 当你这么做的时候,你会发现解密死活不成功。原因很简单,一个utf-8编码汉字是2bytes,如果我们的加密结果不足2byte,我们强转时不足部分就会被补齐,当再转换回来的时候就和原来的不一样了。解决办法:用Base64对byte数组进行编码,具体怎么做可以参考Conceal源码中的SharedPrefsBackedKeyChain。

/**
 * Visible for testing.
 */
/* package */
String encodeForPrefs(byte[]key) {
  if (key==null) {
    return null;
  }
  return Base64.encodeToString(key, Base64.DEFAULT);
}

 

异常

java.lang.NoSuchFieldError:no field with name='mCtxPtr' signature='J' in classLcom/facebook/crypto/cipher/NativeGC

 

This happensbecause native code needs to refer to Java fields/methods. For doing so it usestypical JNI functions which receive the name and signature. At the same timetools like proguard trim off or rename class members in order to get smallerexecutables. Normally this process is run on release versions. When native coderequest the member, it's not present anymore.

To avoid thiskind of problems exceptions can be defined. You will need to configure proguardwith the rules defined inproguard_annotations.pro. You can use the file as is, or you can include its content in your ownproguard configuration file.

这是因为本地代码需要引用java字段/方法。因此它使用典型的JNI函数接收签名。同时工具像ProGuard的修剪或重命名类成员为了获得小的可执行文件。通常这个过程是在发布版本上运行的。当本地代码请求成员时,它不存在了。

为了避免这种问题的异常可以被定义。你需要在proguard_annotations.pro定义的规则配置ProGuard。你可以使用文件,也可以包含在你自己的混淆器配置文件内容。

# Keep our interfaces so they can be used by otherProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interfacecom.facebook.crypto.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interfacecom.facebook.crypto.proguard.annotations.KeepGettersAndSetters

# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.crypto.proguard.annotations.DoNotStripclass *
-keepclassmembers class * {
   @com.facebook.crypto.proguard.annotations.DoNotStrip *;
}

-keepclassmembers @com.facebook.crypto.proguard.annotations.KeepGettersAndSettersclass * {
  void set*(***);
  *** get*();
}

 

你可能感兴趣的:(Android应用开发)