天天看點

Linux下運作java AES解密失敗,報 javax.crypto.BadPaddingException: Given final block not properly padded.

AES 加密、解密源碼見另一篇部落格:https://blog.csdn.net/weixin_43276786/article/details/90288171

在windows下運作正常,對加密後的密文可以正常解密,

但是放到linux上運作,則報錯,錯誤資訊如下

Linux下運作java AES解密失敗,報 javax.crypto.BadPaddingException: Given final block not properly padded.

原因:

經過檢查之後,定位在生成KEY的方法上,即如下紅色代碼:

public static Cipher getCipher(int model) throws Exception{

            //1.擷取加密生成器

            KeyGenerator keygen=KeyGenerator.getInstance("AES");

            //2.根據ecnodeRules規則初始化密鑰生成器

            //生成一個128位的随機源,根據傳入的位元組數組

           keygen.init(128, new SecureRandom(RANDOM_KEY.getBytes()));

            //3.産生原始對稱密鑰

            SecretKey original_key=keygen.generateKey();

            //4.獲得原始對稱密鑰的位元組數組

            byte [] raw=original_key.getEncoded();

            //5.根據位元組數組生成AES密鑰

            SecretKey key=new SecretKeySpec(raw, "AES");

            //6.根據指定算法AES自成密碼器

            Cipher cipher=Cipher.getInstance("AES");

            //7.初始化密碼器,第一個參數為加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二個參數為使用的KEY

            cipher.init(model, key);

            return cipher;

    }

SecureRandom 實作完全随作業系統本身的內部狀态,除非調用方在調用 getInstance 方法,然後調用 setSeed 方法;該實作在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系統上則不同。關于SecureRandom類的詳細介紹,見 http://yangzb.iteye.com/blog/325264

解決辦法

把原來的getCipher方法中紅色改為如下的紅色部分:

public static Cipher getCipher(int model) throws Exception{

            //1.擷取加密生成器

            KeyGenerator keygen=KeyGenerator.getInstance("AES");

            //2.根據ecnodeRules規則初始化密鑰生成器

            //防止linux下 随機生成key

            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

            secureRandom.setSeed(RANDOM_KEY.getBytes());

            keygen.init(128, secureRandom);

            //3.産生原始對稱密鑰

            SecretKey original_key=keygen.generateKey();

            //4.獲得原始對稱密鑰的位元組數組

            byte [] raw=original_key.getEncoded();

            //5.根據位元組數組生成AES密鑰

            SecretKey key=new SecretKeySpec(raw, "AES");

            //6.根據指定算法AES自成密碼器

            Cipher cipher=Cipher.getInstance("AES");

            //7.初始化密碼器,第一個參數為加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二個參數為使用的KEY

            cipher.init(model, key);

            return cipher;

    }