直到现在,我一直在使用 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 readme 中找不到加密和解密字符串的简单方法,只能找到更复杂的操作,实际上我无法理解,因为我在加密方面的知识完全是空的。因此,我使用了一个非常简单的库,如 jasypt。
这是 Tink 存储库:https://github.com/Google/tink
有没有一种简单的方法,类似于我的 jasypt 代码,用 Tink 加密和解密字符串?
最佳答案
注意:该帖子指的是 Tink version 1.2.2 。发布的代码与更高版本部分不兼容。
您的 jasypt
示例代码中的 StrongTextEncryptor
类使用了 PBEWithMD5AndTripleDES
算法。该算法使用对称 key block 密码 Triple DES
并使用 MD5
散列函数从密码中导出 key 。后者称为基于密码的加密,Tink
中不支持(至少截至 08/2018),参见 How to create symmetric encryption key with Google Tink?。因此,在 Tink
中不可能通过密码进行加密,而且目前在 jasypt
中使用的概念 - 代码无法实现。如果在任何情况下都使用基于密码的加密,这对 Tink
来说是一个交易破坏者。
另一种方法是直接使用 key 。 Tink
具有 AesGcmJce
类,它使用 AES-GCM
进行加密。这里 key 的长度必须为 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
开发人员自己不推荐这种方法,因为 AesGcmJce
类属于 com.google.crypto .tink.subtle
-package which may change at any time without further notice,(另见 here,重要警告 部分)。因此,这种方法也不是最优的。
嗯,Tink
通常如何使用对称加密?这显示在以下片段 from 中:
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
方法生成一个新 key 。然而,创建不是基于密码或字节序列,因此,为加密生成的 key 不能轻易重建用于解密。因此,用于加密的 key 必须保存到存储系统中,例如文件系统,以便稍后用于解密。 Tink
允许存储明文 key (当然不推荐)。一种更安全的方法是使用存储在远程 key 管理系统中的主 key 对 key 进行加密(这在 Tink
的 JAVA-HOWTO 部分 Storing Keysets 和 < em>加载现有的键集)。
Tink
的 key 管理概念(旨在避免敏感 key Material 的意外泄漏)使其在某种程度上也很麻烦(这可能会在以后的版本中改变)。这就是为什么我在评论中说我不确定 Tink
是否符合您关于简单性的想法。
关于java - 如何使用 Tink 轻松加密和解密字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55070513/