Unable to execute 'doFinal' with cipher instance


  今天項目啟動后登錄項目,突然爆出Unable to execute 'doFinal' with cipher instance錯誤。清除cookie登錄測試,又不報錯了,以前也見過類似問題,因為不影響使用,於是就忽略了,今天又遇到了,特研究一下。

  原來,項目中使用Shiro作為認證權限控制框架,問題就出在RememberMe功能的配置上。問題產生的原因是rememberMe的cookie在第二次打開頁面后shiro無法解密。

項目配置

 1 @Bean  2     public RememberMeManager rememberMeManager() {  3         CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();  4         //注入自定義cookie(主要是設置壽命, 默認的一年太長)
 5         SimpleCookie simpleCookie = new SimpleCookie("rememberMe");  6         simpleCookie.setHttpOnly(true);  7         //設置RememberMe的cookie有效期為7天
 8         simpleCookie.setMaxAge(604800);  9  rememberMeManager.setCookie(simpleCookie);10         return rememberMeManager; 11     }

框架源碼

 1 public AbstractRememberMeManager() {  2     this.serializer = new DefaultSerializer<PrincipalCollection>();  3     AesCipherService cipherService = new AesCipherService();  4     this.cipherService = cipherService;  5  setCipherKey(cipherService.generateNewKey().getEncoded());  6 }  7 
 8 public void setCipherKey(byte[] cipherKey) {  9     //Since this method should only be used in symmetric ciphers 10     //(where the enc and dec keys are the same), set it on both:
11  setEncryptionCipherKey(cipherKey); 12  setDecryptionCipherKey(cipherKey); 13 }

  rememberMeManager繼承了AbstractRememberMeManager,然而AbstractRememberMeManager的構造方法中每次都會重新生成對稱加密密鑰,意味着每次重啟程序都會重新生成一對加解密密鑰。

  這就會導致了,第一次啟動程序shiro使用A密鑰加密了cookie,第二次啟動程序shiro重新生成了密鑰B,當用戶訪問頁面時,shiro會用密鑰B去解密上一次用密鑰A加密的cookie,導致解密失敗,導致報錯,所以這不影響用戶登錄操作(rememberMe失效罷了),所以這種異常只會在程序重啟(shiro清除session)第一次打開頁面的時候出現。

  解決辦法:手動設置對稱加密秘鑰。

1 //手動設置對稱加密秘鑰,防止重啟系統后系統生成新的隨機秘鑰,防止導致客戶端cookie無效
2         rememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j3Y+R1aSn5BOlAA=="));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM