java - 如何使用 Tink 轻松加密和解密字符串?

标签 java encryption jasypt keyczar 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 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 进行加密(这在 TinkJAVA-HOWTO 部分 Storing Keysets 和 < em>加载现有的键集)。

Tink 的 key 管理概念(旨在避免敏感 key Material 的意外泄漏)使其在某种程度上也很麻烦(这可能会在以后的版本中改变)。这就是为什么我在评论中说我不确定 Tink 是否符合您关于简单性的想法。

关于java - 如何使用 Tink 轻松加密和解密字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55070513/

相关文章:

java - 如何在运行时创建对象时动态关闭 JInternal Frame

java - 使用java仅相对于第一行按升序对二维数组进行排序

c# - .net MVC中key和IV的存储位置在哪里?

java - 使用Java简化加密库有哪些安全风险?

java - Jasypt 使用 Bouncy CaSTLe 的 EncryptionOperationNotPossibleException

java - 如何配置Hibernate @Type注释的属性

java - Ant :[xslt] java.lang.ClassNotFoundException:org.apache.tools.ant.taskdefs.optional.TraXLiaison

java - getCursor() 在我的 actionListener 中不起作用

security - 如何防止重放攻击

angular - 如何使用 Let's Encrypt 证书解决 Angular 7 中的 "error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt"?