为了账号安全,请及时绑定邮箱和手机立即绑定

使用谷歌叮当库解密密钥时出现标签不匹配错误

使用谷歌叮当库解密密钥时出现标签不匹配错误

慕斯王 2022-09-28 15:38:51
我是密码学的新手。我正在研究一个poc来加密和解密字符串。当我解密加密的字符串时,它有时会起作用,但其他时候会引发Tag不匹配错误。我错过了什么吗?这是我的代码:EncryptionServiceImpl.javapublic 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.javapublic class EncryptionServiceImplTest {    @Test    public void encrypt() throws IOException, GeneralSecurityException {        EncryptionServiceImpl encryptionService = new EncryptionServiceImpl();        String encryptedText = encryptionService.encrypt("Hello World");        assertThat(encryptedText, Matchers.notNullValue());    }异常:信息:密文前缀与密钥匹配,但无法解密:javax.crypto.AEAD标记异常:标记不匹配!com.encryption.api.service.EncryptionService测试>解密失败
查看完整描述

3 回答

?
婷婷同学_

TA贡献1844条经验 获得超8个赞

如果加密消息的字节序列存储在字符串中,则必须使用适当的编码。适当意味着编码必须允许序列中的所有字节或字节组合。如果不是这种情况,则字节序列中的值会自动更改,并且在存储期间不会被注意到。如果在解密期间从字符串重建字节数组,则原始字节数组和重建的字节数组会有所不同,并且解密将失败。这里对此进行了很好的解释。

由于 AES-GCM 为每个加密生成一个新的初始化向量,因此即使使用相同的明文,每个加密的加密消息也是不同的。

两者都导致这样一个事实,即在您的示例中,加密有时有效,有时无效:每当字节序列与您正在使用的编码兼容时,解密就会起作用,否则就不起作用。

如果你想独立于编码,只需使用字节数组本身,即-method返回字节数组而不是字符串,类似地,字节数组传递给-method而不是字符串。encryptdecrypt


查看完整回答
反对 回复 2022-09-28
?
www说

TA贡献1775条经验 获得超8个赞

我修改了代码,但我仍然看到解密有时会因相同的请求而失败。


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;

}

}


查看完整回答
反对 回复 2022-09-28
?
富国沪深

TA贡献1790条经验 获得超9个赞

当我在本地机器中运行时,我也没有得到代码中的错误。但是当我在云(谷歌云)中部署时,我开始看到错误。


这是我的朱尼特代码:


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

}

}



查看完整回答
反对 回复 2022-09-28
  • 3 回答
  • 0 关注
  • 94 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信