1. AES加密字元串
public static byte[] encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 創建AES的Key生產者
kgen.init(128, new SecureRandom(password.getBytes()));// 利用用戶密碼作為隨機數初始化出
// 128位的key生產者
//加密沒關系,SecureRandom是生成安全隨機數序列,password.getBytes()是種子,只要種子相同,序列就一樣,所以解密只要有password就行
SecretKey secretKey = kgen.generateKey();// 根據用戶密碼,生成一個密鑰
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本編碼格式的密鑰,如果此密鑰不支持編碼,則返回
// null。
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 轉換為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 (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
2. AES解密
public static byte[] decrypt(byte[] content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 創建AES的Key生產者
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();// 根據用戶密碼,生成一個密鑰
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本編碼格式的密鑰
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 轉換為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;
}
B. 簡述aes演算法的加密過程
AES加密過程涉及到 4 種操作,分別是位元組替代、行移位、列混淆和輪密鑰加。
1.位元組替換:位元組代替的主要功能是通過S盒完成一個位元組到另外一個位元組的映射。
2.行移位:行移位的功能是實現一個4x4矩陣內部位元組之間的置換。
4.輪密鑰加:加密過程中,每輪的輸入與輪密鑰異或一次(當前分組和擴展密鑰的一部分進行按位異或);因為二進制數連續異或一個數結果是不變的,所以在解密時再異或上該輪的密鑰即可恢復輸入。
5.密鑰擴展:其復雜性是確保演算法安全性的重要部分。當分組長度和密鑰長度都是128位時,AES的加密演算法共迭代10輪,需要10個子密鑰。AES的密鑰擴展的目的是將輸入的128位密鑰擴展成11個128位的子密鑰。AES的密鑰擴展演算法是以字為一個基本單位(一個字為4個位元組),剛好是密鑰矩陣的一列。因此4個字(128位)密鑰需要擴展成11個子密鑰,共44個字。
C. 【密碼學】C語言實現AES核心步驟
按照AES演算法,完成AES演算法S盒、行移位、列混合、輪密鑰加操作
高級加密標准(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標准。這個標准用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高級加密標准由美國國家標准與技術研究院(NIST)於2001年11月26日發布於FIPS PUB 197,並在2002年5月26日成為有效的標准。2006年,高級加密標准已然成為對稱密鑰加密中最流行的演算法之一。
AES採用對稱分組密碼體制,密鑰的長度最少支持為128、192、256,分組長度128位,演算法應易於各種硬體和軟體實現。
AES加密數據塊分組長度必須為128比特,密鑰長度可以是128比特、192比特、256比特中的任意一個(如果數據塊及密鑰長度不足時,會補齊)。AES加密有很多輪的重復和變換。大致步驟如下:1、密鑰擴展(KeyExpansion),2、初始輪(Initial Round),3、重復輪(Rounds),每一輪又包括:位元組替代(SubBytes)、行移位(ShiftRows)、列混合(MixColumns)、輪密鑰加(AddRoundKey),4、最終輪(Final Round),最終輪沒有MixColumns。
AES演算法的加密整體結構
位元組替代(SubBytes):使用一個S盒進行非線性置換,S盒是一個16×16的矩陣,如表4-9所示。位元組替代將輸入的狀態矩陣的每一個位元組通過一個簡單查表操作,映射為另外一個位元組。
輸入位元組的前4bits指定S盒的行值,後4bits指定S盒的列值,行和列所確定S盒位置的元素作為輸出,例如輸入位元組「03」,行值為0,列值為3,根據表4-9可知第0行第3列對應的值為 「7B」,因此輸出位元組為「7B」。
舉例
在上面的示例中,第1個基本元素為」F5」,它將被S盒行為第」F行」、列為第」5」列的元素「E6「代替,其餘的輸出也用相同的方法確定。
狀態陣列的4個行循環以位元組為基本單位進行左移,而每行循環做移的偏移量是由明文分組的大小和所在行數共同確定,即列數Nb和行號確定。
舉例
舉例
輪密鑰加操作是將密鑰與明文按比特異或,輪密鑰通過密鑰擴展得到
和fips-192(AES)的標准一樣
D. 如何使用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'
E. java實現ase加密解密
這個演算法java SDK自帶的額 參考代碼如下:
/**解密
*@paramcontent待解密內容
*@parampassword解密密鑰
*@return
*/
publicstaticbyte[]decrypt(byte[]content,Stringpassword){
try{
KeyGeneratorkgen=KeyGenerator.getInstance("AES");
kgen.init(128,newSecureRandom(password.getBytes()));
SecretKeysecretKey=kgen.generateKey();
byte[]enCodeFormat=secretKey.getEncoded();
SecretKeySpeckey=newSecretKeySpec(enCodeFormat,"AES");
Ciphercipher=Cipher.getInstance("AES");//創建密碼器
cipher.init(Cipher.DECRYPT_MODE,key);//初始化
byte[]result=cipher.doFinal(content);
returnresult;//加密
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(IllegalBlockSizeExceptione){
e.printStackTrace();
}catch(BadPaddingExceptione){
e.printStackTrace();
}
returnnull;
}
/**
*加密
*
*@paramcontent需要加密的內容
*@parampassword加密密碼
*@return
*/
publicstaticbyte[]encrypt(Stringcontent,Stringpassword){
try{
KeyGeneratorkgen=KeyGenerator.getInstance("AES");
kgen.init(128,newSecureRandom(password.getBytes()));
SecretKeysecretKey=kgen.generateKey();
byte[]enCodeFormat=secretKey.getEncoded();
SecretKeySpeckey=newSecretKeySpec(enCodeFormat,"AES");
Ciphercipher=Cipher.getInstance("AES");//創建密碼器
byte[]byteContent=content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE,key);//初始化
byte[]result=cipher.doFinal(byteContent);
returnresult;//加密
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(UnsupportedEncodingExceptione){
e.printStackTrace();
}catch(IllegalBlockSizeExceptione){
e.printStackTrace();
}catch(BadPaddingExceptione){
e.printStackTrace();
}
returnnull;
}
http://blog.csdn.net/hbcui1984/article/details/5201247
圖像界面的話就不說了
F. 用AES演算法對整個文件加密,怎麼做
1.加密,是以某種特殊的演算法改變原有的信息數據,使得未授權的用戶即使獲得了已加密的信息,但因不知解密的方法,仍然無法了解信息的內容。例如對稱演算法亦或加密。
2.什麼是異或演算法
異或的特點是原始值經過兩次異或某一個數後會變成原來的值,所以有時利用這個特性來進行加密,加密端把數據與一個密鑰進行異或操作,生成密文。接收方收到密文後利用加密方提供的密鑰進行再次異或操作就能得到明文。
3.常式:
/*以DWORD為單位對文件進行加密,將每個DWORD與0xfcba0000(密鑰)做異或,寫入另一個文件*/
#include <stdio.h>
#include <stdlib.h>
#define DWORD unsigned long
#define BYTE unsigned char
#define false 0
#define true 1
int main(int argc, char *argv[])
{
FILE *hSource;
FILE *hDestination;
DWORD dwKey=0xfcba0000;
char* pbBuffer;
DWORD dwBufferLen=sizeof(DWORD);
DWORD dwCount;
DWORD dwData;
if(argv[1]==0||argv[2]==0)
{
printf("missing argument!\n");
return false;
}
G. 如何使用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變換一樣,都是按位與子密鑰做異或操作。解密過程的密鑰膨脹演算法也與加密的密鑰膨脹演算法相同。最後狀態矩陣中的數據就是明文。
H. AES加密的詳細過程是怎麼樣的
詳細過程如下圖:
AES加密標准又稱為高級加密標准Rijndael加密法,是美國國家標准技術研究所NIST旨在取代DES的21世紀的加密標准。AES的基本要求是,採用對稱分組密碼體制,密鑰長度可以為128、192或256位,分組長度128位,演算法應易在各種硬體和軟體上實現。
1998年NIST開始AES第一輪分析、測試和徵集,共產生了15個候選演算法。
1999年3月完成了第二輪AES2的分析、測試。2000年10月2日美國政府正式宣布選中比利時密碼學家Joan Daemen和Vincent Rijmen提出的一種密碼演算法Rijndael作為AES的加密演算法。
AES加密數據塊和密鑰長度可以是128b、192b、256b中的任意一個。AES加密有很多輪的重復和變換。