异常解决 javax.crypto.AEADBadTagException: Tag mismatch!

简介: 异常解决 javax.crypto.AEADBadTagException: Tag mismatch!


自己编写的java web项目每次重启后登录都会报下面错误:

javax.crypto.AEADBadTagException: Tag mismatch!

image.gif

有道翻译的了一下,意思是加密异常,标签不匹配。

错误堆栈:

org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with cipher instance [javax.crypto.Cipher@17359b49].
  at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:462)
  at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:445)
  at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:390)
  at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:382)
  at org.apache.shiro.mgt.AbstractRememberMeManager.decrypt(AbstractRememberMeManager.java:482)
  at org.apache.shiro.mgt.AbstractRememberMeManager.convertBytesToPrincipals(AbstractRememberMeManager.java:419)
  at org.apache.shiro.mgt.AbstractRememberMeManager.getRememberedPrincipals(AbstractRememberMeManager.java:386)
  at org.apache.shiro.mgt.DefaultSecurityManager.getRememberedIdentity(DefaultSecurityManager.java:613)
  at org.apache.shiro.mgt.DefaultSecurityManager.resolvePrincipals(DefaultSecurityManager.java:501)
  at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:347)
  at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:845)
  at org.apache.shiro.web.subject.WebSubject$Builder.buildWebSubject(WebSubject.java:148)
  at org.apache.shiro.web.servlet.AbstractShiroFilter.createSubject(AbstractShiroFilter.java:292)
  at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:359)
  at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
  at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
  at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
  at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  at java.lang.Thread.run(Thread.java:748)
Caused by: javax.crypto.AEADBadTagException: Tag mismatch!
  at com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:620)
  at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1116)
  at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1053)
  at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
  at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
  at javax.crypto.Cipher.doFinal(Cipher.java:2168)
  at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:459)
  ... 44 common frames omitted

image.gif

问题产生的缘由是rememberMe的cookie在第二次打开页面后shiro没法解密,通过查询资料以及代码跟踪发现了缘由所在。

先附上rememberMe管理器配置

/**
     * cookie管理对象;记住我功能
     *
     * @return
     */
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        return cookieRememberMeManager;
    }

image.gif

导致原因:

rememberMeManager继承了AbstractRememberMeManager,然而AbstractRememberMeManager的构造方法中每次都会重新生成对称加密密钥,意味着每次重启程序都会重新生成一对加解密密钥。

  这就会导致了,第一次启动程序shiro使用A密钥加密了cookie,第二次启动程序shiro重新生成了密钥B,当用户访问页面时,shiro会用密钥B去解密上一次用密钥A加密的cookie,导致解密失败,导致报错,所以这不影响用户登录操作(rememberMe失效罢了),所以这种异常只会在程序重启(shiro清除session)第一次打开页面的时候出现。

解决办法:

手动设置对称加密秘钥。修改后rememberMe管理器配置

/**
     * cookie管理对象;记住我功能
     *
     * @return
     */
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        //手动设置对称加密秘钥,防止重启系统后系统生成新的随机秘钥,防止导致客户端cookie无效
        cookieRememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j3Y+R1aSn5BOlAA=="));
        return cookieRememberMeManager;
    }

image.gif


相关文章
|
JSON 数据格式
SpringMVC-接收请求中的json数据及日期类型参数传递
SpringMVC-接收请求中的json数据及日期类型参数传递
709 0
|
5月前
|
人工智能 运维 数据安全/隐私保护
保姆级教程:OpenClaw(Clawdbot)本地部署+阿里云1键部署及iMessage集成指南
2026年,OpenClaw(原Clawdbot)已成为轻量化、高可用的开源AI智能体框架,支持本地私有化部署与阿里云云端稳定运行,可无缝对接iMessage实现苹果生态全设备AI交互。本文从零开始,提供本地部署、阿里云一键部署、iMessage消息通道集成的完整流程,附带可直接执行的代码命令、权限配置、端口放行、服务自启与问题排查方案,全程无多余平台信息,新手也能一次性跑通。
3511 2
|
11月前
|
Java 测试技术
Java浮点类型详解:使用与区别
Java中的浮点类型主要包括float和double,它们在内存占用、精度范围和使用场景上有显著差异。float占用4字节,提供约6-7位有效数字;double占用8字节,提供约15-16位有效数字。float适合内存敏感或精度要求不高的场景,而double精度更高,是Java默认的浮点类型,推荐在大多数情况下使用。两者都存在精度限制,不能用于需要精确计算的金融领域。比较浮点数时应使用误差范围或BigDecimal类。科学计算和工程计算通常使用double,而金融计算应使用BigDecimal。
3689 102
|
NoSQL 安全 Java
深入理解 RedisConnectionFactory:Spring Data Redis 的核心组件
在 Spring Data Redis 中,`RedisConnectionFactory` 是核心组件,负责创建和管理与 Redis 的连接。它支持单机、集群及哨兵等多种模式,为上层组件(如 `RedisTemplate`)提供连接抽象。Spring 提供了 Lettuce 和 Jedis 两种主要实现,其中 Lettuce 因其线程安全和高性能特性被广泛推荐。通过手动配置或 Spring Boot 自动化配置,开发者可轻松集成 Redis,提升应用性能与扩展性。本文深入解析其作用、实现方式及常见问题解决方法,助你高效使用 Redis。
1428 4
针对报错:java.lang.Integer cannot be cast to java.lang.Long..的解决办法
针对报错:java.lang.Integer cannot be cast to java.lang.Long..的解决办法
5142 0
针对报错:java.lang.Integer cannot be cast to java.lang.Long..的解决办法
|
Java 数据库连接 微服务
若依微服务的Mybatis-plus集成过程:一份详细的入门教程。
以上就是Spring Boot项目中集成MyBatis Plus的详细步骤。集成成功后,你就可以使用Mybatis-plus提供的强大功能,让你的增删改查操作更为简单。以上步骤简单易懂,非常适合初学者使用。希望对您有所帮助。
1113 20
|
缓存 安全 Java
Shiro简介及SpringBoot集成Shiro(狂神说视频简易版)
Shiro简介及SpringBoot集成Shiro(狂神说视频简易版)
967 7
|
Java API Spring
spring boot中Excel文件下载踩坑大全
spring boot中Excel文件下载踩坑大全
2911 2
spring boot中Excel文件下载踩坑大全
|
存储 前端开发 Java
SpringBoot整合Flowable【05】- 使用流程变量传递业务数据
本文介绍了如何使用Flowable的流程变量来管理绩效流程中的自定义数据。首先回顾了之前的简单绩效流程,指出现有流程缺乏分数输入和保存步骤。接着详细解释了流程变量的定义、分类(运行时变量和历史变量)及类型。通过具体代码示例展示了如何在绩效流程中插入全局和局部流程变量,实现各节点打分并维护分数的功能。最后总结了流程变量的使用场景及其在实际业务中的灵活性,并承诺将持续更新Flowable系列文章,帮助读者更好地理解和应用Flowable。 简要来说,本文通过实例讲解了如何利用Flowable的流程变量功能优化绩效评估流程,确保每个环节都能记录和更新分数,同时提供了全局和局部变量的对比和使用方法。
1458 0
SpringBoot整合Flowable【05】- 使用流程变量传递业务数据
|
存储 安全 Java
shiro学习二:shiro的加密认证详解,加盐与不加盐两个版本。
这篇文章详细介绍了Apache Shiro安全框架中密码的加密认证机制,包括不加盐和加盐两种加密方式的实现和测试。
1031 0