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
    🙂


Anmelden zum Antworten