解密结果不一致

时间:2019-04-15 15:10:01

标签: java tink

我有两个服务实例,它们执行在云中运行的加密和解密。解密有时会失败,并显示“解密失败”错误。我猜这是因为每个实例都有自己的Aead实例。我该如何解决这个问题?

    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;
    }

 @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"));
    }

如果仅运行一个实例,我将获得一致的结果...

2 个答案:

答案 0 :(得分:0)

看起来像线程安全问题。尝试使getInstance同步。另外,保护对私人Aead aead

的访问

如果不小心,多个线程可能会改变aead的状态。

考虑一个队列来完成您的工作,或同步对与aead交互的内容的访问。

答案 1 :(得分:0)

我将不得不使用相同的密钥集进行加密和解密。我可以通过将密钥集存储在物理位置并使用它来创建Aead实例来解决此问题。进行此更改后,我的服务的所有实例都能够成功解密字符串

相关问题