1. 程式人生 > >32位AES加密解密(AES/ECB/PKCS7Padding)

32位AES加密解密(AES/ECB/PKCS7Padding)

兩個問題:

1. 金鑰超出了JDK預設的長度128時會報錯:

java.security.InvalidKeyException: Illegal key size or default parameters

(參考別人的)因為美國的出口限制,Sun通過許可權檔案(local_policy.jar、US_export_policy.jar)做了相應限制。因此存在一些問題:

●金鑰長度上不能滿足需求(如:java.security.InvalidKeyException: Illegal key size or default parameters);
●部分演算法未能支援,如MD4、SHA-224等演算法;
●API使用起來還不是很方便;一些常用的進位制轉換輔助工具未能提供,如Base64編碼轉換、十六進位制編碼轉換等工具。

Oracle在其官方網站上提供了無政策限制許可權檔案(Unlimited Strength Jurisdiction Policy Files),我們只需要將其部署在JRE環境中,就可以解決限制問題。

解決辦法:

JDK8 jar包下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
JDK7 jar包下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

%JDK_Home%\jre\lib\security目錄下,對應覆蓋local_policy.jar和US_export_policy.jar兩個檔案。

%JRE_Home%\lib\security目錄下,也需要對應覆蓋這兩個檔案。

2. JDK自帶的方法只支援PKCS5Padding,PKCS7Padding需要特殊處理:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

具體加解密演算法如下:

public class AesUtils {
    /**
     * 演算法/模式/填充
     **/
private static final String CipherMode = "AES/ECB/PKCS7Padding";

    /**
* 建立金鑰 **/ private static SecretKeySpec createKey(String password) { byte[] data = null; if (password == null) { password = ""; } StringBuffer sb = new StringBuffer(32); sb.append(password); while (sb.length() < 32) { sb.append("0"); } if (sb.length() > 32) { sb.setLength(32); } try { data = sb.toString().getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { log.error("createKey error: ", e); } return new SecretKeySpec(data, "AES"); } public static String create32Key(String password) { StringBuffer sb = new StringBuffer(32); sb.append(password); while (sb.length() < 32) { sb.append("0"); } if (sb.length() > 32) { sb.setLength(32); } return sb.toString(); } /** * 加密位元組資料 **/ public static byte[] encryptJava(byte[] content, String password) { try { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); SecretKeySpec key = createKey(password); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] result = cipher.doFinal(content); return result; } catch (Exception e) { log.error("encryptJava error: ", e); } return null; } /** * 解密位元組陣列 **/ public static byte[] decryptJava(byte[] content, String password) { try { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); SecretKeySpec key = createKey(password); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.DECRYPT_MODE, key); byte[] result = cipher.doFinal(content); return result; } catch (Exception e) { log.error("decryptJava error: ", e); } return null; } /** * 加密(結果為16進位制字串) **/ public static String encryptJava(String content, String password) { if (StringUtils.isEmpty(password) || StringUtils.isEmpty(content)) { return content; } byte[] data = null; try { data = content.getBytes("UTF-8"); } catch (Exception e) { log.error("encryptJava error: ", e); } data = encryptJava(data, password); return Base64Utils.encode(data); } public static String decryptJava(String content, String password) { if (StringUtils.isEmpty(password) || StringUtils.isEmpty(content)) { return content; } if (StringUtils.isEmpty(password)) { return content; } byte[] data = decryptJava(Base64Utils.decode(content), password); if (data == null) { return null; } String result = ""; try { result = new String(data, "UTF-8"); } catch (UnsupportedEncodingException e) { log.error("decrypt error: ", e); } return result; } /** * 加密(結果為16進位制字串) **/ public static String encrypt(String content, String password) { return encryptJava(content, password); } /** * 解密16進位制的字串為字串 **/ public static String decrypt(String content, String password) { return decryptJava(content, password); } }
public class Base64Utils {
    private static char[] base64EncodeChars = new char[] { 'A', 'B', 'C', 'D',
            'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
            'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
            'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
            'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
            '4', '5', '6', '7', '8', '9', '+', '/' };
    private static byte[] base64DecodeChars = new byte[] { -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59,
            60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
            10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1,
            -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
            38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1,
            -1, -1 };

    private Base64Utils() {
    }

    public static String encode(byte[] data) {
        StringBuffer sb = new StringBuffer();
        int len = data.length;
        int i = 0;
        int b1, b2, b3;

        while (i < len) {
            b1 = data[i++] & 0xff;
            if (i == len) {
                sb.append(base64EncodeChars[b1 >>> 2]);
                sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
                sb.append("==");
                break;
            }
            b2 = data[i++] & 0xff;
            if (i == len) {
                sb.append(base64EncodeChars[b1 >>> 2]);
                sb.append(base64EncodeChars[((b1 & 0x03) << 4)
                        | ((b2 & 0xf0) >>> 4)]);
                sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
                sb.append("=");
                break;
            }
            b3 = data[i++] & 0xff;
            sb.append(base64EncodeChars[b1 >>> 2]);
            sb.append(base64EncodeChars[((b1 & 0x03) << 4)
                    | ((b2 & 0xf0) >>> 4)]);
            sb.append(base64EncodeChars[((b2 & 0x0f) << 2)
                    | ((b3 & 0xc0) >>> 6)]);
            sb.append(base64EncodeChars[b3 & 0x3f]);
        }
        return sb.toString();
    }

    public static byte[] decode(String str) {
        byte[] data = str.getBytes();
        int len = data.length;
        ByteArrayOutputStream buf = new ByteArrayOutputStream(len);
        int i = 0;
        int b1, b2, b3, b4;

        while (i < len) {

         /* b1 */
do {
                b1 = base64DecodeChars[data[i++]];
            } while (i < len && b1 == -1);
            if (b1 == -1) {
                break;
            }

         /* b2 */
do {
                b2 = base64DecodeChars[data[i++]];
            } while (i < len && b2 == -1);
            if (b2 == -1) {
                break;
            }
            buf.write((int) ((b1 << 2) | ((b2 & 0x30) >>> 4)));

         /* b3 */
do {
                b3 = data[i++];
                if (b3 == 61) {
                    return buf.toByteArray();
                }
                b3 = base64DecodeChars[b3];
            } while (i < len && b3 == -1);
            if (b3 == -1) {
                break;
            }
            buf.write((int) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));

         /* b4 */
do {
                b4 = data[i++];
                if (b4 == 61) {
                    return buf.toByteArray();
                }
                b4 = base64DecodeChars[b4];
            } while (i < len && b4 == -1);
            if (b4 == -1) {
                break;
            }
            buf.write((int) (((b3 & 0x03) << 6) | b4));
        }
        return buf.toByteArray();
    }
}

相關推薦

32AES加密解密AES/ECB/PKCS7Padding

兩個問題:1. 金鑰超出了JDK預設的長度128時會報錯:java.security.InvalidKeyException: Illegal key size or default parameters(參考別人的)因為美國的出口限制,Sun通過許可權檔案(local_po

AES加密解密工具類+例項

工具類:  package com.valueaddedservices.web.utils; import java.util.Date; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec;

AES 加密 解密Hex編碼解碼

Aes加密解密方法使用Hex進行了編碼解碼 package com.baidu.wallet.bdwallet.utils; import java.io.UnsupportedEncodingException; import java.security.Inval

CTR分組模式實現AES加密解密go語言

版權宣告:本文為作者原創,如需轉載,請註明出處 https://blog.csdn.net/weixin_42940826 AES演算法簡介 AES演算法是為了取代DES演算法而生,雖然3DES演算法仍然可以使用,但是效率比較低下,AES演算法是在眾多演算法中選拔

android AES加密解密最新版

專案中要用到AES加密,百度上的AES壓根不能用,也不知道是那年的東西了,和後臺不相容,後來,後臺把他的AES程式碼拷給我  通過PHP程式碼找到了對應的Android程式碼 原文地址:http://www.funboxpower.com/php_android_ios_a

二十四進制編碼串轉換為32無符號整數C語言實現

bool while open 參數錯誤 hint div 第一個字符 bsp opened typedef int BOOL; #define TRUE 1; #define FALSE 0; #define UINT_MAX 0xffffffff

IP轉換為32無符號數即,inet_aton函式

#include<sys/types.h> #include<netinet/in.h> int inet_aton(const char *cp, struct in_addr *ap) { int dots = 0; register u_long acc =

Java 3DES加密解密Commons.Codec Base64

依賴包import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.binary.Base64;演算法程式碼 /** * 轉換成十六進位制字串 * @

win8 X64上安裝32Oracle Instant Client即時客戶端 安裝與配置

一、下載 這是Oracle Instant Client的下載首頁,有很多種版本可供下載。 但要注意第三方工具如:PL/SQL Developer和Toad的版本,32位的要對應32位的OracleInstant Client,不要因為系統是64位的就下載64位的,

aes加密解密,含 128、192、256,cbc、cfb、ecb、ofb、pcbc模式

AES加解密總共有以下這些 演算法/模式/填充 位元組加密後資料長度 不滿16位元組加密後長度 AES/CBC/NoPadding 16

php aes加密解密兼容php5、php7

bytes pri rip dom ase lee vat idea cipher <?php /** * @desc:php aes加密解密類 * @author [Lee] <[<[email protected]>]> */ class

java AES 加密解密工具Advanced Encryption Standard

@param key block 生成 utf i++ spec res null 1、通用方法 package com.qlkj.hzd.commom.utils; import javax.crypto.*; import java.io.Unsupported

工具篇——AESCBCUtil用於AES加密解密

寫程式碼的四點:      1.明確需求。要做什麼?      2.分析思路。要怎麼做?(1,2,3……)      3.確定步驟。每一個思路要用到哪些語句、方法和物件。      4.程式碼實現。用具體的語言程式碼將思路實現出來。 學習新技術的四點:      

AES ECB加密實現java/php/python

這裡做個一個加密實現的記錄,方便以後查詢 AES加密 ECB模式 PKCS5填充 128位密碼/密碼塊 ECB模式是將明文按照固定大小的塊進行加密的,塊大小不足則進行填充。ECB模式沒有用到向量。 python 實現 # -*- coding=u

使用AES演算法對檔案進行加密解密JAVA+Eclipse

一、專案中引用第三方類庫的方法    Bouncy Castle類庫的用法(如何在自己的專案中使用第三方類庫)    1)手動配置    將.jar,src,javadoc拷到專案目錄下   專案名,右鍵選build path-configure build path   

java使用AES加密解密 AES-128-ECB加密

http://www.cnblogs.com/chen-lhx/p/5817161.html *************************************************** import javax.crypto.Cipher; import jav

GO語言JAVA語言實現的AES/CFB/256加密解密例子

AES加密解密演算法裡面,最複雜的的就是CFB模式,因為CFB模式每次附加隨機一個IV,造成同樣的KEY,每次生成的加密串不一樣。解密的時候要用到這個IV,IV附加在了加密好的資料裡面,有的實現是把IV放資料的最後,有的是最面前,比如加密之後的資料是XXX,    則最終的資

Aes加密解密

tran delegate class ext str eap ase hfs tde 加密時:先對string進行utf8解析成數組-->對數組進行加密-->對加密結果用base64解析成string。 那麽揭秘時,

AES加密解密&amp;&amp;SHA1、SHA加密&amp;&amp;MD5加密

algorithm buffer password 使用 eas ray locks tex update AES加密解密 SHA1、SHA加密 MD5加密 二話不說立即附上代碼: package com.luo.util; import j

C# 實現 JAVA AES加密解密[原創]

com base gets tran con spec ole tor 技術分享 以下是網上普遍能收到的JAVA AES加密解密方法。 因為裏面用到了KeyGenerator 和 SecureRandom,但是.NET 裏面沒有這2個類。無法使用安全隨機數生成KEY。 我們