1. 程式人生 > >AES加密演算法入門

AES加密演算法入門

1. AES簡介

AES是一個對稱密碼演算法。

AES支援五中模式:ECB,CBC,CFB,OFB,PCBC;支援三種填充:NoPaddingPKCS5PaddingISO10126Padding

這章只講AES加密的使用,不講具體原理,後面可能會具體講原理(博主不偷懶的話)。

值得注意的是:NoPadding填充方式只能加密長度為16n的內容

2. 程式碼示例

2.1程式碼

package com.tricycle.aes;


import java.util.Arrays;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;


import com.tricycle.utils.Log;


public class AES {
static Cipher cipher;
static final String AES_ALGORITHMS = "AES";
static final String ALGORITHMS_ECB_PKCS5Padding = "AES/ECB/PKCS5Padding";
static final String ALGORITHMS_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding";
static final String ALGORITHMS_CBC_NoPadding = "AES/CBC/NoPadding";
static final String ALGORITHMS_ECB_NoPadding = "AES/ECB/NoPadding";


static SecretKey secretKey;


public static void main(String[] args) {
encryptECB(ALGORITHMS_ECB_PKCS5Padding, "0123456789abcde");
encryptECB(ALGORITHMS_ECB_PKCS5Padding, "0123456789abcdef");
encryptECB(ALGORITHMS_ECB_NoPadding, "0123456789abcdef");
encryptECB(ALGORITHMS_ECB_NoPadding, "0123456789abcde");


encryptCBC(ALGORITHMS_CBC_PKCS5Padding, "0123456789abcde");
encryptCBC(ALGORITHMS_CBC_PKCS5Padding, "0123456789abcdef");
encryptCBC(ALGORITHMS_CBC_NoPadding, "0123456789abcdef");
encryptCBC(ALGORITHMS_CBC_NoPadding, "0123456789abcde");


}


private static void encryptECB(String padding, String source) {
try {
cipher = Cipher.getInstance(padding);


secretKey = KeyGenerator.getInstance(AES_ALGORITHMS).generateKey();
Log.print(padding + "; key length: "
+ secretKey.getEncoded().length);
Log.print(Arrays.toString(secretKey.getEncoded()));


cipher.init(Cipher.ENCRYPT_MODE, secretKey);


byte[] encrypt = cipher.doFinal(source.getBytes());
Log.print(Arrays.toString(encrypt));


cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decrypt = cipher.doFinal(encrypt);
Log.print(new String(decrypt));
} catch (Exception e) {
e.printStackTrace();
}
}


/*
* CBC need an initial vector; IV length must be 16 bytes long
*/
private static byte[] getIV() {
String iv = "1234567812345678";
return iv.getBytes();
}


private static void encryptCBC(String padding, String source) {
try {
cipher = Cipher.getInstance(padding);


secretKey = KeyGenerator.getInstance(AES_ALGORITHMS).generateKey();
Log.print(padding + "; key length: "
+ secretKey.getEncoded().length);
Log.print(Arrays.toString(secretKey.getEncoded()));


cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(
getIV()));
byte[] encrypt = cipher.doFinal(source.getBytes());
Log.print(Arrays.toString(encrypt));


cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(
getIV()));
byte[] decrypt = cipher.doFinal(encrypt);
Log.print(new String(decrypt));
} catch (Exception e) {
e.printStackTrace();
}
}


}

2.2輸出

AES/ECB/PKCS5Padding; key length: 16

[88, -41, 105, 86, -18, -91, -88, -4, -21, -56, 51, 72, 87, 114, -38, 13]

[-76, 11, -17, 55, 108, -52, -38, -96, -22, -124, -102, 61, 113, 81, 34, -84]

0123456789abcde

AES/ECB/PKCS5Padding; key length: 16

[104, -13, 9, 8, 95, -107, -96, 46, 71, -11, 34, 122, -20, -73, 19, -42]

[45, 118, 127, 84, -18, -122, -4, 105, 105, 56, -59, 94, -115, -108, -12, -8, -62, -71, 55, 13, 63, -82, 78, -5, -65, 10, 30, -9, 54, -9, -39, 70]

0123456789abcdef

AES/ECB/NoPadding; key length: 16

[-62, -48, -55, 82, -83, 115, 17, 122, 89, -25, -19, -31, -84, -111, -11, 16]

[39, 103, 109, 16, -83, 67, 109, 104, -111, -65, -30, -64, 11, -19, 4, 18]

0123456789abcdef

AES/ECB/NoPadding; key length: 16

[-10, 106, 99, -14, 25, 6, -64, -52, 88, 6, 24, 74, -90, 20, -52, 74]

javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes

at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:854)

at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:828)

at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)

at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)

at javax.crypto.Cipher.doFinal(Cipher.java:2087)

at com.tricycle.aes.AES.encryptECB(AES.java:57)

at com.tricycle.aes.AES.main(AES.java:37)

AES/CBC/PKCS5Padding; key length: 16

[68, -70, -14, -73, -14, 85, 113, -46, 37, 55, 5, 3, 52, -127, 12, 68]

[94, -18, 6, -27, 10, 97, 61, -69, -50, 0, 30, -49, 125, 106, -114, 20]

0123456789abcde

AES/CBC/PKCS5Padding; key length: 16

[1, -72, -50, 41, -111, 39, -26, -49, 78, -9, -27, -67, 29, 127, 8, 114]

[90, -65, 72, 108, -75, -54, 45, -45, 109, 117, -29, -99, -91, 118, -24, -37, 61, -43, -119, 119, 68, -50, 83, 105, -76, 70, 75, -80, 120, -60, -6, -40]

0123456789abcdef

AES/CBC/NoPadding; key length: 16

[25, -3, 116, -8, -9, 14, 119, 54, -18, -49, 11, -85, -56, 110, 17, -19]

[-114, -123, -43, 55, -85, -98, 24, 125, -45, 43, -3, 65, -98, -104, -34, -30]

0123456789abcdef

AES/CBC/NoPadding; key length: 16

[-79, 28, -10, 43, -50, -108, 7, -59, -116, -110, -42, 38, 56, 75, 71, 32]

javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes

at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:854)

at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:828)

at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)

at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)

at javax.crypto.Cipher.doFinal(Cipher.java:2087)

at com.tricycle.aes.AES.encryptCBC(AES.java:88)

at com.tricycle.aes.AES.main(AES.java:42)