如何使用Tink轻松加密和解密String?

问题描述 投票:2回答:2

到目前为止,我正在使用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加密和解密字符串?

java encryption jasypt keyczar tink
2个回答
3
投票

你的StrongTextEncryptor-example-code中的jasypt类使用PBEWithMD5AndTripleDES算法。该算法使用对称密钥块密码Triple DES,并使用MD5哈希函数从密码导出密钥。后者称为基于密码的加密,这在Tink中不受支持(至少在08/2018),请参阅How to create symmetric encryption key with Google Tink?。因此,在Tink中不可能通过密码进行加密,到目前为止在jasypt代码中使用的概念无法实现。如果要在任何情况下使用基于密码的加密,这是Tink的交易破坏者。

另一种方法是直接使用密钥。 TinkAesGcmJce级,它使用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开发人员自己不推荐这种方法,因为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方法生成一个新密钥。但是,创建不是基于密码或字节序列,因此,为加密生成的密钥不能轻易地重建以进行解密。因此,用于加密的密钥必须保存到存储系统,例如,存储系统。文件系统,因此可以在以后用于解密。 Tink允许存储明文密钥(当然不建议这样做)。更安全的方法是使用存储在远程密钥管理系统中的主密钥对密钥进行加密(这更详细地解释了TinkJAVA-HOWTO,存储密钥集和加载现有密钥集的部分)。

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


0
投票

免责声明:Tink的首席开发人员。

(我没有足够的声誉发表评论,所以我会添加答案)

Peter,如果您正在使用Android应用程序,可以查看AndroidKeysetManager [2]。你可以复制一个你好世界的例子[3]。

通常,无论何时您想加密某些内容,您应该问自己的第一个问题是您要存储密钥的位置。将密钥存储在存储加密数据的相同位置(并使用相同的ACL)并不会产生很多意义。密钥应存储在不同的位置(或使用不同的ACL)。

Tink的密钥管理API有点复杂,因为我们希望引导用户将密钥存储在正确的位置[1]。

[1] https://github.com/google/tink/blob/master/docs/JAVA-HOWTO.md#storing-keysets

[2] http://google.github.io/tink/javadoc/tink-android/1.2.2/com/google/crypto/tink/integration/android/AndroidKeysetManager.html

[3] https://github.com/google/tink/blob/master/examples/helloworld/android/app/src/main/java/com/helloworld/TinkApplication.java

© www.soinside.com 2019 - 2024. All rights reserved.