Ошибка несоответствия тегов при расшифровке ключа с помощью библиотеки Google Tink - PullRequest
0 голосов
/ 09 апреля 2019

Я новичок в криптографии.Я работаю над документом, чтобы зашифровать и расшифровать строку.Когда я расшифровываю зашифрованную строку, она иногда срабатывает, но иногда выдает ошибку несоответствия тега.Я что-то пропустил?

Вот мой код:

EncryptionServiceImpl.java

public class EncryptionServiceImpl {
    private static final Logger log = LoggerFactory.getLogger("EncryptionServiceImpl");

    private final KeysetHandle keysetHandle;
    private final Aead aead;

    public EncryptionServiceImpl() throws GeneralSecurityException {
        AeadConfig.register();
        this.keysetHandle = KeysetHandle.generateNew(AeadKeyTemplates.AES128_GCM);
        aead = AeadFactory.getPrimitive(keysetHandle);
    }

    public String encrypt(String text) throws GeneralSecurityException {

        log.info(String.format("Encrypting %s", text));
        byte[] plainText = text.getBytes();
        byte[] additionalData = "masterkey".getBytes();
        byte[] cipherText = aead.encrypt(plainText,additionalData);

        String output = new String(cipherText);

        log.info(String.format("The encrypted text: %s", output));
        return output;
    }

    public String decrypt(String text) throws GeneralSecurityException {

        log.info(String.format("Decrypting %s", text));

        byte[] cipherText = text.getBytes();
        byte[] additionalData = "masterkey".getBytes();
        byte[] decipheredData = aead.decrypt(cipherText,additionalData);

        String output = new String(decipheredData);

        log.info(String.format("The decrypted text: %s", output));
        return output;
    }

}

EncryptionServiceImplTest.java

public class EncryptionServiceImplTest {

    @Test
    public void encrypt() throws IOException, GeneralSecurityException {
        EncryptionServiceImpl encryptionService = new EncryptionServiceImpl();
        String encryptedText = encryptionService.encrypt("Hello World");
        assertThat(encryptedText, Matchers.notNullValue());
    }

    @Test
    public void decrypt() throws IOException, GeneralSecurityException {
        EncryptionServiceImpl encryptionService = new EncryptionServiceImpl();

        String encryptedText = encryptionService.encrypt("Hello World");
        String decrypedText = encryptionService.decrypt(encryptedText);

        assertThat(decrypedText, Matchers.is("Hello World"));
    }
}

Исключение: INFO: префикс зашифрованного текста соответствует ключу, но не может расшифровать: javax.crypto.AEADBadTagException: Tag mismatch!com.encryption.api.service.EncryptionServiceImplTest> decrypt FAILED

java.security.GeneralSecurityException at EncryptionServiceImplTest.java:25

расшифровка не удалась java.security.GeneralSecurityException: расшифровка не удалась в com.google.crypto.tink.aead.AeadFactory $ 1.java: 109) в com.encryption.api.service.EncryptionServiceImpl.decrypt (EncryptionServiceImpl.java:53) в com.encryption.api.service.EncryptionServiceImplTest.decrypt (EncryptionServiceImplTlect.ho.Imp.Ign.Ign.jp.Собственный метод) в sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.vo.etg.reg ()в org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall (FrameworkMethod.java:50) в org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:12) в org.junit.del.FrameworkMethod.invokeExplosively (FrameworkMethod.java:47) в org.junit.internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:17) в org.junit.runners.ParentRunner.runLeaf (ParentRunner.java:325) в org.junit.runners.BlockJUnit4ClassRunner.jun4 (ru).junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:57) в org.junit.runners.ParentRunner $ 3.run (ParentRunner.java:290) в org.junit.runners.ParentRunjj) в org.junit.runners.ParentRunner.runChildren (ParentRunner.java:288) в org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:58) в org.junit.runners.ParentRunner $ 2.evaluate (Java: 268) в org.junit.runners.ParentRunner.run (ParentRunner.java:363) в org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass (JUnitTestClassExecudle.g:.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute (JUnitTestClassExecuter.java:57) в org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass (JUnitTestClassProcessor.java:66) по адресу org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass (SuiteTestClassProcessor.java:51) по адресу sun.reflect.NativeMethodAccessorImpl.intotive.Ignative.Ignative.Noke0invoke (NativeMethodAccessorImpl.java:62) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.lang.reflect.Method.invoke (Method.java:498) в org.Файлgradle.internal.dispatch.ProxyDispatchAdapter $ DispatchingInvocationHandler.invoke (ProxyDispatchAdapter.java:93) по адресу com.sun.proxy.processTestClass (TestWorker.java:108) в sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) в sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) в sun.reflect.DelegatingMethodAccessorImpl.invod.hoho.javaMethod.java:498) в org.gradle.internal.dispatch.ReflectionDispatch.dispatch (ReflectionDispatch.java:35)в org.gradle.internal.dispatch.ReflectionDispatch.dispatch (ReflectionDispatch.java:24) в org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection $ DispatchWrapper.dispatch (MessageHubBackedObjectConnection.java:146) в org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection $ DispatchWrapper.dispatch (MessageHubBackedObjectConnection.java:128) в org.gradle.internal.remote.internal.hub.MessageHub $ Handler.run (MessageHub.java:404) в org.gradle.internal.concurrent.ExecutorPolicy $ CatchAndRecordFailures.onExecute (ExecutorPolicy.java:63) в org.gradle.internal.concurrent.ManagedExecutorImpl $ 1.run (ManagedExecutorImpl.java:46) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1149) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:624) в org.gradle.internal.concurrent.ThreadFactoryImpl $ ManagedThreadRunnable.run (ThreadFactoryImpl.java:55) at java.lang.Thread.run (Thread.java:748)

1 тест завершен, 1 не пройден

Ответы [ 3 ]

0 голосов
/ 12 апреля 2019

Я пересмотрел код, но все равно вижу, что расшифровка иногда не выполняется для одного и того же запроса.

public class Utils {
private static final Logger log = LoggerFactory.getLogger(Utils.class);
private Aead aead;
private static Utils utils;

private Utils() {
    try {
        AeadConfig.register();
        KeysetHandle keysetHandle = KeysetHandle.generateNew(AeadKeyTemplates.AES128_GCM);
        aead = AeadFactory.getPrimitive(keysetHandle);
    } catch (GeneralSecurityException e) {
        log.error(String.format("Error occured: %s",e.getMessage())).log();
    }
}

public static Utils getInstance() {
    if(null == utils) {
        utils = new Utils();
    }

    return utils;
}

public String encrypt(String text) throws GeneralSecurityException, UnsupportedEncodingException {
    byte[] plainText = text.getBytes("ISO-8859-1");
    byte[] additionalData = null;
    byte[] cipherText = aead.encrypt(plainText,additionalData);

    String output = Base64.getEncoder().encodeToString(cipherText);
    return output;
}

public String decrypt(String text) throws GeneralSecurityException, UnsupportedEncodingException {
    byte[] cipherText = Base64.getDecoder().decode(text);
    byte[] additionalData = null;
    byte[] decipheredData = aead.decrypt(cipherText,additionalData);

    String output = new String(decipheredData,"ISO-8859-1");
    return output;
}

}

0 голосов
/ 12 апреля 2019

Я тоже не получил ошибку в коде, когда я работал на локальной машине.Но когда я развернул в облаке (Google Cloud), я увидел ошибку.

Вот мой код Junit:

public class UtilsTest {

private static final Utils cryptographicUtils = Utils.getInstance();

@Test
public void encrypt() throws IOException, GeneralSecurityException {
    String encryptedText = cryptographicUtils.encrypt("Hello World");
    assertThat(encryptedText, Matchers.notNullValue());
}

@Test
public void decrypt() throws IOException, GeneralSecurityException {
    String encryptedText = cryptographicUtils.encrypt("Hello 123456");
    String decrypedText = cryptographicUtils.decrypt(encryptedText);

    assertThat(decrypedText, Matchers.is("Hello 123456"));
}

}

0 голосов
/ 09 апреля 2019

Если последовательность байтов зашифрованного сообщения хранится в строке, должна использоваться соответствующая кодировка.Соответствующее означает, что кодирование должно разрешать все байты или байтовые комбинации в последовательности.Если это не так, значения в последовательности байтов изменяются автоматически и остаются незамеченными во время хранения.Если байтовый массив затем восстанавливается из строки во время дешифрования, исходные и восстановленные байтовые массивы различаются, и дешифрование завершается неудачно.Это очень хорошо объяснено здесь .

Поскольку AES-GCM генерирует новый вектор инициализации для каждого шифрования, зашифрованное сообщение отличается для каждого шифрования, даже с идентичнымпростой текст.

Оба приводят к тому, что в вашем примере шифрование иногда работает, а иногда нет: всякий раз, когда последовательность байтов совместима с используемой кодировкой, дешифрование работает, в противном случае - нет.

Если вы хотите быть независимым от кодировки, просто используйте сам байтовый массив, т.е. encrypt -метод возвращает байтовый массив вместо строки и, аналогично, вместо строки байтовый массив передается в decrypt -метод.

...