引用中文維基百科的定義(瀏覽全文):
密碼學(xué)中的高級(jí)加密標(biāo)準(zhǔn)(Advanced Encryption Standard,AES),又稱Rijndael加密法,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES,已經(jīng)被多方分析且廣為全世界所使用。經(jīng)過(guò)五年的甄選流程,高級(jí)加密標(biāo)準(zhǔn)由美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究院 (NIST)于2001年11月26日發(fā)布于FIPS PUB 197,并在2002年5月26日成為有效的標(biāo)準(zhǔn)。2006年,高級(jí)加密標(biāo)準(zhǔn)已然成為對(duì)稱密鑰加密中最流行的算法之一。該算法為比利時(shí)密碼學(xué)家Joan Daemen和Vincent Rijmen所設(shè)計(jì),結(jié)合兩位作者的名字,以Rijdael之命名之,投稿高級(jí)加密標(biāo)準(zhǔn)的甄選流程(Rijdael的發(fā)音近于 “Rhine doll”)。
AES 加密過(guò)程是在一個(gè)4×4的字節(jié)矩陣上運(yùn)作,這個(gè)矩陣又稱為“體(state)”,其初值就是一個(gè)明文區(qū)塊(矩陣中一個(gè)元素大小就是明文區(qū)塊中的一個(gè) Byte)。(Rijndael加密法因支援更大的區(qū)塊,其矩陣行數(shù)可視情況增加)加密時(shí),各輪AES加密循環(huán)(除最后一輪外)均包含4個(gè)步驟:
1. AddRoundKey — 矩陣中的每一個(gè)字節(jié)都與該次循環(huán)的子密鑰(round key)做XOR運(yùn)算;每個(gè)子密鑰由密鑰生成方案產(chǎn)生。
2. SubBytes — 透過(guò)一個(gè)非線性的替換函數(shù),用查找表的方式把每個(gè)字節(jié)替換成對(duì)應(yīng)的字節(jié)。
3. ShiftRows — 將矩陣中的每個(gè)橫列進(jìn)行循環(huán)式移位。
4. MixColumns — 為了充分混合矩陣中各個(gè)直行的操作。這個(gè)步驟使用線性轉(zhuǎn)換來(lái)混合每行內(nèi)的四個(gè)字節(jié)。最后一個(gè)加密循環(huán)中省略MixColumns步驟,而以另一個(gè)AddRoundKey取代。
創(chuàng)建加密/解密類源代碼:
01 | import java.security.SecureRandom; |
02 | |
03 | import javax.crypto.Cipher; |
04 | import javax.crypto.KeyGenerator; |
05 | import javax.crypto.SecretKey; |
06 | import javax.crypto.spec.SecretKeySpec; |
07 | |
08 | public class SimpleCrypto { |
09 | |
10 | public static String encrypt(String seed, String cleartext) throws Exception { |
11 | byte [] rawKey = getRawKey(seed.getBytes()); |
12 | byte [] result = encrypt(rawKey, cleartext.getBytes()); |
13 | return toHex(result); |
14 | } |
15 | |
16 | public static String decrypt(String seed, String encrypted) throws Exception { |
17 | byte [] rawKey = getRawKey(seed.getBytes()); |
18 | byte [] enc = toByte(encrypted); |
19 | byte [] result = decrypt(rawKey, enc); |
20 | return new String(result); |
21 | } |
22 | |
23 | private static byte [] getRawKey( byte [] seed) throws Exception { |
24 | KeyGenerator kgen = KeyGenerator.getInstance( "AES" ); |
25 | SecureRandom sr = SecureRandom.getInstance( "SHA1PRNG" ); |
26 | sr.setSeed(seed); |
27 | kgen.init( 128 , sr); // 192 and 256 bits may not be available |
28 | SecretKey skey = kgen.generateKey(); |
29 | byte [] raw = skey.getEncoded(); |
30 | return raw; |
31 | } |
32 | |
33 | private static byte [] encrypt( byte [] raw, byte [] clear) throws Exception { |
34 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES" ); |
35 | Cipher cipher = Cipher.getInstance( "AES" ); |
36 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec); |
37 | byte [] encrypted = cipher.doFinal(clear); |
38 | return encrypted; |
39 | } |
40 | |
41 | private static byte [] decrypt( byte [] raw, byte [] encrypted) throws Exception { |
42 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES" ); |
43 | Cipher cipher = Cipher.getInstance( "AES" ); |
44 | cipher.init(Cipher.DECRYPT_MODE, skeySpec); |
45 | byte [] decrypted = cipher.doFinal(encrypted); |
46 | return decrypted; |
47 | } |
48 | |
49 | public static String toHex(String txt) { |
50 | return toHex(txt.getBytes()); |
51 | } |
52 | public static String fromHex(String hex) { |
53 | return new String(toByte(hex)); |
54 | } |
55 | |
56 | public static byte [] toByte(String hexString) { |
57 | int len = hexString.length()/ 2 ; |
58 | byte [] result = new byte [len]; |
59 | for ( int i = 0 ; i < len; i++) |
60 | result[i] = Integer.valueOf(hexString.substring( 2 *i, 2 *i+ 2 ), 16 ).byteValue(); |
61 | return result; |
62 | } |
63 | |
64 | public static String toHex( byte [] buf) { |
65 | if (buf == null ) |
66 | return "" ; |
67 | StringBuffer result = new StringBuffer( 2 *buf.length); |
68 | for ( int i = 0 ; i < buf.length; i++) { |
69 | appendHex(result, buf[i]); |
70 | } |
71 | return result.toString(); |
72 | } |
73 | private final static String HEX = "0123456789ABCDEF" ; |
74 | private static void appendHex(StringBuffer sb, byte b) { |
75 | sb.append(HEX.charAt((b>> 4 )& 0x0f )).append(HEX.charAt(b& 0x0f )); |
76 | } |
77 | |
78 | } |
使用方法:
加密 –
1
String encryptingCode = SimpleCrypto.encrypt(masterPassword,originalText);
解密 –
1
String originalText = SimpleCrypto.decrypt(masterpassword, encryptingCode);
masterpassword: 密碼。
encryptingCode:加密后的字符串。
originalText: 需要加密的字符串。
聯(lián)系客服