擴散加密算法是一種使用擴散算法進行數據加密/解密的算法。它使用擴散算法的原理,在處理過程中加入密匙,從而達到數據加密的目的。擴散算法有著完美的擴散率,進行數據加密可謂是“本職所在”。
基本介紹
- 中文名:擴散加密算法
- 外文名:Diffusion Encryption Algorithm
- 用途:數據加密
- 標籤:數據加密 加密算法 加密技術
擴散算法介紹
加密原理
加密過程
算法特性
加密模式
代碼實現
/** * <p> * 套用擴散算法進行數據加密和解密示例(以兩組為例,分別為X和Y)。 * </p> * * * @version 2.0 * @author Angel * */public class CryptoDemo { /* * S盒子, 任意0~255之間的不重複隨機整數。 S盒子是用於數據加密時函式所使用的數據,用以消除線性。 * S盒子的隨機性將會影響加密質量。 */ //@formatter:off public static final byte[] S = { (byte)0xd9, (byte)0x25, (byte)0x48, (byte)0x5c, (byte)0x55, (byte)0xa0, (byte)0x3c, (byte)0x94, (byte)0x83, (byte)0x36, (byte)0x11, (byte)0x74, (byte)0x69, (byte)0x2e, (byte)0x59, (byte)0x7b, (byte)0xd1, (byte)0x23, (byte)0x70, (byte)0x75, (byte)0x3a, (byte)0xbf, (byte)0x8c, (byte)0xd8, (byte)0x2f, (byte)0x34, (byte)0xb3, (byte)0x79, (byte)0xa4, (byte)0x27, (byte)0xa9, (byte)0x1d, (byte)0xb0, (byte)0xc8, (byte)0x38, (byte)0x8f, (byte)0x49, (byte)0x8b, (byte)0x89, (byte)0x0f, (byte)0x3b, (byte)0x92, (byte)0x33, (byte)0xcf, (byte)0xcd, (byte)0x1b, (byte)0x06, (byte)0xf0, (byte)0xfb, (byte)0x82, (byte)0xbb, (byte)0xc6, (byte)0xf2, (byte)0x07, (byte)0x4e, (byte)0xe8, (byte)0x77, (byte)0x6c, (byte)0x88, (byte)0x28, (byte)0xba, (byte)0xb9, (byte)0xe1, (byte)0xe9, (byte)0xd7, (byte)0x4b, (byte)0x81, (byte)0xde, (byte)0x08, (byte)0x0d, (byte)0xfc, (byte)0x03, (byte)0x87, (byte)0x56, (byte)0x14, (byte)0x0a, (byte)0x63, (byte)0x98, (byte)0x7a, (byte)0xf9, (byte)0x2c, (byte)0x7e, (byte)0x13, (byte)0x7d, (byte)0x04, (byte)0x01, (byte)0x9e, (byte)0xbc, (byte)0x41, (byte)0xdf, (byte)0x05, (byte)0x4f, (byte)0xfa, (byte)0x47, (byte)0x53, (byte)0xf8, (byte)0x46, (byte)0x52, (byte)0x8e, (byte)0x4a, (byte)0x76, (byte)0x09, (byte)0x1e, (byte)0xd2, (byte)0x2d, (byte)0x3e, (byte)0x61, (byte)0x5a, (byte)0x20, (byte)0x29, (byte)0xd0, (byte)0x16, (byte)0xb4, (byte)0x67, (byte)0xbd, (byte)0x50, (byte)0x60, (byte)0x35, (byte)0x19, (byte)0xd5, (byte)0xdd, (byte)0x8a, (byte)0xea, (byte)0xa5, (byte)0xac, (byte)0x1a, (byte)0x58, (byte)0x1f, (byte)0x5d, (byte)0x40, (byte)0x6d, (byte)0x86, (byte)0xeb, (byte)0x42, (byte)0x02, (byte)0x00, (byte)0xaa, (byte)0x9b, (byte)0xa1, (byte)0x7f, (byte)0xe4, (byte)0xb8, (byte)0xe6, (byte)0x21, (byte)0x68, (byte)0x12, (byte)0xd6, (byte)0x4d, (byte)0x4c, (byte)0x62, (byte)0xc0, (byte)0x66, (byte)0x0e, (byte)0x72, (byte)0x64, (byte)0xf6, (byte)0x80, (byte)0xb5, (byte)0xd4, (byte)0xf4, (byte)0x84, (byte)0x9d, (byte)0x73, (byte)0x51, (byte)0xe3, (byte)0x26, (byte)0xf3, (byte)0x1c, (byte)0x96, (byte)0xe2, (byte)0xcc, (byte)0x90, (byte)0xa3, (byte)0xc5, (byte)0xda, (byte)0xf7, (byte)0xad, (byte)0x6b, (byte)0x44, (byte)0x31, (byte)0xdb, (byte)0xa7, (byte)0xd3, (byte)0xfd, (byte)0xb2, (byte)0xcb, (byte)0xc7, (byte)0xf1, (byte)0x91, (byte)0x97, (byte)0xae, (byte)0xb6, (byte)0x45, (byte)0xc4, (byte)0xec, (byte)0xc2, (byte)0xce, (byte)0x18, (byte)0x3d, (byte)0xbe, (byte)0x7c, (byte)0xe5, (byte)0xb1, (byte)0xc9, (byte)0x0c, (byte)0x54, (byte)0x24, (byte)0x43, (byte)0x30, (byte)0x2a, (byte)0xb7, (byte)0xca, (byte)0x6e, (byte)0xc3, (byte)0x5b, (byte)0x9f, (byte)0x10, (byte)0xee, (byte)0x8d, (byte)0x95, (byte)0x32, (byte)0xc1, (byte)0x57, (byte)0x0b, (byte)0xed, (byte)0x99, (byte)0x5f, (byte)0xdc, (byte)0xaf, (byte)0x17, (byte)0xef, (byte)0xff, (byte)0x9c, (byte)0x9a, (byte)0x85, (byte)0x2b, (byte)0xab, (byte)0x5e, (byte)0xf5, (byte)0x6f, (byte)0xa6, (byte)0x39, (byte)0xa8, (byte)0x6a, (byte)0x3f, (byte)0x93, (byte)0x65, (byte)0xe0, (byte)0xfe, (byte)0x71, (byte)0x15, (byte)0x78, (byte)0x22, (byte)0xa2, (byte)0x37, (byte)0xe7, }; /* * 逆S盒子,設v是一個0~255之間的整數,_S必須滿足_S[S[v]] = v. */ public static final byte[] _S = { (byte)0x1c, (byte)0xc2, (byte)0xb1, (byte)0x88, (byte)0x20, (byte)0x6a, (byte)0x03, (byte)0xc8, (byte)0xba, (byte)0xa6, (byte)0xf9, (byte)0xa5, (byte)0x96, (byte)0x5a, (byte)0xe2, (byte)0xa3, (byte)0x2b, (byte)0x3c, (byte)0xa9, (byte)0x75, (byte)0x87, (byte)0x5b, (byte)0x28, (byte)0x3d, (byte)0xcd, (byte)0x61, (byte)0x69, (byte)0x09, (byte)0x68, (byte)0x21, (byte)0xd6, (byte)0x57, (byte)0x85, (byte)0x0a, (byte)0x7d, (byte)0x2c, (byte)0x9c, (byte)0xfb, (byte)0x70, (byte)0x35, (byte)0x72, (byte)0x9e, (byte)0x08, (byte)0x6c, (byte)0xfc, (byte)0x30, (byte)0x3e, (byte)0x64, (byte)0xa0, (byte)0x4a, (byte)0x38, (byte)0x9a, (byte)0xf0, (byte)0x1d, (byte)0x3f, (byte)0x52, (byte)0x0d, (byte)0xbd, (byte)0xbc, (byte)0xb2, (byte)0xd7, (byte)0xf2, (byte)0x47, (byte)0x95, (byte)0x16, (byte)0x5d, (byte)0x43, (byte)0x55, (byte)0x41, (byte)0x2d, (byte)0xb3, (byte)0x3a, (byte)0xa1, (byte)0x4b, (byte)0x53, (byte)0x39, (byte)0x2a, (byte)0xac, (byte)0x44, (byte)0xab, (byte)0xee, (byte)0x90, (byte)0xe7, (byte)0x36, (byte)0x1e, (byte)0xf7, (byte)0x12, (byte)0xc0, (byte)0x97, (byte)0x80, (byte)0x2e, (byte)0x34, (byte)0x63, (byte)0xf8, (byte)0xc3, (byte)0xd9, (byte)0x77, (byte)0xbe, (byte)0x29, (byte)0x24, (byte)0x0c, (byte)0x49, (byte)0x0e, (byte)0x7f, (byte)0xb7, (byte)0xbf, (byte)0xfa, (byte)0x04, (byte)0x42, (byte)0x60, (byte)0x59, (byte)0x66, (byte)0xaf, (byte)0x3b, (byte)0xb4, (byte)0x26, (byte)0x1f, (byte)0x6e, (byte)0x1b, (byte)0x2f, (byte)0xdf, (byte)0xcf, (byte)0xdc, (byte)0xb0, (byte)0xc6, (byte)0x37, (byte)0x78, (byte)0x67, (byte)0x07, (byte)0xd5, (byte)0x06, (byte)0xc7, (byte)0xd4, (byte)0xda, (byte)0xae, (byte)0xb5, (byte)0xc4, (byte)0xe5, (byte)0xcb, (byte)0x5f, (byte)0x4c, (byte)0xc5, (byte)0x18, (byte)0xa7, (byte)0x58, (byte)0x8a, (byte)0x11, (byte)0xd2, (byte)0xca, (byte)0x7a, (byte)0xef, (byte)0x65, (byte)0x45, (byte)0xf6, (byte)0xfd, (byte)0xad, (byte)0x27, (byte)0x9f, (byte)0xe6, (byte)0xff, (byte)0xec, (byte)0x0f, (byte)0x7c, (byte)0x91, (byte)0x4e, (byte)0x81, (byte)0x25, (byte)0x9d, (byte)0xbb, (byte)0xed, (byte)0x51, (byte)0x6b, (byte)0xd0, (byte)0xe8, (byte)0x8d, (byte)0x98, (byte)0x50, (byte)0x33, (byte)0x5c, (byte)0xaa, (byte)0x99, (byte)0xf5, (byte)0x89, (byte)0x7e, (byte)0xa2, (byte)0x71, (byte)0x94, (byte)0xa8, (byte)0x86, (byte)0x46, (byte)0xe9, (byte)0x74, (byte)0x01, (byte)0xd8, (byte)0x05, (byte)0x4f, (byte)0x32, (byte)0x40, (byte)0xe0, (byte)0xdd, (byte)0x82, (byte)0xa4, (byte)0xe3, (byte)0xc1, (byte)0x14, (byte)0x13, (byte)0xb6, (byte)0xdb, (byte)0xf3, (byte)0x23, (byte)0xe1, (byte)0xde, (byte)0x4d, (byte)0x84, (byte)0xc9, (byte)0x5e, (byte)0xfe, (byte)0x8e, (byte)0xeb, (byte)0x56, (byte)0x83, (byte)0x00, (byte)0x6d, (byte)0x62, (byte)0xf4, (byte)0xea, (byte)0x15, (byte)0xcc, (byte)0x1a, (byte)0x76, (byte)0x17, (byte)0xf1, (byte)0x10, (byte)0x8c, (byte)0x73, (byte)0x31, (byte)0xb9, (byte)0x02, (byte)0x54, (byte)0x6f, (byte)0x92, (byte)0x79, (byte)0x19, (byte)0x22, (byte)0x8b, (byte)0x93, (byte)0xe4, (byte)0xb8, (byte)0x7b, (byte)0x9b, (byte)0xce, (byte)0x8f, (byte)0x48, (byte)0xd3, (byte)0xd1, (byte)0x0b, }; static long LONG_TEN = 100000000000000L; int E = 2; // 額外的循環數量E int N; // 分組長度N int P; // 基於長度N的完美長度。 int round; // 用於加密的輪數(對應擴散階段的數量)。 byte[][] KX; // 用於加密的子密匙(X), 每一輪的密匙都不相同。 byte[][] KY; // 用於加密的子密匙(Y), 每一輪的密匙都不相同。 // @formatter:on public CryptoDemo(int keySize) { // keySize:byte N = keySize; int G = (int) Math.ceil(Math.log(N) / Math.log(2)); // 計算以2為底N的對數,並向上取整 P = 1 << G; // P=2的G次方 round = G + E; KX = new byte[round][]; KY = new byte[round][]; } /** * 生成子密匙, 通過擴散算法使得原密匙的每一個密匙都影響其它任何一個密匙。 * <p> * 每個周期完成後,將本周的輸出作為下一個周期的輸入再計運算元密匙。共需round個周期。 * </p> * * @param kx * 原始密匙X * @param ky * 原始密匙Y */ public void init(byte[] kx, byte[] ky) { for (int i = 0; i < round; i++) { init(kx, ky, i); } } Function FKx = new XKey(); // 用於生成子密匙的函式X Function FKy = new YKey(); // 用於生成子密匙的函式Y private void init(byte[] kx, byte[] ky, int index) { int l = 0; for (int i = 1; i <= round; i++) { for (int r = 0; r < N; r++) { ky[r] = (byte) (FKy.call(kx[l], ky[r]) & 255); kx[l] = (byte) (FKx.call(kx[l], ky[r]) & 255); l = (++l) % N; } l = P >> i; } KX[index] = kx.clone(); KY[index] = ky.clone(); } /** * 用於生成子密匙的函式X實現。 * * @author Angel * */ class XKey implements Function { int A = 11; int B = 21; int C = 31; @Override public int call(int x, int y, int... values) { return A * x * x + B * y + C; } } /** * 用於生成子密匙的函式Y實現。 * * @author Angel * */ class YKey implements Function { long C = 0x6180339887L; @Override public int call(int x, int y, int... values) { double a = Math.sin(x); double b = Math.cos(y); long v = (long) ((a + b) * LONG_TEN + C); return (int) (v & 0xffffffff); } } // ---------------------------------------------------------------------------- Function Ex = new XEncrypt(); // 用於加密進行擴散運算的函式X Function Ey = new YEncrypt(); // 用於加密進行擴散運算的函式Y /** * 加密明文。次方法只加密一組數據,X,Y的長度為N。 * * @param X * 明文X * @param Y * 明文Y */ public void encrypt(byte[] X, byte[] Y) { int x = 0; for (int i = 1, k = 0; i <= round; i++, k++) { for (int y = 0; y < N; y++) { Y[y] = (byte) Ey.call(X[x], Y[y], KY[k][y]); X[x] = (byte) Ex.call(X[x], Y[y], KX[k][y]); // KX[k][x] // 不建議使用%運算 // 當N&(N-1)=0時,可使用&運算,即N=2的j次方(j>0,且j為整數) x = (++x) % N; // x = (++x) & (N-1); } x = P >> i; } } /** * 用於加密算法的函式X實現。 * * @author Angel * */ class XEncrypt implements Function { /** * 由於java中byte的值域為[-128,127],因此需要將運算後的值加128以改變值域為[0,255](余同)。 * * <p> * 此處為行方便,特將key以其他參數的第0位傳入(余同)。 * </p> */ @Override public int call(int x, int y, int... values) { // values[0] is key return S[(x ^ values[0]) + 128] ^ y; } } /** * 用於加密算法的函式Y實現。 * * @author Angel * */ class YEncrypt implements Function { @Override public int call(int x, int y, int... values) { // values[0] is key return S[(y ^ values[0]) + 128] ^ x; } } // ------------------------------------------------------------------------ Function Dx = new XDecrypt(); // 用於解密進行擴散運算的函式X Function Dy = new YDecrypt(); // 用於解密進行擴散運算的函式Y /** * 解密密文,次方法只解密一組數據,X,Y的長度為N。 * * @param X * 密文X,對應加密後所輸出的X * @param Y * 密文Y,對應加密後所輸出的Y */ public void decrypt(byte[] X, byte[] Y) { int x = 0; int k = round - 1; for (int i = 0; i < round; i++, k--) { for (int y = 0; y < N; y++) { X[x] = (byte) Dx.call(X[x], Y[y], KX[k][y]); // KX[k][x] Y[y] = (byte) Dy.call(X[x], Y[y], KY[k][y]); x = (++x) % N; // x=(++x)&(N-1); and N&(N-1)=0 } x = (1 << i) % P; // x=(1<<i)&(P-1); and P&(P-1)=0 } } /** * 用於解密算法的函式X實現。 * * @author Angel * */ class XDecrypt implements Function { @Override public int call(int x, int y, int... values) { // values[0] is key return _S[(x ^ y) + 128] ^ values[0]; } } /** * 用於解密算法的函式Y實現。 * * @author Angel * */ class YDecrypt implements Function { @Override public int call(int x, int y, int... values) { // values[0] is key return _S[(x ^ y) + 128] ^ values[0]; } } // --------------------------------------------------------------------------- static interface Function { int call(int x, int y, int... values); } static void print(byte[] array) { for (byte b : array) { String s = Integer.toHexString(b & 0xff); if (s.length() == 1) { s = '0' + s; } System.out.print(s + ", "); } } // -------------------------------------------------------------------------- /** * 微變加密測試, 每次加密只需改變原輸入的一個元素(可以是密匙或者明文)。 * 不建議使用弱密匙,當所有密匙X的元素相等且所有密匙Y的元素都相等時為弱密匙,即: * <p> * KX[0]=KX[1]=KX[2]=...=KX[n-1]; KY[0]=KY[1]=KY[2]=...=KY[n-1]; * </P> */ public static void microChangeTest() { String line = "-------------------------------------------------------------------------------"; int length = 9; byte[] KX = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙X(不建議全部相等) byte[] KY = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙Y(不建議全部相等) byte[] MX = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文X byte[] MY = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文Y CryptoDemo demo = new CryptoDemo(length); for (int i = 0; i < 256; i++) { demo.init(KX, KY); // 初始化密匙 byte[] TX = MX.clone(); byte[] TY = MY.clone(); System.out.print("明 文:"); print(TX); print(TY); System.out.println(); demo.encrypt(TX, TY); System.out.print("加密後:"); print(TX); print(TY); System.out.println(); byte[] CX = TX.clone(); byte[] CY = TY.clone(); demo.decrypt(CX, CY); System.out.print("解密後:"); print(CX); print(CY); System.out.println(); MX[0]++; // 更改原數據 System.out.println(line); } } public static void main(String[] args) { microChangeTest(); }}
算法特性
加密模式
代碼實現
/** * <p> * 套用擴散算法進行數據加密和解密示例(以兩組為例,分別為X和Y)。 * </p> * * * @version 2.0 * @author Angel * */public class CryptoDemo { /* * S盒子, 任意0~255之間的不重複隨機整數。 S盒子是用於數據加密時函式所使用的數據,用以消除線性。 * S盒子的隨機性將會影響加密質量。 */ //@formatter:off public static final byte[] S = { (byte)0xd9, (byte)0x25, (byte)0x48, (byte)0x5c, (byte)0x55, (byte)0xa0, (byte)0x3c, (byte)0x94, (byte)0x83, (byte)0x36, (byte)0x11, (byte)0x74, (byte)0x69, (byte)0x2e, (byte)0x59, (byte)0x7b, (byte)0xd1, (byte)0x23, (byte)0x70, (byte)0x75, (byte)0x3a, (byte)0xbf, (byte)0x8c, (byte)0xd8, (byte)0x2f, (byte)0x34, (byte)0xb3, (byte)0x79, (byte)0xa4, (byte)0x27, (byte)0xa9, (byte)0x1d, (byte)0xb0, (byte)0xc8, (byte)0x38, (byte)0x8f, (byte)0x49, (byte)0x8b, (byte)0x89, (byte)0x0f, (byte)0x3b, (byte)0x92, (byte)0x33, (byte)0xcf, (byte)0xcd, (byte)0x1b, (byte)0x06, (byte)0xf0, (byte)0xfb, (byte)0x82, (byte)0xbb, (byte)0xc6, (byte)0xf2, (byte)0x07, (byte)0x4e, (byte)0xe8, (byte)0x77, (byte)0x6c, (byte)0x88, (byte)0x28, (byte)0xba, (byte)0xb9, (byte)0xe1, (byte)0xe9, (byte)0xd7, (byte)0x4b, (byte)0x81, (byte)0xde, (byte)0x08, (byte)0x0d, (byte)0xfc, (byte)0x03, (byte)0x87, (byte)0x56, (byte)0x14, (byte)0x0a, (byte)0x63, (byte)0x98, (byte)0x7a, (byte)0xf9, (byte)0x2c, (byte)0x7e, (byte)0x13, (byte)0x7d, (byte)0x04, (byte)0x01, (byte)0x9e, (byte)0xbc, (byte)0x41, (byte)0xdf, (byte)0x05, (byte)0x4f, (byte)0xfa, (byte)0x47, (byte)0x53, (byte)0xf8, (byte)0x46, (byte)0x52, (byte)0x8e, (byte)0x4a, (byte)0x76, (byte)0x09, (byte)0x1e, (byte)0xd2, (byte)0x2d, (byte)0x3e, (byte)0x61, (byte)0x5a, (byte)0x20, (byte)0x29, (byte)0xd0, (byte)0x16, (byte)0xb4, (byte)0x67, (byte)0xbd, (byte)0x50, (byte)0x60, (byte)0x35, (byte)0x19, (byte)0xd5, (byte)0xdd, (byte)0x8a, (byte)0xea, (byte)0xa5, (byte)0xac, (byte)0x1a, (byte)0x58, (byte)0x1f, (byte)0x5d, (byte)0x40, (byte)0x6d, (byte)0x86, (byte)0xeb, (byte)0x42, (byte)0x02, (byte)0x00, (byte)0xaa, (byte)0x9b, (byte)0xa1, (byte)0x7f, (byte)0xe4, (byte)0xb8, (byte)0xe6, (byte)0x21, (byte)0x68, (byte)0x12, (byte)0xd6, (byte)0x4d, (byte)0x4c, (byte)0x62, (byte)0xc0, (byte)0x66, (byte)0x0e, (byte)0x72, (byte)0x64, (byte)0xf6, (byte)0x80, (byte)0xb5, (byte)0xd4, (byte)0xf4, (byte)0x84, (byte)0x9d, (byte)0x73, (byte)0x51, (byte)0xe3, (byte)0x26, (byte)0xf3, (byte)0x1c, (byte)0x96, (byte)0xe2, (byte)0xcc, (byte)0x90, (byte)0xa3, (byte)0xc5, (byte)0xda, (byte)0xf7, (byte)0xad, (byte)0x6b, (byte)0x44, (byte)0x31, (byte)0xdb, (byte)0xa7, (byte)0xd3, (byte)0xfd, (byte)0xb2, (byte)0xcb, (byte)0xc7, (byte)0xf1, (byte)0x91, (byte)0x97, (byte)0xae, (byte)0xb6, (byte)0x45, (byte)0xc4, (byte)0xec, (byte)0xc2, (byte)0xce, (byte)0x18, (byte)0x3d, (byte)0xbe, (byte)0x7c, (byte)0xe5, (byte)0xb1, (byte)0xc9, (byte)0x0c, (byte)0x54, (byte)0x24, (byte)0x43, (byte)0x30, (byte)0x2a, (byte)0xb7, (byte)0xca, (byte)0x6e, (byte)0xc3, (byte)0x5b, (byte)0x9f, (byte)0x10, (byte)0xee, (byte)0x8d, (byte)0x95, (byte)0x32, (byte)0xc1, (byte)0x57, (byte)0x0b, (byte)0xed, (byte)0x99, (byte)0x5f, (byte)0xdc, (byte)0xaf, (byte)0x17, (byte)0xef, (byte)0xff, (byte)0x9c, (byte)0x9a, (byte)0x85, (byte)0x2b, (byte)0xab, (byte)0x5e, (byte)0xf5, (byte)0x6f, (byte)0xa6, (byte)0x39, (byte)0xa8, (byte)0x6a, (byte)0x3f, (byte)0x93, (byte)0x65, (byte)0xe0, (byte)0xfe, (byte)0x71, (byte)0x15, (byte)0x78, (byte)0x22, (byte)0xa2, (byte)0x37, (byte)0xe7, }; /* * 逆S盒子,設v是一個0~255之間的整數,_S必須滿足_S[S[v]] = v. */ public static final byte[] _S = { (byte)0x1c, (byte)0xc2, (byte)0xb1, (byte)0x88, (byte)0x20, (byte)0x6a, (byte)0x03, (byte)0xc8, (byte)0xba, (byte)0xa6, (byte)0xf9, (byte)0xa5, (byte)0x96, (byte)0x5a, (byte)0xe2, (byte)0xa3, (byte)0x2b, (byte)0x3c, (byte)0xa9, (byte)0x75, (byte)0x87, (byte)0x5b, (byte)0x28, (byte)0x3d, (byte)0xcd, (byte)0x61, (byte)0x69, (byte)0x09, (byte)0x68, (byte)0x21, (byte)0xd6, (byte)0x57, (byte)0x85, (byte)0x0a, (byte)0x7d, (byte)0x2c, (byte)0x9c, (byte)0xfb, (byte)0x70, (byte)0x35, (byte)0x72, (byte)0x9e, (byte)0x08, (byte)0x6c, (byte)0xfc, (byte)0x30, (byte)0x3e, (byte)0x64, (byte)0xa0, (byte)0x4a, (byte)0x38, (byte)0x9a, (byte)0xf0, (byte)0x1d, (byte)0x3f, (byte)0x52, (byte)0x0d, (byte)0xbd, (byte)0xbc, (byte)0xb2, (byte)0xd7, (byte)0xf2, (byte)0x47, (byte)0x95, (byte)0x16, (byte)0x5d, (byte)0x43, (byte)0x55, (byte)0x41, (byte)0x2d, (byte)0xb3, (byte)0x3a, (byte)0xa1, (byte)0x4b, (byte)0x53, (byte)0x39, (byte)0x2a, (byte)0xac, (byte)0x44, (byte)0xab, (byte)0xee, (byte)0x90, (byte)0xe7, (byte)0x36, (byte)0x1e, (byte)0xf7, (byte)0x12, (byte)0xc0, (byte)0x97, (byte)0x80, (byte)0x2e, (byte)0x34, (byte)0x63, (byte)0xf8, (byte)0xc3, (byte)0xd9, (byte)0x77, (byte)0xbe, (byte)0x29, (byte)0x24, (byte)0x0c, (byte)0x49, (byte)0x0e, (byte)0x7f, (byte)0xb7, (byte)0xbf, (byte)0xfa, (byte)0x04, (byte)0x42, (byte)0x60, (byte)0x59, (byte)0x66, (byte)0xaf, (byte)0x3b, (byte)0xb4, (byte)0x26, (byte)0x1f, (byte)0x6e, (byte)0x1b, (byte)0x2f, (byte)0xdf, (byte)0xcf, (byte)0xdc, (byte)0xb0, (byte)0xc6, (byte)0x37, (byte)0x78, (byte)0x67, (byte)0x07, (byte)0xd5, (byte)0x06, (byte)0xc7, (byte)0xd4, (byte)0xda, (byte)0xae, (byte)0xb5, (byte)0xc4, (byte)0xe5, (byte)0xcb, (byte)0x5f, (byte)0x4c, (byte)0xc5, (byte)0x18, (byte)0xa7, (byte)0x58, (byte)0x8a, (byte)0x11, (byte)0xd2, (byte)0xca, (byte)0x7a, (byte)0xef, (byte)0x65, (byte)0x45, (byte)0xf6, (byte)0xfd, (byte)0xad, (byte)0x27, (byte)0x9f, (byte)0xe6, (byte)0xff, (byte)0xec, (byte)0x0f, (byte)0x7c, (byte)0x91, (byte)0x4e, (byte)0x81, (byte)0x25, (byte)0x9d, (byte)0xbb, (byte)0xed, (byte)0x51, (byte)0x6b, (byte)0xd0, (byte)0xe8, (byte)0x8d, (byte)0x98, (byte)0x50, (byte)0x33, (byte)0x5c, (byte)0xaa, (byte)0x99, (byte)0xf5, (byte)0x89, (byte)0x7e, (byte)0xa2, (byte)0x71, (byte)0x94, (byte)0xa8, (byte)0x86, (byte)0x46, (byte)0xe9, (byte)0x74, (byte)0x01, (byte)0xd8, (byte)0x05, (byte)0x4f, (byte)0x32, (byte)0x40, (byte)0xe0, (byte)0xdd, (byte)0x82, (byte)0xa4, (byte)0xe3, (byte)0xc1, (byte)0x14, (byte)0x13, (byte)0xb6, (byte)0xdb, (byte)0xf3, (byte)0x23, (byte)0xe1, (byte)0xde, (byte)0x4d, (byte)0x84, (byte)0xc9, (byte)0x5e, (byte)0xfe, (byte)0x8e, (byte)0xeb, (byte)0x56, (byte)0x83, (byte)0x00, (byte)0x6d, (byte)0x62, (byte)0xf4, (byte)0xea, (byte)0x15, (byte)0xcc, (byte)0x1a, (byte)0x76, (byte)0x17, (byte)0xf1, (byte)0x10, (byte)0x8c, (byte)0x73, (byte)0x31, (byte)0xb9, (byte)0x02, (byte)0x54, (byte)0x6f, (byte)0x92, (byte)0x79, (byte)0x19, (byte)0x22, (byte)0x8b, (byte)0x93, (byte)0xe4, (byte)0xb8, (byte)0x7b, (byte)0x9b, (byte)0xce, (byte)0x8f, (byte)0x48, (byte)0xd3, (byte)0xd1, (byte)0x0b, }; static long LONG_TEN = 100000000000000L; int E = 2; // 額外的循環數量E int N; // 分組長度N int P; // 基於長度N的完美長度。 int round; // 用於加密的輪數(對應擴散階段的數量)。 byte[][] KX; // 用於加密的子密匙(X), 每一輪的密匙都不相同。 byte[][] KY; // 用於加密的子密匙(Y), 每一輪的密匙都不相同。 // @formatter:on public CryptoDemo(int keySize) { // keySize:byte N = keySize; int G = (int) Math.ceil(Math.log(N) / Math.log(2)); // 計算以2為底N的對數,並向上取整 P = 1 << G; // P=2的G次方 round = G + E; KX = new byte[round][]; KY = new byte[round][]; } /** * 生成子密匙, 通過擴散算法使得原密匙的每一個密匙都影響其它任何一個密匙。 * <p> * 每個周期完成後,將本周的輸出作為下一個周期的輸入再計運算元密匙。共需round個周期。 * </p> * * @param kx * 原始密匙X * @param ky * 原始密匙Y */ public void init(byte[] kx, byte[] ky) { for (int i = 0; i < round; i++) { init(kx, ky, i); } } Function FKx = new XKey(); // 用於生成子密匙的函式X Function FKy = new YKey(); // 用於生成子密匙的函式Y private void init(byte[] kx, byte[] ky, int index) { int l = 0; for (int i = 1; i <= round; i++) { for (int r = 0; r < N; r++) { ky[r] = (byte) (FKy.call(kx[l], ky[r]) & 255); kx[l] = (byte) (FKx.call(kx[l], ky[r]) & 255); l = (++l) % N; } l = P >> i; } KX[index] = kx.clone(); KY[index] = ky.clone(); } /** * 用於生成子密匙的函式X實現。 * * @author Angel * */ class XKey implements Function { int A = 11; int B = 21; int C = 31; @Override public int call(int x, int y, int... values) { return A * x * x + B * y + C; } } /** * 用於生成子密匙的函式Y實現。 * * @author Angel * */ class YKey implements Function { long C = 0x6180339887L; @Override public int call(int x, int y, int... values) { double a = Math.sin(x); double b = Math.cos(y); long v = (long) ((a + b) * LONG_TEN + C); return (int) (v & 0xffffffff); } } // ---------------------------------------------------------------------------- Function Ex = new XEncrypt(); // 用於加密進行擴散運算的函式X Function Ey = new YEncrypt(); // 用於加密進行擴散運算的函式Y /** * 加密明文。次方法只加密一組數據,X,Y的長度為N。 * * @param X * 明文X * @param Y * 明文Y */ public void encrypt(byte[] X, byte[] Y) { int x = 0; for (int i = 1, k = 0; i <= round; i++, k++) { for (int y = 0; y < N; y++) { Y[y] = (byte) Ey.call(X[x], Y[y], KY[k][y]); X[x] = (byte) Ex.call(X[x], Y[y], KX[k][y]); // KX[k][x] // 不建議使用%運算 // 當N&(N-1)=0時,可使用&運算,即N=2的j次方(j>0,且j為整數) x = (++x) % N; // x = (++x) & (N-1); } x = P >> i; } } /** * 用於加密算法的函式X實現。 * * @author Angel * */ class XEncrypt implements Function { /** * 由於java中byte的值域為[-128,127],因此需要將運算後的值加128以改變值域為[0,255](余同)。 * * <p> * 此處為行方便,特將key以其他參數的第0位傳入(余同)。 * </p> */ @Override public int call(int x, int y, int... values) { // values[0] is key return S[(x ^ values[0]) + 128] ^ y; } } /** * 用於加密算法的函式Y實現。 * * @author Angel * */ class YEncrypt implements Function { @Override public int call(int x, int y, int... values) { // values[0] is key return S[(y ^ values[0]) + 128] ^ x; } } // ------------------------------------------------------------------------ Function Dx = new XDecrypt(); // 用於解密進行擴散運算的函式X Function Dy = new YDecrypt(); // 用於解密進行擴散運算的函式Y /** * 解密密文,次方法只解密一組數據,X,Y的長度為N。 * * @param X * 密文X,對應加密後所輸出的X * @param Y * 密文Y,對應加密後所輸出的Y */ public void decrypt(byte[] X, byte[] Y) { int x = 0; int k = round - 1; for (int i = 0; i < round; i++, k--) { for (int y = 0; y < N; y++) { X[x] = (byte) Dx.call(X[x], Y[y], KX[k][y]); // KX[k][x] Y[y] = (byte) Dy.call(X[x], Y[y], KY[k][y]); x = (++x) % N; // x=(++x)&(N-1); and N&(N-1)=0 } x = (1 << i) % P; // x=(1<<i)&(P-1); and P&(P-1)=0 } } /** * 用於解密算法的函式X實現。 * * @author Angel * */ class XDecrypt implements Function { @Override public int call(int x, int y, int... values) { // values[0] is key return _S[(x ^ y) + 128] ^ values[0]; } } /** * 用於解密算法的函式Y實現。 * * @author Angel * */ class YDecrypt implements Function { @Override public int call(int x, int y, int... values) { // values[0] is key return _S[(x ^ y) + 128] ^ values[0]; } } // --------------------------------------------------------------------------- static interface Function { int call(int x, int y, int... values); } static void print(byte[] array) { for (byte b : array) { String s = Integer.toHexString(b & 0xff); if (s.length() == 1) { s = '0' + s; } System.out.print(s + ", "); } } // -------------------------------------------------------------------------- /** * 微變加密測試, 每次加密只需改變原輸入的一個元素(可以是密匙或者明文)。 * 不建議使用弱密匙,當所有密匙X的元素相等且所有密匙Y的元素都相等時為弱密匙,即: * <p> * KX[0]=KX[1]=KX[2]=...=KX[n-1]; KY[0]=KY[1]=KY[2]=...=KY[n-1]; * </P> */ public static void microChangeTest() { String line = "-------------------------------------------------------------------------------"; int length = 9; byte[] KX = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙X(不建議全部相等) byte[] KY = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙Y(不建議全部相等) byte[] MX = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文X byte[] MY = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文Y CryptoDemo demo = new CryptoDemo(length); for (int i = 0; i < 256; i++) { demo.init(KX, KY); // 初始化密匙 byte[] TX = MX.clone(); byte[] TY = MY.clone(); System.out.print("明 文:"); print(TX); print(TY); System.out.println(); demo.encrypt(TX, TY); System.out.print("加密後:"); print(TX); print(TY); System.out.println(); byte[] CX = TX.clone(); byte[] CY = TY.clone(); demo.decrypt(CX, CY); System.out.print("解密後:"); print(CX); print(CY); System.out.println(); MX[0]++; // 更改原數據 System.out.println(line); } } public static void main(String[] args) { microChangeTest(); }}