📄 aescipher.java
字号:
// AesCipher - the AES encryption method
//
// Before being selected as the Advanced Encryption Standard this was
// known as Rijndael, and was designed by Joan Daemen and Vincent Rijmen.
// Most of the algorithm code is copyright by them. A few modifications
// to the algorithm, and the surrounding glue, are:
//
// Copyright (C) 1996,2000 by Jef Poskanzer <jef@acme.com>.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Crypto;
import java.io.*;
/// The AES encryption method.
// <P>
// Before being selected as the Advanced Encryption Standard this was
// known as Rijndael, and was designed by Joan Daemen and Vincent Rijmen.
// <P>
// <A HREF="/resources/classes/Acme/Crypto/AesCipher.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see EncryptedOutputStream
// @see EncryptedInputStream
public class AesCipher extends BlockCipher
{
// Constants, variables, and auxillary routines.
// Key size in bytes. Valid values are 16, 24, and 32.
public static final int KEY_SIZE = 16;
// Block size in bytes. Valid values are 16, 24, and 32.
public static final int BLOCK_SIZE = 16;
private static final int[] alog = new int[256];
private static final int[] log = new int[256];
private static final byte[] S = new byte[256];
private static final byte[] Si = new byte[256];
private static final int[] T1 = new int[256];
private static final int[] T2 = new int[256];
private static final int[] T3 = new int[256];
private static final int[] T4 = new int[256];
private static final int[] T5 = new int[256];
private static final int[] T6 = new int[256];
private static final int[] T7 = new int[256];
private static final int[] T8 = new int[256];
private static final int[] U1 = new int[256];
private static final int[] U2 = new int[256];
private static final int[] U3 = new int[256];
private static final int[] U4 = new int[256];
private static final byte[] rcon = new byte[30];
static private final int[][][] shifts = new int[][][] {
{ { 0, 0 }, { 1, 3 }, { 2, 2 }, { 3, 1 } },
{ { 0, 0 }, { 1, 5 }, { 2, 4 }, { 3, 3 } },
{ { 0, 0 }, { 1, 7 }, { 3, 5 }, { 4, 4 } }
};
private static final char[] HEX_DIGITS = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
// Static initializer - to intialise S-boxes and T-boxes
static
{
int ROOT = 0x11B;
int i, j = 0;
// Produce log and alog tables, needed for multiplying in the
// field GF(2^m) (generator = 3).
alog[0] = 1;
for ( i = 1; i < 256; ++i )
{
j = ( alog[i - 1] << 1 ) ^ alog[i - 1];
if ( ( j & 0x100 ) != 0 )
j ^= ROOT;
alog[i] = j;
}
for ( i = 1; i < 255; ++i )
log[alog[i]] = i;
byte[][] A = new byte[][] {
{ 1, 1, 1, 1, 1, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 1, 0, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 1, 1, 1, 1 },
{ 1, 1, 0, 0, 0, 1, 1, 1 },
{ 1, 1, 1, 0, 0, 0, 1, 1 },
{ 1, 1, 1, 1, 0, 0, 0, 1 }
};
byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1 };
// Substitution box based on F^{-1}(x).
int t;
byte[][] box = new byte[256][8];
box[1][7] = 1;
for ( i = 2; i < 256; ++i )
{
j = alog[255 - log[i]];
for ( t = 0; t < 8; ++t )
box[i][t] = (byte) ( ( j >>> ( 7 - t ) ) & 0x01 );
}
// Affine transform: box[i] <- B + A*box[i].
byte[][] cox = new byte[256][8];
for ( i = 0; i < 256; ++i )
for ( t = 0; t < 8; ++t )
{
cox[i][t] = B[t];
for ( j = 0; j < 8; ++j )
cox[i][t] ^= A[t][j] * box[i][j];
}
// S-boxes and inverse S-boxes.
for ( i = 0; i < 256; ++i )
{
S[i] = (byte) ( cox[i][0] << 7 );
for ( t = 1; t < 8; ++t )
S[i] ^= cox[i][t] << ( 7 - t );
Si[S[i] & 0xFF] = (byte) i;
}
// T-boxes.
byte[][] G = new byte[][] {
{ 2, 1, 1, 3 },
{ 3, 2, 1, 1 },
{ 1, 3, 2, 1 },
{ 1, 1, 3, 2 }
};
byte[][] AA = new byte[4][8];
for ( i = 0; i < 4; ++i )
{
for ( j = 0; j < 4; ++j )
AA[i][j] = G[i][j];
AA[i][i + 4] = 1;
}
byte pivot, tmp;
byte[][] iG = new byte[4][4];
for ( i = 0; i < 4; ++i )
{
pivot = AA[i][i];
if ( pivot == 0 )
{
t = i + 1;
while ( ( AA[t][i] == 0 ) && ( t < 4 ) )
++t;
if ( t == 4 )
throw new RuntimeException("G matrix is not invertible");
else
{
for ( j = 0; j < 8; ++j )
{
tmp = AA[i][j];
AA[i][j] = AA[t][j];
AA[t][j] = (byte) tmp;
}
pivot = AA[i][i];
}
}
for ( j = 0; j < 8; ++j )
if (AA[i][j] != 0)
AA[i][j] = (byte)
alog[( 255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF] ) % 255];
for ( t = 0; t < 4; ++t )
if ( i != t )
{
for ( j = i+1; j < 8; ++j )
AA[t][j] ^= mul( AA[i][j], AA[t][i] );
AA[t][i] = 0;
}
}
for ( i = 0; i < 4; ++i )
for ( j = 0; j < 4; ++j )
iG[i][j] = AA[i][j + 4];
int s;
for ( t = 0; t < 256; ++t )
{
s = S[t];
T1[t] = mul4( s, G[0]) ;
T2[t] = mul4( s, G[1]) ;
T3[t] = mul4( s, G[2]) ;
T4[t] = mul4( s, G[3]) ;
s = Si[t];
T5[t] = mul4( s, iG[0] );
T6[t] = mul4( s, iG[1] );
T7[t] = mul4( s, iG[2] );
T8[t] = mul4( s, iG[3] );
U1[t] = mul4( t, iG[0] );
U2[t] = mul4( t, iG[1] );
U3[t] = mul4( t, iG[2] );
U4[t] = mul4( t, iG[3] );
}
// Round constants.
rcon[0] = 1;
int r = 1;
for ( t = 1; t < 30; )
rcon[t++] = (byte)( r = mul( 2, r ) );
}
/// Multiply two elements of GF(2^m).
static final int mul( int a, int b )
{
return ( a != 0 && b != 0 ) ?
alog[( log[a & 0xFF] + log[b & 0xFF] ) % 255] :
0;
}
/// Convenience method used in generating Transposition boxes.
static final int mul4( int a, byte[] b )
{
if ( a == 0 )
return 0;
a = log[a & 0xFF];
int a0 = ( b[0] != 0 ) ?
alog[( a + log[b[0] & 0xFF] ) % 255] & 0xFF : 0;
int a1 = ( b[1] != 0 ) ?
alog[( a + log[b[1] & 0xFF] ) % 255] & 0xFF : 0;
int a2 = ( b[2] != 0 ) ?
alog[( a + log[b[2] & 0xFF] ) % 255] & 0xFF : 0;
int a3 = ( b[3] != 0 ) ?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -