Как легко зашифровать и расшифровать строку с помощью Tink? - PullRequest
2 голосов
/ 08 марта 2019

До сих пор я использовал 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.

Я не могу найти в readme Tink repo простой способзашифровать и расшифровать строку, просто можно найти более сложные операции, которые на самом деле я не могу понять, потому что мои знания в области шифрования совершенно пусты.Из-за этого я использовал очень простую библиотеку, такую ​​как jasypt.

Это репо Tink: https://github.com/Google/tink

Есть ли простой способ, похожий на мой jasyptкод, чтобы зашифровать и расшифровать строку с Tink?

Ответы [ 2 ]

3 голосов
/ 10 марта 2019

Класс StrongTextEncryptor в вашем коде jasypt -example использует алгоритм PBEWithMD5AndTripleDES.Этот алгоритм использует блочный шифр с симметричным ключом Triple DES и получает ключ из пароля, используя хэш-функцию MD5.Последнее называется шифрование на основе пароля , и это не поддерживается в Tink (по крайней мере, по состоянию на 08/2018), см. Как создать симметричный ключ шифрованияс Google Tink? .Таким образом, в Tink невозможно зашифровать с помощью пароля, и концепция, использованная до сих пор в jasypt -коде, не может быть реализована.Если шифрование на основе пароля должно использоваться в любом случае, которое является нарушителем условий для Tink.

Другой подход заключается в прямом использовании ключа.Tink имеет класс AesGcmJce, который использует 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 -пакету , который может измениться в любое время без дальнейшего уведомления , (см. также здесь , раздел Важные предупреждения ).Следовательно, этот подход также не оптимален.

Ну, а как 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 позволяет хранить ключи открытого текста (что, конечно, не рекомендуется).Более безопасный подход - это шифрование ключей с помощью мастер-ключей, хранящихся в системе удаленного управления ключами (это более подробно объясняется Tink JAVA-HOWTO , разделы Хранение ключей и Загрузка существующих наборов ключей ). Концепция управления ключами

Tink (с целью избежать случайной утечки чувствительного материала ключа) также делает ее несколько громоздкой (это может измениться позжеверсии).Вот почему я сказал в своем комментарии, что я не уверен, подходит ли Tink вашим идеям относительно простоты.

0 голосов
/ 19 марта 2019

Отказ от ответственности: ведущий разработчик Тинка.

(у меня недостаточно репутации, чтобы комментировать, поэтому я добавлю ответ)

Питер, если ты работаешь на AndroidПриложение, вы можете проверить AndroidKeysetManager [2].Есть пример hello world [3], из которого вы можете скопировать.

В общем, когда вы хотите что-то зашифровать, первый вопрос, который вы должны задать себе, - это место хранения ключей.Не имеет смысла хранить ключи в том же месте (и с тем же ACL), где вы храните свои зашифрованные данные.Ключи должны храниться в другом месте (или с другим ACL).

API управления ключами Tink немного сложнее, потому что мы хотим, чтобы пользователи хранили ключи в нужном месте [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

...