AES-256 gesucht
-
Hallo,
Woher bekomme ich eine AES256-Verschlüsselung?
Im JCE ist sie nur bis 128 bits eingestellt bzw. lässt sich nur sehr schwer umkonfiguruieren. Gibt es einen open-Source von AES-256 für Java?
-
import java.util.Arrays; public class MyAES256 { private final byte[] key = new byte[32]; private final byte[] enckey = new byte[32]; private final byte[] deckey = new byte[32]; private final byte[] sbox = { 99, 124, 119, 123, -14, 107, 111, -59, 48, 1, 103, 43, -2, -41, -85, 118, -54, -126, -55, 125, -6, 89, 71, -16, -83, -44, -94, -81, -100, -92, 114, -64, -73, -3, -109, 38, 54, 63, -9, -52, 52, -91, -27, -15, 113, -40, 49, 21, 4, -57, 35, -61, 24, -106, 5, -102, 7, 18, -128, -30, -21, 39, -78, 117, 9, -125, 44, 26, 27, 110, 90, -96, 82, 59, -42, -77, 41, -29, 47, -124, 83, -47, 0, -19, 32, -4, -79, 91, 106, -53, -66, 57, 74, 76, 88, -49, -48, -17, -86, -5, 67, 77, 51, -123, 69, -7, 2, 127, 80, 60, -97, -88, 81, -93, 64, -113, -110, -99, 56, -11, -68, -74, -38, 33, 16, -1, -13, -46, -51, 12, 19, -20, 95, -105, 68, 23, -60, -89, 126, 61, 100, 93, 25, 115, 96, -127, 79, -36, 34, 42, -112, -120, 70, -18, -72, 20, -34, 94, 11, -37, -32, 50, 58, 10, 73, 6, 36, 92, -62, -45, -84, 98, -111, -107, -28, 121, -25, -56, 55, 109, -115, -43, 78, -87, 108, 86, -12, -22, 101, 122, -82, 8, -70, 120, 37, 46, 28, -90, -76, -58, -24, -35, 116, 31, 75, -67, -117, -118, 112, 62, -75, 102, 72, 3, -10, 14, 97, 53, 87, -71, -122, -63, 29, -98, -31, -8, -104, 17, 105, -39, -114, -108, -101, 30, -121, -23, -50, 85, 40, -33, -116, -95, -119, 13, -65, -26, 66, 104, 65, -103, 45, 15, -80, 84, -69, 22 }; private final int xtime[] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, -229, -231, -225, -227, -237, -239, -233, -235, -245, -247, -241, -243, -253, -255, -249, -251, -197, -199, -193, -195, -205, -207, -201, -203, -213, -215, -209, -211, -221, -223, -217, -219, -165, -167, -161, -163, -173, -175, -169, -171, -181, -183, -177, -179, -189, -191, -185, -187, -133, -135, -129, -131, -141, -143, -137, -139, -149, -151, -145, -147, -157, -159, -153, -155, -101, -103, -97, -99, -109, -111, -105, -107, -117, -119, -113, -115, -125, -127, -121, -123, -69, -71, -65, -67, -77, -79, -73, -75, -85, -87, -81, -83, -93, -95, -89, -91, -37, -39, -33, -35, -45, -47, -41, -43, -53, -55, -49, -51, -61, -63, -57, -59, -5, -7, -1, -3, -13, -15, -9, -11, -21, -23, -17, -19, -29, -31, -25, -27 }; private void addRoundKey(byte[] buf, byte[] key, int keyoffset) { int i = 16; while (i-- != 0) { buf[i] ^= key[i + keyoffset]; } } private void addRoundKeyAndCopy(byte[] buf, byte[] key, byte[] cpk) { int i = 16; while (i-- != 0) { buf[i] ^= (cpk[i] = key[i]); cpk[16 + i] = key[16 + i]; } } private void shiftRows(byte[] buf) { byte i; i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i; i = buf[10]; buf[10] = buf[2]; buf[2] = i; i = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = i; i = buf[14]; buf[14] = buf[6]; buf[6] = i; } private void inverseShiftRows(byte[] buf) { byte i; i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i; i = buf[2]; buf[2] = buf[10]; buf[10] = i; i = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = i; i = buf[6]; buf[6] = buf[14]; buf[14] = i; } private void mixColumns(byte[] buf) { int i; int a, b, c, d, e; for (i = 0; i < 16; i += 4) { a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3]; e = a ^ b ^ c ^ d; buf[i] ^= e ^ xtime[(a ^ b) & 0xff]; buf[i + 1] ^= e ^ xtime[(b ^ c) & 0xff]; buf[i + 2] ^= e ^ xtime[(c ^ d) & 0xff]; buf[i + 3] ^= e ^ xtime[(d ^ a) & 0xff]; } } private int expandEncryptionKey(byte[] k, int rc) { int i; k[0] ^= sbox[k[29] & 0xff] ^ rc; k[1] ^= sbox[k[30] & 0xff]; k[2] ^= sbox[k[31] & 0xff]; k[3] ^= sbox[k[28] & 0xff]; rc = rc << 1 ^ ((rc & 0xff) >>> 7 & 1) * 0x1b; for (i = 4; i < 16; i += 4) { k[i] ^= k[i - 4]; k[i + 1] ^= k[i - 3]; k[i + 2] ^= k[i - 2]; k[i + 3] ^= k[i - 1]; } k[16] ^= sbox[k[12] & 0xff]; k[17] ^= sbox[k[13] & 0xff]; k[18] ^= sbox[k[14] & 0xff]; k[19] ^= sbox[k[15] & 0xff]; for (i = 20; i < 32; i += 4) { k[i] ^= k[i - 4]; k[i + 1] ^= k[i - 3]; k[i + 2] ^= k[i - 2]; k[i + 3] ^= k[i - 1]; } return rc; } /** * Call this first * @param k Key used for en- and decryption. Must be 32 byte long */ void init(byte[] k) { int rcon = 1; int i; for (i = 0; i < key.length; i++) { enckey[i] = deckey[i] = k[i]; } for (i = 8; --i != 0; ) { rcon = expandEncryptionKey(deckey, rcon); } } /** * Encrypts a chunk of 16 byte * @param buf Points to the beginning of the block that should be encrypted */ void encrypt(byte[] buf) { int i; int rcon = 1; addRoundKeyAndCopy(buf, enckey, key); for (i = 1; i < 14; ++i) { int i1 = 16; while (i1-- != 0) { buf[i1] = sbox[buf[i1] & 0xff]; } shiftRows(buf); mixColumns(buf); if ((i & 1) == 1) { addRoundKey(buf, key, 16); } else { rcon = expandEncryptionKey(key, rcon); addRoundKey(buf, key, 0); } } int i1 = 16; while (i1-- != 0) { buf[i1] = sbox[buf[i1] & 0xff]; } shiftRows(buf); expandEncryptionKey(key, rcon); addRoundKey(buf, key, 0); } /** * Decrypts a chunk of 16 bytes * Much more complex than encrypt due to inlining * @param buf Points to the beginning of the block that should be decrypted */ void decrypt(byte[] buf) { int i = 16, i1; int rcon = 0x80; addRoundKeyAndCopy(buf, deckey, key); inverseShiftRows(buf); while (i-- != 0) { byte j = 0; do { if (sbox[(int)j & 0xff] == buf[i]) { buf[i] = j; break; } } while (++j != 0); } for (i = 14; (--i) != 0; ) { if ((i & 1) == 1) { for (i1 = 28; i1 > 16; i1 -= 4) { key[i1] ^= key[i1 - 4]; key[i1 + 1] ^= key[i1 - 3]; key[i1 + 2] ^= key[i1 - 2]; key[i1 + 3] ^= key[i1 - 1]; } key[16] ^= sbox[key[12] & 0xff]; key[17] ^= sbox[key[13] & 0xff]; key[18] ^= sbox[key[14] & 0xff]; key[19] ^= sbox[key[15] & 0xff]; for (i1 = 12; i1 > 0; i1 -= 4) { key[i1] ^= key[i1 - 4]; key[i1 + 1] ^= key[i1 - 3]; key[i1 + 2] ^= key[i1 - 2]; key[i1 + 3] ^= key[i1 - 1]; } if ((rcon & 1) == 1) { rcon = (rcon & 0xff) >>> 1 ^ 0x8d; } else { rcon = (rcon & 0xff) >>> 1; } key[0] ^= sbox[key[29] & 0xff] ^ rcon; key[1] ^= sbox[key[30] & 0xff]; key[2] ^= sbox[key[31] & 0xff]; key[3] ^= sbox[key[28] & 0xff]; addRoundKey(buf, key, 16); } else { addRoundKey(buf, key, 0); } for (i1 = 0; i1 < 16; i1 += 4) { int a = buf[i1]; int b = buf[i1 + 1]; int c = buf[i1 + 2]; int d = buf[i1 + 3]; int e = a ^ b ^ c ^ d; int z = xtime[e & 0xff]; int x = e ^ xtime[xtime[(z ^ a ^ c) & 0xff] & 0xff]; int y = e ^ xtime[xtime[(z ^ b ^ d) & 0xff] & 0xff]; buf[i1] ^= x ^ xtime[(a ^ b) & 0xff]; buf[i1 + 1] ^= y ^ xtime[(b ^ c) & 0xff]; buf[i1 + 2] ^= x ^ xtime[(c ^ d) & 0xff]; buf[i1 + 3] ^= y ^ xtime[(d ^ a) & 0xff]; } inverseShiftRows(buf); i1 = 16; while (i1-- != 0) { byte j = 0; do { if (sbox[j & 0xff] == buf[i1]) { buf[i1] = j; break; } } while (++j != 0); } } addRoundKey(buf, key, 0); } /** * A little test routine * Encrypts 1...16 and then decrypts them */ static void test() { byte[] test1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; byte[] test2 = { -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16 }; System.out.println("before: " + Arrays.toString(test1)); System.out.println("before: " + Arrays.toString(test2)); MyAES256 aes = new MyAES256(); byte key[] = new byte[32]; for (int s = 0; s < key.length; s++) { key[s] = (byte)(Math.random() * 256); } System.out.println("key: " + Arrays.toString(key)); aes.init(key); aes.encrypt(test1); System.out.println("after: " + Arrays.toString(test1)); aes.encrypt(test2); System.out.println("after: " + Arrays.toString(test2)); aes.decrypt(test1); System.out.println("decrypted: " + Arrays.toString(test1)); aes.decrypt(test2); System.out.println("decrypted: " + Arrays.toString(test2)); } }
^^ viel spass