javaaes256加密
深圳遠標幫你:
1.默認 Java 中僅支持 128 位密鑰,當使用 256 位密鑰的時候,會報告密鑰長度錯誤
Invalid AES key length
你需要下載一個支持更長密鑰的包。這個包叫做 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6
看一下你的 JRE 環境,將 JRE 環境中 lib\lib\security 中的同名包替換掉。
2. Base64 問題
// 編碼
String asB64 = new Base64().encodeToString("some string".getBytes("utf-8"));
System.out.println(asB64); // 輸出為: c29tZSBzdHJpbmc=
解碼
// 解碼
byte[] asBytes = new Base64().getDecoder().decode("c29tZSBzdHJpbmc=");
System.out.println(new String(asBytes, "utf-8")); // 輸出為: some string
如果你已經使用 Java 8,那麼就不需要再選用第三方的實現了,在 java.util 包中已經包含了 Base64 的處理。
編碼的方式
// 編碼
String asB64 = Base64.getEncoder().encodeToString("some string".getBytes("utf-8"));
System.out.println(asB64); // 輸出為: c29tZSBzdHJpbmc=
解碼處理
// 解碼
byte[] asBytes = Base64.getDecoder().decode("c29tZSBzdHJpbmc=");
System.out.println(new String(asBytes, "utf-8")); // 輸出為: some string
3. 關於 PKCS5 和 PKCS7 填充問題
PKCS #7 填充字元串由一個位元組序列組成,每個位元組填充該填充位元組序列的長度。
假定塊長度為 8,數據長度為 9,
數據: FF FF FF FF FF FF FF FF FF
PKCS7 填充: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07
簡單地說, PKCS5, PKCS7和SSL3, 以及CMS(Cryptographic Message Syntax)
有如下相同的特點:
1)填充的位元組都是一個相同的位元組
2)該位元組的值,就是要填充的位元組的個數
如果要填充8個位元組,那麼填充的位元組的值就是0×8;
要填充7個位元組,那麼填入的值就是0×7;
…
如果只填充1個位元組,那麼填入的值就是0×1;
這種填充方法也叫PKCS5, 恰好8個位元組時還要補8個位元組的0×08
正是這種即使恰好是8個位元組也需要再補充位元組的規定,可以讓解密的數據很確定無誤的移除多餘的位元組。
比如, Java中
Cipher.getInstance(「AES/CBC/PKCS5Padding」)
這個加密模式
跟C#中的
RijndaelManaged cipher = new RijndaelManaged();
cipher.KeySize = 128;
cipher.BlockSize = 128;
cipher.Mode = CipherMode.CBC;
cipher.Padding = PaddingMode.PKCS7;
的加密模式是一樣的
因為AES並沒有64位的塊, 如果採用PKCS5, 那麼實質上就是採用PKCS7
❷ java aes加密與網上在線加密不同。誰能告訴我為什麼求個正確的例子,謝謝了!
Cipher.getInstance("AES/ECB/PKCS5Padding");
就是這個東西有很多標準的,你得看下線上用的是什麼標准
AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)
DES/CBC/NoPadding (56)
DES/CBC/PKCS5Padding (56)
DES/ECB/NoPadding (56)
DES/ECB/PKCS5Padding (56)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
RSA/ECB/PKCS1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
❸ 如何解密加密的AES-256字元串從CryptoJS使用Java
java和C#只是語言,AES這些是演算法,所以和語言沒太大關系,JAVA加密的「1」和c#加密的「1」結果是一樣的,解密出來也是一樣的。
❹ Java實現AES256位對稱加密演算法要替換什麼包才能實現
需要下載對應版本的Java Cryptography Extension (JCE),替換JDK安裝目錄\jre\lib\security下的local_policy.jar和US_export_policy.jar,如果獨立JRE的話也是覆蓋相同路徑的文件。
JDK8對應的JCE在 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
可以參考我的文章 http://boytnt.blog.51cto.com/966121/1860309
❺ 如何使用java對密碼加密 加密方式aes
Java有相關的實現類:具體原理如下
對於任意長度的明文,AES首先對其進行分組,每組的長度為128位。分組之後將分別對每個128位的明文分組進行加密。
對於每個128位長度的明文分組的加密過程如下:
(1)將128位AES明文分組放入狀態矩陣中。
(2)AddRoundKey變換:對狀態矩陣進行AddRoundKey變換,與膨脹後的密鑰進行異或操作(密鑰膨脹將在實驗原理七中詳細討論)。
(3)10輪循環:AES對狀態矩陣進行了10輪類似的子加密過程。前9輪子加密過程中,每一輪子加密過程包括4種不同的變換,而最後一輪只有3種變換,前9輪的子加密步驟如下:
● SubBytes變換:SubBytes變換是一個對狀態矩陣非線性的變換;
● ShiftRows變換:ShiftRows變換對狀態矩陣的行進行循環移位;
● MixColumns變換:MixColumns變換對狀態矩陣的列進行變換;
● AddRoundKey變換:AddRoundKey變換對狀態矩陣和膨脹後的密鑰進行異或操作。
最後一輪的子加密步驟如下:
● SubBytes變換:SubBytes變換是一個對狀態矩陣非線性的變換;
● ShiftRows變換:ShiftRows變換對狀態矩陣的行進行循環移位;
● AddRoundKey變換:AddRoundKey變換對狀態矩陣和膨脹後的密鑰進行異或操作;
(4)經過10輪循環的狀態矩陣中的內容就是加密後的密文。
AES的加密演算法的偽代碼如下。
在AES演算法中,AddRoundKey變換需要使用膨脹後的密鑰,原始的128位密鑰經過膨脹會產生44個字(每個字為32位)的膨脹後的密鑰,這44個字的膨脹後的密鑰供11次AddRoundKey變換使用,一次AddRoundKey使用4個字(128位)的膨脹後的密鑰。
三.AES的分組過程
對於任意長度的明文,AES首先對其進行分組,分組的方法與DES相同,即對長度不足的明文分組後面補充0即可,只是每一組的長度為128位。
AES的密鑰長度有128比特,192比特和256比特三種標准,其他長度的密鑰並沒有列入到AES聯邦標准中,在下面的介紹中,我們將以128位密鑰為例。
四.狀態矩陣
狀態矩陣是一個4行、4列的位元組矩陣,所謂位元組矩陣就是指矩陣中的每個元素都是一個1位元組長度的數據。我們將狀態矩陣記為State,State中的元素記為Sij,表示狀態矩陣中第i行第j列的元素。128比特的明文分組按位元組分成16塊,第一塊記為「塊0」,第二塊記為「塊1」,依此類推,最後一塊記為「塊15」,然後將這16塊明文數據放入到狀態矩陣中,將這16塊明文數據放入到狀態矩陣中的方法如圖2-2-1所示。
塊0
塊4
塊8
塊12
塊1
塊5
塊9
塊13
塊2
塊6
塊10
塊14
塊3
塊7
塊11
塊15
圖2-2-1 將明文塊放入狀態矩陣中
五.AddRoundKey變換
狀態矩陣生成以後,首先要進行AddRoundKey變換,AddRoundKey變換將狀態矩陣與膨脹後的密鑰進行按位異或運算,如下所示。
其中,c表示列數,數組W為膨脹後的密鑰,round為加密輪數,Nb為狀態矩陣的列數。
它的過程如圖2-2-2所示。
圖2-2-2 AES演算法AddRoundKey變換
六.10輪循環
經過AddRoundKey的狀態矩陣要繼續進行10輪類似的子加密過程。前9輪子加密過程中,每一輪要經過4種不同的變換,即SubBytes變換、ShiftRows變換、MixColumns變換和AddRoundKey變換,而最後一輪只有3種變換,即SubBytes變換、ShiftRows變換和AddRoundKey變換。AddRoundKey變換已經討論過,下面分別討論餘下的三種變換。
1.SubBytes變換
SubBytes是一個獨立作用於狀態位元組的非線性變換,它由以下兩個步驟組成:
(1)在GF(28)域,求乘法的逆運算,即對於α∈GF(28)求β∈GF(28),使αβ =βα = 1mod(x8 + x4 + x3 + x + 1)。
(2)在GF(28)域做變換,變換使用矩陣乘法,如下所示:
由於所有的運算都在GF(28)域上進行,所以最後的結果都在GF(28)上。若g∈GF(28)是GF(28)的本原元素,則對於α∈GF(28),α≠0,則存在
β ∈ GF(28),使得:
β = gαmod(x8 + x4 + x3 + x + 1)
由於g255 = 1mod(x8 + x4 + x3 + x + 1)
所以g255-α = β-1mod(x8 + x4 + x3 + x + 1)
根據SubBytes變換演算法,可以得出SubBytes的置換表,如表2-2-1所示,這個表也叫做AES的S盒。該表的使用方法如下:狀態矩陣中每個元素都要經過該表替換,每個元素為8比特,前4比特決定了行號,後4比特決定了列號,例如求SubBytes(0C)查表的0行C列得FE。
表2-2-1 AES的SubBytes置換表
它的變換過程如圖2-2-3所示。
圖2-2-3 SubBytes變換
AES加密過程需要用到一些數學基礎,其中包括GF(2)域上的多項式、GF(28)域上的多項式的計算和矩陣乘法運算等,有興趣的同學請參考相關的數學書籍。
2.ShiftRows變換
ShiftRows變換比較簡單,狀態矩陣的第1行不發生改變,第2行循環左移1位元組,第3行循環左移2位元組,第4行循環左移3位元組。ShiftRows變換的過程如圖2-2-4所示。
圖2-2-4 AES的ShiftRows變換
3.MixColumns變換
在MixColumns變換中,狀態矩陣的列看作是域GF(28)的多項式,模(x4+1)乘以c(x)的結果:
c(x)=(03)x3+(01)x2+(01)x+(02)
這里(03)為十六進製表示,依此類推。c(x)與x4+1互質,故存在逆:
d(x)=(0B)x3+(0D)x2+(0G)x+(0E)使c(x)•d(x) = (D1)mod(x4+1)。
設有:
它的過程如圖2-2-5所示。
圖2-2-5 AES演算法MixColumns變換
七.密鑰膨脹
在AES演算法中,AddRoundKey變換需要使用膨脹後的密鑰,膨脹後的密鑰記為子密鑰,原始的128位密鑰經過膨脹會產生44個字(每個字為32位)的子密鑰,這44個字的子密鑰供11次AddRoundKey變換使用,一次AddRoundKey使用4個字(128位)的膨脹後的密鑰。
密鑰膨脹演算法是以字為基礎的(一個字由4個位元組組成,即32比特)。128比特的原始密鑰經過膨脹後將產生44個字的子密鑰,我們將這44個密鑰保存在一個字數組中,記為W[44]。128比特的原始密鑰分成16份,存放在一個位元組的數組:Key[0],Key[1]……Key[15]中。
在密鑰膨脹演算法中,Rcon是一個10個字的數組,在數組中保存著演算法定義的常數,分別為:
Rcon[0] = 0x01000000
Rcon[1] = 0x02000000
Rcon[2] = 0x04000000
Rcon[3] = 0x08000000
Rcon[4] = 0x10000000
Rcon[5] = 0x20000000
Rcon[6] = 0x40000000
Rcon[7] = 0x80000000
Rcon[8] = 0x1b000000
Rcon[9] = 0x36000000
另外,在密鑰膨脹中包括其他兩個操作RotWord和SubWord,下面對這兩個操作做說明:
RotWord( B0,B1,B2,B3 )對4個位元組B0,B1,B2,B3進行循環移位,即
RotWord( B0,B1,B2,B3 ) = ( B1,B2,B3,B0 )
SubWord( B0,B1,B2,B3 )對4個位元組B0,B1,B2,B3使用AES的S盒,即
SubWord( B0,B1,B2,B3 ) = ( B』0,B』1,B』2,B』3 )
其中,B』i = SubBytes(Bi),i = 0,1,2,3。
密鑰膨脹的演算法如下:
八.解密過程
AES的加密和解密過程並不相同,首先密文按128位分組,分組方法和加密時的分組方法相同,然後進行輪變換。
AES的解密過程可以看成是加密過程的逆過程,它也由10輪循環組成,每一輪循環包括四個變換分別為InvShiftRows變換、InvSubBytes變換、InvMixColumns變換和AddRoundKey變換;
這個過程可以描述為如下代碼片段所示:
九.InvShiftRows變換
InvShiftRows變換是ShiftRows變換的逆過程,十分簡單,指定InvShiftRows的變換如下。
Sr,(c+shift(r,Nb))modNb= Sr,c for 0 < r< 4 and 0 ≤ c < Nb
圖2-2-6演示了這個過程。
圖2-2-6 AES演算法InvShiftRows變換
十.InvSubBytes變換
InvSubBytes變換是SubBytes變換的逆變換,利用AES的S盒的逆作位元組置換,表2-2-2為InvSubBytes變換的置換表。
表2-2-2 InvSubBytes置換表
十一.InvMixColumns變換
InvMixColumns變換與MixColumns變換類似,每列乘以d(x)
d(x) = (OB)x3 + (0D)x2 + (0G)x + (0E)
下列等式成立:
( (03)x3 + (01)x2 + (01)x + (02) )⊙d(x) = (01)
上面的內容可以描述為以下的矩陣乘法:
十二.AddRoundKey變換
AES解密過程的AddRoundKey變換與加密過程中的AddRoundKey變換一樣,都是按位與子密鑰做異或操作。解密過程的密鑰膨脹演算法也與加密的密鑰膨脹演算法相同。最後狀態矩陣中的數據就是明文。
❻ java AES256加密怎麼實現啊
java.security.InvalidKeyException: Illegal key
package com.jlins;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.jlins.util.Hex;
/**
* java Aes256 加密
*
* @author jlins
*
*/
public class Aes256Encryptor {
// 說明 key 需要大家自己去設定加密解密的key,key牽涉到安全信息,所以這里無法公布
private static final byte[] key = {};
private static final String transform = "AES/CBC/NoPadding";
private static final String algorithm = "AES";
private static final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);
public static void main(String[] args) throws Exception {
String pwds[] = { "123", "0123456789012345", "01234567890123456", "123", "123", "0123456789012345678",
"", "b", "0123456789012345", "01234567890123456", "012345678901234567" };
String ivss[] = { "test", "test", "test", "test0123456789012", "test01234567890123", "test", "test", "a",
"test", "test", "test" };
String rr[] = new String[ivss.length];
for (int i = 0; i < ivss.length; i++) {
String en = encrypt(pwds[i], ivss[i]);
String decy = decrypt(en, ivss[i]);
rr[i] = "[" + ivss[i] + "],[" + decy + "]-->[" + en + "]";
System.out.println(rr[i]);
}
System.out.println("---------");
for (int i = 0; i < rr.length; i++) {
System.out.println(rr[i]);
}
}
/**
*/
public static String decrypt(String pHexText, String pIv) throws Exception {
Cipher cipher = Cipher.getInstance(transform);
byte[] encryptedBytes = Hex.decode(pHexText);
byte[] iv = createIV(pIv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
System.array(decryptedBytes, 0, encryptedBytes, 0, encryptedBytes.length);
String result = new String(encryptedBytes);
return result.trim();
}
/**
*/
public static String encrypt(String pData, String pIv) throws Exception {
Cipher cipher = Cipher.getInstance(transform);
byte[] iv = createIV(pIv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));
byte[] output = cipher.doFinal(paddingData(pData));
byte[] encryptedContent = new byte[output.length];
System.array(output, 0, encryptedContent, 0, encryptedContent.length);
String result = new String(Hex.encode(encryptedContent)).toUpperCase();
return result;
}
/**
* 補齊的16位的整數倍
*
* @param pData
* @return
*/
private static byte[] paddingData(String pData) {
byte[] bytes = pData.getBytes();
int length = bytes.length / 16;
if (length * 16 < bytes.length) {
length++;
}
byte[] result = new byte[length * 16];
System.array(bytes, 0, result, 0, bytes.length);
for (int i = bytes.length; i < result.length; i++) {
result[i] = 0x00;
}
return result;
}
/**
* 初始化向量到16位
* */
private static byte[] createIV(String pIv) throws UnsupportedEncodingException {
byte[] bytes = pIv.getBytes("US-ASCII");
int length = bytes.length / 16;
if (length * 16 < bytes.length) {
length++;
}
byte[] result = new byte[16];
System.array(bytes, 0, result, 0, bytes.length > 16 ? 16 : bytes.length);
for (int i = bytes.length; i < result.length; i++) {
result[i] = 0x00;
}
return result;
}
}
❼ 如何使用CryptoJS的AES方法進行加密和解密
首先准備一份明文和秘鑰:
var plaintText = 'aaaaaaaaaaaaaaaa'; // 明文
var keyStr = 'bbbbbbbbbbbbbbbb'; // 一般key為一個字元串
參看官網文檔,AES方法是支持AES-128、AES-192和AES-256的,加密過程中使用哪種加密方式取決於傳入key的類型,否則就會按照AES-256的方式加密。
CryptoJS supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a passphrase, then it will generate a 256-bit key.
由於Java就是按照128bit給的,但是由於是一個字元串,需要先在前端將其轉為128bit的才行。
最開始以為使用CryptoJS.enc.Hex.parse就可以正確地將其轉為128bit的key。但是不然...
經過多次嘗試,需要使用CryptoJS.enc.Utf8.parse方法才可以將key轉為128bit的。好吧,既然說了是多次嘗試,那麼就不知道原因了,後期再對其進行更深入的研究。
// 字元串類型的key用之前需要用uft8先parse一下才能用
var key = CryptoJS.enc.Utf8.parse(keyStr);
由於後端使用的是PKCS5Padding,但是在使用CryptoJS的時候發現根本沒有這個偏移,查詢後發現PKCS5Padding和PKCS7Padding是一樣的東東,使用時默認就是按照PKCS7Padding進行偏移的。
// 加密
var encryptedData = CryptoJS.AES.encrypt(plaintText, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
由於CryptoJS生成的密文是一個對象,如果直接將其轉為字元串是一個Base64編碼過的,在encryptedData.ciphertext上的屬性轉為字元串才是後端需要的格式。
var encryptedBase64Str = encryptedData.toString();
// 輸出:'+ot8JuxWVdLgY='
console.log(encryptedBase64Str);
// 需要讀取encryptedData上的ciphertext.toString()才能拿到跟Java一樣的密文
var encryptedStr = encryptedData.ciphertext.toString();
// 輸出:''
console.log(encryptedStr);
由於加密後的密文為128位的字元串,那麼解密時,需要將其轉為Base64編碼的格式。
那麼就需要先使用方法CryptoJS.enc.Hex.parse轉為十六進制,再使用CryptoJS.enc.Base64.stringify將其變為Base64編碼的字元串,此時才可以傳入CryptoJS.AES.decrypt方法中對其進行解密。
// 拿到字元串類型的密文需要先將其用Hex方法parse一下
var encryptedHexStr = CryptoJS.enc.Hex.parse(encryptedStr);
// 將密文轉為Base64的字元串
// 只有Base64類型的字元串密文才能對其進行解密
var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
使用轉為Base64編碼後的字元串即可傳入CryptoJS.AES.decrypt方法中進行解密操作。
// 解密
var decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
經過CryptoJS解密後,依然是一個對象,將其變成明文就需要按照Utf8格式轉為字元串。
// 解密後,需要按照Utf8的方式將明文轉位字元串
var decryptedStr = decryptedData.toString(CryptoJS.enc.Utf8);
console.log(decryptedStr); // 'aaaaaaaaaaaaaaaa'
❽ java aes加密 如何用php 進行解密,以下是java代碼,求php 代碼如何寫 (主要是createkey 那個方法)
先看用什麼方式的加密,拿AES來說,你需要問java要到混淆值、初始化向量與AES加密的方式如AES-192-CFB.然後直接調用openssl_decrypt方法進行解密.
openssl_decrypt('需要解密的字元串','AES-192-CFB','混淆值',0,'初始化向量'),true)
❾ 為什麼JDK默認不支持AES 256位加密
aes加密其實是一種對稱加密的演算法,256位的話,其實就是計算的復雜度比128位增加了很多而已,因為我們一般的解破辦法都是採用字典或者是遍歷的方法來解破,所以計算復雜度增加就直接增加了計算的時間。如果這個時間很大的話,就認為不可能解破了,但是現在計算能力一直在不斷的提升和爆發中,所以原來以為很大的計算量,可能很快就變成很小的了。
❿ 關於iOS aes256加密的問題,請各位幫忙,搞了一個星期,急求答案!
之前在項目上用到AES256加密解密演算法,剛開始在java端加密解密都沒有問題,在iOS端加密解密也沒有問題。但是奇怪的是在java端加密後的文件在iOS端無法正確解密打開,然後簡單測試了一下,發現在java端和iOS端採用相同明文,相同密鑰加密後的密文不一樣!上網查了資料後發現iOS中AES加密演算法採用的填充是PKCS7Padding,而java不支持PKCS7Padding,只支持PKCS5Padding。我們知道加密演算法由演算法+模式+填充組成,所以這兩者不同的填充演算法導致相同明文相同密鑰加密後出現密文不一致的情況。那麼我們需要在java中用PKCS7Padding來填充,這樣就可以和iOS端填充演算法一致了。
要實現在java端用PKCS7Padding填充,需要用到bouncycastle組件來實現,下面我會提供該包的下載。啰嗦了一大堆,下面是一個簡單的測試,上代碼!
001 package com.encrypt.file;
002
003
004 import java.io.UnsupportedEncodingException;
005 importjava.security.Key;
006 import java.security.Security;
007
008 importjavax.crypto.Cipher;
009 importjavax.crypto.SecretKey;
010 importjavax.crypto.spec.SecretKeySpec;
011
012 public classAES256Encryption{
013
014 /**
015 * 密鑰演算法
016 * java6支持56位密鑰,bouncycastle支持64位
017 * */
018 public static finalString KEY_ALGORITHM="AES";
019
020 /**
021 * 加密/解密演算法/工作模式/填充方式
022 *
023 * JAVA6 支持PKCS5PADDING填充方式
024 * Bouncy castle支持PKCS7Padding填充方式
025 * */
026 public static finalString CIPHER_ALGORITHM="AES/ECB/PKCS7Padding";
027
028 /**
029 *
030 * 生成密鑰,java6隻支持56位密鑰,bouncycastle支持64位密鑰
031 * @return byte[] 二進制密鑰
032 * */
033 public static byte[] initkey() throwsException{
034
035 // //實例化密鑰生成器
036 // Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
037 // KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
038 // //初始化密鑰生成器,AES要求密鑰長度為128位、192位、256位
039 //// kg.init(256);
040 // kg.init(128);
041 // //生成密鑰
042 // SecretKey secretKey=kg.generateKey();
043 // //獲取二進制密鑰編碼形式
044 // return secretKey.getEncoded();
045 //為了便於測試,這里我把key寫死了,如果大家需要自動生成,可用上面注釋掉的代碼
046 return new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c,
047 0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a, 0x04, 0x0f,
048 0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09,
049 0x06, 0x07, 0x09, 0x0d };
050 }
051
052 /**
053 * 轉換密鑰
054 * @param key 二進制密鑰
055 * @return Key 密鑰
056 * */
057 public static Key toKey(byte[] key) throwsException{
058 //實例化DES密鑰
059 //生成密鑰
060 SecretKey secretKey=newSecretKeySpec(key,KEY_ALGORITHM);
061 returnsecretKey;
062 }
063
064 /**
065 * 加密數據
066 * @param data 待加密數據
067 * @param key 密鑰
068 * @return byte[] 加密後的數據
069 * */
070 public static byte[] encrypt(byte[] data,byte[] key) throwsException{
071 //還原密鑰
072 Key k=toKey(key);
073 /**
074 * 實例化
075 * 使用 PKCS7PADDING 填充方式,按如下方式實現,就是調用bouncycastle組件實現
076 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
077 */
078 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
079 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");
080 //初始化,設置為加密模式
081 cipher.init(Cipher.ENCRYPT_MODE, k);
082 //執行操作
083 returncipher.doFinal(data);
084 }
085 /**
086 * 解密數據
087 * @param data 待解密數據
088 * @param key 密鑰
089 * @return byte[] 解密後的數據
090 * */
091 public static byte[] decrypt(byte[] data,byte[] key) throwsException{
092 //歡迎密鑰
093 Key k =toKey(key);
094 /**
095 * 實例化
096 * 使用 PKCS7PADDING 填充方式,按如下方式實現,就是調用bouncycastle組件實現
097 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
098 */
099 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
100 //初始化,設置為解密模式
101 cipher.init(Cipher.DECRYPT_MODE, k);
102 //執行操作
103 returncipher.doFinal(data);
104 }
105 /**
106 * @param args
107 * @throws UnsupportedEncodingException
108 * @throws Exception
109 */
110 public static void main(String[] args) {
111
112 String str="AES";
113 System.out.println("原文:"+str);
114
115 //初始化密鑰
116 byte[] key;
117 try {
118 key = AES256Encryption.initkey();
119 System.out.print("密鑰:");
120 for(int i = 0;i<key.length;i++){
121 System.out.printf("%x", key[i]);
122 }
123 System.out.print("\n");
124 //加密數據
125 byte[] data=AES256Encryption.encrypt(str.getBytes(), key);
126 System.out.print("加密後:");
127 for(int i = 0;i<data.length;i++){
128 System.out.printf("%x", data[i]);
129 }
130 System.out.print("\n");
131
132 //解密數據
133 data=AES256Encryption.decrypt(data, key);
134 System.out.println("解密後:"+newString(data));
135 } catch (Exception e) {
136 // TODO Auto-generated catch block
137 e.printStackTrace();
138 }
139
140 }
141 }
運行程序後的結果截圖:
ViewController.m文件
01 //
02 // ViewController.m
03 // AES256EncryptionDemo
04 //
05 // Created by 孫 裔 on 12-12-13.
06 // Copyright (c) 2012年 rich sun. All rights reserved.
07 //
08
09 #import "ViewController.h"
10 #import "EncryptAndDecrypt.h"
11
12 @interface ViewController ()
13
14 @end
15
16 @implementation ViewController
17 @synthesize plainTextField;
18 - (void)viewDidLoad
19 {
20 [super viewDidLoad];
21 // Do any additional setup after loading the view, typically from a nib.
22 }
23
24 - (void)didReceiveMemoryWarning
25 {
26 [super didReceiveMemoryWarning];
27 // Dispose of any resources that can be recreated.
28 }
29 //這個函數實現了用戶輸入完後點擊視圖背景,關閉鍵盤
30 - (IBAction)backgroundTap:(id)sender{
31 [plainTextField resignFirstResponder];
32 }
33
34 - (IBAction)encrypt:(id)sender {
35
36 NSString *plainText = plainTextField.text;//明文
37 NSData *plainTextData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
38
39 //為了測試,這里先把密鑰寫死
40 Byte keyByte[] = {0x08,0x08,0x04,0x0b,0x02,0x0f,0x0b,0x0c,0x01,0x03,0x09,0x07,0x0c,0x03,
41 0x07,0x0a,0x04,0x0f,0x06,0x0f,0x0e,0x09,0x05,0x01,0x0a,0x0a,0x01,0x09,
42 0x06,0x07,0x09,0x0d};
43 //byte轉換為NSData類型,以便下邊加密方法的調用
44 NSData *keyData = [[NSData alloc] initWithBytes:keyByte length:32];
45 //
46 NSData *cipherTextData = [plainTextData AES256EncryptWithKey:keyData];
47 Byte *plainTextByte = (Byte *)[cipherTextData bytes];
48 for(int i=0;i<[cipherTextData length];i++){
49 printf("%x",plainTextByte[i]);
50 }
51
52 }
53 @end
附上出處鏈接:http://blog.csdn.net/pjk1129/article/details/8489550