⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aescipher.java

📁 java高级使用教程 全书一共分六章
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	    alog[( a + log[b[3] & 0xFF] ) % 255] & 0xFF : 0;
        return a0 << 24 | a1 << 16 | a2 << 8 | a3;
	}

    /// Return the number of rounds for a given Rijndael's key and block sizes.
    // @param keySize    The size of the user key material in bytes.
    // @param blockSize  The desired block size in bytes.
    // @return The number of rounds for a given Rijndael's key and block sizes.
    public static int getRounds( int keySize, int blockSize )
	{
        switch ( keySize )
	    {
	    case 16:
            return blockSize == 16 ? 10 : ( blockSize == 24 ? 12 : 14 );
	    case 24:
            return blockSize != 32 ? 12 : 14;
	    default: // 32 bytes = 256 bits
            return 14;
	    }
	}


    // Constructors.

    // Constructor, string key.
    public AesCipher( String keyStr )
	{
	super( KEY_SIZE, BLOCK_SIZE );
	setKey( keyStr );
	}

    // Constructor, byte-array key.
    public AesCipher( byte[] key )
	{
	super( KEY_SIZE, BLOCK_SIZE );
	setKey( key );
	}


    // Key routines.

    private int ROUNDS = getRounds( KEY_SIZE, BLOCK_SIZE );
    private int BC = BLOCK_SIZE / 4;
    private int[][] Ke = new int[ROUNDS + 1][BC];  // encryption round keys
    private int[][] Kd = new int[ROUNDS + 1][BC];  // decryption round keys

    /// Set the key.
    public void setKey( byte[] key )
	{
        if ( key.length != KEY_SIZE )
	    throw new RuntimeException("Incorrect key length");
        int ROUND_KEY_COUNT = ( ROUNDS + 1 ) * BC;
        int KC = KEY_SIZE / 4;
        int[] tk = new int[KC];
        int i, j;

        // Copy user material bytes into temporary ints.
        for ( i = 0, j = 0; i < KC; )
            tk[i++] = ( key[j++] & 0xFF ) << 24 |
                      ( key[j++] & 0xFF ) << 16 |
                      ( key[j++] & 0xFF ) <<  8 |
                      ( key[j++] & 0xFF );
        // Copy values into round key arrays.
        int t = 0;
        for ( j = 0; ( j < KC ) && ( t < ROUND_KEY_COUNT ); ++j, ++t )
	    {
            Ke[t / BC][t % BC] = tk[j];
            Kd[ROUNDS - ( t / BC )][t % BC] = tk[j];
	    }
        int tt, rconpointer = 0;
        while ( t < ROUND_KEY_COUNT )
	    {
            // Extrapolate using phi (the round key evolution function).
            tt = tk[KC - 1];
            tk[0] ^= ( S[( tt >>> 16 ) & 0xFF] & 0xFF ) << 24 ^
                     ( S[( tt >>>  8 ) & 0xFF] & 0xFF ) << 16 ^
                     ( S[  tt          & 0xFF] & 0xFF ) <<  8 ^
                     ( S[( tt >>> 24 ) & 0xFF] & 0xFF )       ^
                     ( rcon[rconpointer++]     & 0xFF ) << 24;
            if ( KC != 8 )
                for ( i = 1, j = 0; i < KC; )
		    tk[i++] ^= tk[j++];
            else
		{
                for ( i = 1, j = 0; i < KC / 2; )
		    tk[i++] ^= tk[j++];
                tt = tk[KC / 2 - 1];
                tk[KC / 2] ^= ( S[  tt          & 0xFF] & 0xFF )       ^
                              ( S[( tt >>>  8 ) & 0xFF] & 0xFF ) <<  8 ^
                              ( S[( tt >>> 16 ) & 0xFF] & 0xFF ) << 16 ^
                              ( S[( tt >>> 24 ) & 0xFF] & 0xFF ) << 24;
                for ( j = KC / 2, i = j + 1; i < KC; )
		    tk[i++] ^= tk[j++];
		}
            // Copy values into round key arrays.
            for ( j = 0; ( j < KC ) && ( t < ROUND_KEY_COUNT ); ++j, ++t )
		{
                Ke[t / BC][t % BC] = tk[j];
                Kd[ROUNDS - ( t / BC )][t % BC] = tk[j];
		}
	    }
        for ( int r = 1; r < ROUNDS; ++r )  // inverse MixColumn where needed
            for ( j = 0; j < BC; ++j )
		{
                tt = Kd[r][j];
                Kd[r][j] = U1[( tt >>> 24 ) & 0xFF] ^
                           U2[( tt >>> 16 ) & 0xFF] ^
                           U3[( tt >>>  8 ) & 0xFF] ^
                           U4[  tt          & 0xFF];
		}
	}


    // Block encryption routines.

    private int[] tempInts = new int[8];


    /// Encrypt a block.
    public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff )
	{
        int SC = ( BC == 4 ? 0 : ( BC == 6 ? 1 : 2 ) );
        int s1 = shifts[SC][1][0];
        int s2 = shifts[SC][2][0];
        int s3 = shifts[SC][3][0];
        int[] a = new int[BC];
        int[] t = new int[BC];	// temporary work array
        int i;
        int tt;

        for ( i = 0; i < BC; ++i )	// plaintext to ints + key
            t[i] = ( ( clearText[clearOff++] & 0xFF ) << 24 |
                     ( clearText[clearOff++] & 0xFF ) << 16 |
                     ( clearText[clearOff++] & 0xFF ) <<  8 |
                     ( clearText[clearOff++] & 0xFF )        ) ^ Ke[0][i];
	// Apply round transforms.
        for ( int r = 1; r < ROUNDS; ++r )
	    {
            for ( i = 0; i < BC; ++i )
                a[i] = ( T1[( t[  i            ] >>> 24 ) & 0xFF] ^
                         T2[( t[( i + s1 ) % BC] >>> 16 ) & 0xFF] ^
                         T3[( t[( i + s2 ) % BC] >>>  8 ) & 0xFF] ^
                         T4[  t[( i + s3 ) % BC]          & 0xFF]  ) ^ Ke[r][i];
            System.arraycopy( a, 0, t, 0, BC );
	    }
	// Last round is special.
        for ( i = 0; i < BC; ++i )
	    {
            tt = Ke[ROUNDS][i];
            cipherText[cipherOff++] =
		(byte) ( S[( t[  i            ] >>> 24 ) & 0xFF] ^
			 ( tt >>> 24 ) );
            cipherText[cipherOff++] =
		(byte) ( S[( t[( i + s1 ) % BC] >>> 16 ) & 0xFF] ^
			 ( tt >>> 16 ) );
            cipherText[cipherOff++] =
		(byte) ( S[( t[( i + s2 ) % BC] >>>  8 ) & 0xFF] ^
			 ( tt >>>  8 ) );
            cipherText[cipherOff++] =
		(byte) ( S[  t[( i + s3 ) % BC]          & 0xFF] ^
			   tt          );
	    }
	}


    /// Decrypt a block.
    public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff )
	{
        int SC = ( BC == 4 ? 0 : ( BC == 6 ? 1 : 2 ) );
        int s1 = shifts[SC][1][1];
        int s2 = shifts[SC][2][1];
        int s3 = shifts[SC][3][1];
        int[] a = new int[BC];
        int[] t = new int[BC];	// temporary work array
        int i;
        int tt;

        for ( i = 0; i < BC; ++i )	// ciphertext to ints + key
            t[i] = ( ( cipherText[cipherOff++] & 0xFF ) << 24 |
                     ( cipherText[cipherOff++] & 0xFF ) << 16 |
                     ( cipherText[cipherOff++] & 0xFF ) <<  8 |
                     ( cipherText[cipherOff++] & 0xFF )        ) ^ Kd[0][i];
	// Apply round transforms.
        for ( int r = 1; r < ROUNDS; ++r )
	    { 
            for ( i = 0; i < BC; ++i )
                a[i] = ( T5[( t[  i            ] >>> 24 ) & 0xFF] ^
                         T6[( t[( i + s1 ) % BC] >>> 16 ) & 0xFF] ^
                         T7[( t[( i + s2 ) % BC] >>>  8 ) & 0xFF] ^
                         T8[  t[( i + s3 ) % BC]          & 0xFF]  ) ^ Kd[r][i];
            System.arraycopy( a, 0, t, 0, BC );
	    }
	// Last round is special.
        for ( i = 0; i < BC; ++i )
	    {
            tt = Kd[ROUNDS][i];
            clearText[clearOff++] =
		(byte) ( Si[( t[  i            ] >>> 24 ) & 0xFF] ^
			 ( tt >>> 24 ) );
            clearText[clearOff++] =
		(byte) ( Si[( t[( i + s1 ) % BC] >>> 16 ) & 0xFF] ^
			 ( tt >>> 16 ) );
            clearText[clearOff++] =
		(byte) ( Si[( t[( i + s2 ) % BC] >>>  8 ) & 0xFF] ^
			 ( tt >>>  8 ) );
            clearText[clearOff++] =
		(byte) ( Si[  t[( i + s3 ) % BC]          & 0xFF] ^
			   tt          );
	    }
	}


    /// Test routine.
    public static void main( String[] args )
	{
	byte[] cipherText = new byte[16];
	byte[] decipherText = new byte[16];

	BlockCipher aesa = new AesCipher( "0123456789" );
	byte[] clearText1 = {
	    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
	    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
	    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
	    (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
	System.out.println( "cleartext: " + toStringBlock( clearText1 ) );
	aesa.encrypt( clearText1, cipherText );
	System.out.println( "encrypted: " + toStringBlock( cipherText ) );
	aesa.decrypt( cipherText, decipherText );
	System.out.println( "decrypted: " + toStringBlock( decipherText ) );

	System.out.println();

	BlockCipher aesb = new AesCipher( "abcdefghijklmnopqrstuvwxyz" );
	byte[] clearText2 = {
	    (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
	    (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
	    (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b,
	    (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f };
	System.out.println( "cleartext: " + toStringBlock( clearText2 ) );
	aesb.encrypt( clearText2, cipherText );
	System.out.println( "encrypted: " + toStringBlock( cipherText ) );
	aesb.decrypt( cipherText, decipherText );
	System.out.println( "decrypted: " + toStringBlock( decipherText ) );
	}

    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -