解決Linux下AES解密失敗

來源:互聯網
上載者:User

標籤:linux   伺服器   解密   加密   發布   

        前段時間,用了個AES加密解密的方法,詳見上篇部落格AES加密解密。加解密方法在window上測試的時候沒有出現任何問題,將加密過程放在安卓上,解密發布到Linux伺服器的時候,安卓將加密的結果傳到Linux上解密的時候卻總是失敗,讓使用者不能成功登入,經過檢查,測試後,發現AES在Linux上解密失敗,出現錯誤:

        javax.crypto.BadPaddingException: Given final block not properly padded

現在來回顧下自己的解決思路:

        加密過程是在安卓上,解密是在Linu上,會不會是因為環境的不同,在加密過程中產生的二進位和在解密過程中產生的二進位不一樣呢?可是在經過聯調後,比對二進位,發現沒有問題。那問題是在哪裡呢?

       繼續聯調, 仔細比對加密和解密過程中每一步產生的結果,發現了問題:

Linux解密端:

       發現這裡的cipher下的 firstService是有值的。

        


安卓加密端:

       發現這裡的cipher下的 firstService是沒有值的。

       


百度後發現:

       加密解密方法的唯一差別是Cipher對象的模式不一樣,這就排除了程式寫錯的可能性。因為錯誤資訊是在宜昌中出現的,其大概意思是:提供的字塊不符合填補的。什麼意思呢?原來在用加密的時候,最後一位長度不足,它會自動補足,那麼在我們進行位元組數組到字串的轉化過程中,可以把它填補的不可見字元改變了,所以系統拋出異常。

        問題找到,怎麼解決呢?方式如下:

package ICT.base.rest.services.app;import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class AESDecodeUtils {public static void main(String[] args) {String content = "g25";String pwd = "8182838485";String addPwd = "123456";// 加密System.out.println("加密前content:" + content);byte[] enAccount = encrypt(content, addPwd);byte[] enPwd = encrypt(pwd, addPwd);String encryptResultStr = parseByte2HexStr(enAccount);String parseByte2HexStr2 = parseByte2HexStr(enPwd);System.out.println("加密後content:" + encryptResultStr);// 解密 ——帳號/社會安全號碼byte[] accountFrom = AESDecodeUtils.parseHexStr2Byte(encryptResultStr);byte[] deAccount = AESDecodeUtils.decrypt(accountFrom, addPwd);String userAccount = new String(deAccount);System.out.println("解密後content:" + userAccount);// 解密——密碼byte[] pwdFrom = AESDecodeUtils.parseHexStr2Byte(parseByte2HexStr2);byte[] deUserPwd = AESDecodeUtils.decrypt(pwdFrom, addPwd);String userPwd = new String(deUserPwd);// System.out.println(userPwd);}/** * AES加密 *  * @param content *            要加密的內容 * @param password *            加密使用的密鑰 * @return 加密後的位元組數組 */public static byte[] encrypt(String content, String password) {SecureRandom random = null;try {<span style="color:#ff0000;">random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(password.getBytes());</span>} catch (NoSuchAlgorithmException e1) {e1.printStackTrace();}try {KeyGenerator kgen = KeyGenerator.getInstance("AES");// kgen.init(128, new SecureRandom(password.getBytes()));<span style="color:#ff0000;">kgen.init(128, random);</span>SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");Cipher cipher = Cipher.getInstance("AES");// 建立密碼器byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化byte[] result = cipher.doFinal(byteContent);return result; // 加密} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/** * 將二進位轉換成16進位 加密 *  * @param buf * @return */public static String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/** * 解密 *  * @param content *            待解密內容 * @param password *            解密密鑰 * @return */public static byte[] decrypt(byte[] content, String password) {SecureRandom random = null;try {<span style="color:#ff0000;">random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(password.getBytes());</span>} catch (NoSuchAlgorithmException e1) {e1.printStackTrace();}try {KeyGenerator kgen = KeyGenerator.getInstance("AES");// kgen.init(128, new SecureRandom(password.getBytes()));<span style="color:#ff0000;">kgen.init(128, random);</span>SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");Cipher cipher = Cipher.getInstance("AES");// 建立密碼器cipher.init(Cipher.DECRYPT_MODE, key);// 初始化byte[] result = cipher.doFinal(content);return result; // 加密} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/** * 將16進位轉換為二進位 *  * @param hexStr * @return */public static byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1)return null;byte[] result = new byte[hexStr.length() / 2];for (int i = 0; i < hexStr.length() / 2; i++) {int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),16);result[i] = (byte) (high * 16 + low);}return result;}}


 運行結果:

        


將加密放到安卓端,解密放大Linux上後,如下:

       此時cipher下的 firstService不再是Null,都有了值

安卓加密端:

       

Linux解密端:

       


總結:

      AES是對稱式加密,解密端改變解密過程,同樣,加密端的加密過程也會改變,不管怎麼著,調程式還是得要有耐心,用一個東西,其簡單基本的原理還是要知道的。




       

        


       

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

解決Linux下AES解密失敗

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.