com.google.gson.Gson类失败了javax.crypto.SecretKey?

时间:2017-06-03 15:53:15

标签: java android gson javax.crypto

我在某些加密操作期间存储了SecretKey,我需要稍后使用。存储时我将其转换为字符串:

String keyAsString = new Gson().toJson(key);

但是,在重新检索时,以下代码失败了:

   SecretKey secKey =  new Gson().fromJson(keyAsString, SecretKey.class);

即使使用Verbose消息传递过滤器,我也没有在LogCat中获得任何单一提示。我试着在try catch中使用调试点来包围代码(希望我可以在调试时获得任何异常跟踪):

try {
SecretKey secKey =  new Gson().fromJson(keyAsString, SecretKey.class); // One debug point here
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e)); // And one debug point here
}

但调试器不会在两个调试点停止,设备应用程序上的立即崩溃并显示不幸的应用程序崩溃消息。

SecretKey保存时的json结构如下:

{
  "algorithm": "AES",
  "key": [
   integer1, integre2, ....
  ]
}

注意:整数1,整数2 ...是出于安全目的的实际数字我没有发布原始结果数字。

可能出了什么问题?是不允许存储SecretKey

更新

将SecretKey转换为json字符串&反之亦然使用Gson是一个糟糕的想法,由jonathanrz在下面回答我跟着他的回答&在android中编写了两个实用函数,将SecretKey转换为String&反之亦然功能如下:

public static String secretKeyToString(SecretKey key) {
  return Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
}

public static SecretKey encodedStringToSecretKey(String encodedKey) {
  byte[] decodedKey = Base64.decode(encodedKey, Base64.DEFAULT);
  return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
}

1 个答案:

答案 0 :(得分:1)

您应该将密钥解析为字符串,然后使用SecretKeyFactory.translateKey来解析密钥。

更新:在您编辑问题后,我看到您的输出不仅仅是一个字符串。因此,您需要创建一个代表您的json的类,使用它解析响应并使用translateKey构造每个键。如果类具有与json中的键具有相同名称和相同类型的属性,则GSON只能解析json,而SecretKey的情况则不然。

UPDATE2:translateKey无法从String创建密钥。从String创建键的选项是:Converting Secret Key into a String and Vice Versa