java - 如何使用 Tink 轻松加密和解密字符串?
问题描述
到目前为止,我一直在使用 jasypt 加密字符串,然后在应用程序关闭时将其存储在磁盘上,然后在打开应用程序以在从磁盘检索字符串后解密字符串时。
使用 jasypt 非常简单,代码如下:
private static final String JASYPT_PWD = "mypassword";
public static String encryptString(String string) {
StrongTextEncryptor textEncryptor = new StrongTextEncryptor();
textEncryptor.setPassword(JASYPT_PWD);
return textEncryptor.encrypt(string);
}
public static String decryptString(String string) {
StrongTextEncryptor textEncryptor = new StrongTextEncryptor();
textEncryptor.setPassword(JASYPT_PWD);
return textEncryptor.decrypt(string);
}
它工作得很好,但是现在,jasypt 已被弃用,我正在尝试迁移到Google Tink库,问题是 Google Tink 似乎要复杂得多,因为只需像使用 jasypt 一样轻松地加密和解密字符串。
我在 Tink repo 自述文件中找不到加密和解密字符串的简单方法,只能找到更复杂的操作,实际上我无法理解,因为我在加密方面的知识完全是空的。因此,我使用了一个非常简单的库,比如 jasypt。
这是 Tink 仓库:https ://github.com/Google/tink
有没有一种简单的方法,类似于我的 jasypt 代码,用 Tink 加密和解密字符串?
解决方案
注意:帖子指的是Tink 版本 1.2.2。发布的代码与更高版本部分不兼容。
-example-code中的StrongTextEncryptor
-class使用-algorithm。该算法使用对称密钥分组密码,并使用散列函数从密码中导出密钥。后者称为基于密码的加密,并且不支持(至少在 08/2018 时),请参阅如何使用 Google Tink 创建对称加密密钥?. 因此,不可能通过密码进行加密,并且迄今为止在-code中使用的概念无法实现。如果要在任何情况下使用基于密码的加密,这对.jasypt
PBEWithMD5AndTripleDES
Triple DES
MD5
Tink
Tink
jasypt
Tink
另一种方法是直接使用密钥。Tink
具有用于加密的AesGcmJce
-class 。AES-GCM
此处密钥的长度必须为 128 位或 256 位:
String plainText = "This is a plain text which needs to be encrypted!";
String aad = "These are additional authenticated data (optional)";
String key = "ThisIsThe32ByteKeyForEncryption!"; // 256 bit
// Encryption
AesGcmJce agjEncryption = new AesGcmJce(key.getBytes());
byte[] encrypted = agjEncryption.encrypt(plainText.getBytes(), aad.getBytes());
// Decryption
AesGcmJce agjDecryption = new AesGcmJce(key.getBytes());
byte[] decrypted = agjDecryption.decrypt(encrypted, aad.getBytes());
使用简单,而且使用的密码 ( AES-GCM
) 是安全的。但是,Tink
-developers 自己不推荐这种方法,因为AesGcmJce
-class 属于com.google.crypto.tink.subtle
-package可能随时更改,恕不另行通知,(另请参见此处,重要警告部分)。因此,这种方法也不是最优的。
那么,Tink
通常如何使用对称加密呢?这显示在以下片段中:
String plainText = "This is a plain text which needs to be encrypted!";
String aad = "These are additional authenticated data (optional)";
AeadConfig.register();
KeysetHandle keysetHandle = KeysetHandle.generateNew(AeadKeyTemplates.AES256_GCM);
Aead aead = AeadFactory.getPrimitive(keysetHandle);
// Encryption
byte[] ciphertext = aead.encrypt(plainText.getBytes(), aad.getBytes());
// Decryption
byte[] decrypted = aead.decrypt(ciphertext, aad.getBytes());
-generateNew
方法生成一个新密钥。但是,创建不是基于密码或字节序列,因此,为加密生成的密钥无法轻松重建以进行解密。因此,用于加密的密钥必须保存在存储系统中,例如文件系统,以便以后用于解密。Tink
允许存储明文密钥(当然不推荐)。一种更安全的方法是使用存储在远程密钥管理系统中的主密钥对密钥进行加密(这在JAVA-HOWTOTink
的存储密钥集和加载现有密钥集部分有更详细的解释)。
Tink
的密钥管理概念(旨在避免敏感密钥材料的意外泄漏)使其在某种程度上也很麻烦(这可能会在以后的版本中改变)。这就是为什么我在评论中说我不确定是否Tink
符合您关于简单性的想法。
推荐阅读
- javascript - 在 React 中删除和复制数组元素
- flutter - Dart (Flutter) 迭代 assets 文件夹文件内容
- arrays - 在 Swift 中检查 2 个固定大小的数组是否相等的最快方法是什么?
- algorithm - 空间复杂度总是时间复杂度的下界
- python - 我们是否使用空间滤波或频率滤波来进行模糊、边缘检测?
- mqtt - 将 gcloud 连接到 MQTT 网桥时出现问题
- r - 如何使用 dplyr r 对 grouped_tbl 中的选择列使用行手段来改变新列?
- ios - 未执行 Segue
- java - 在安装了 facebook Lite 的手机上使用 facebook 按钮登录时出错
- typescript - 具有泛型的函数在其他函数中用作参数