AES算法重点详解和实现


可以看到,在原始数据长度为16的整数倍时,假如原始数据长度等于16*n,则使用NoPadding时加密后数据长度等于16*n,其它情况下加密数据长度等于16*(n+1)。在不足16的整数倍的情况下,假如原始数据长度等于16*n+m[其中m小于16],除了NoPadding填充之外的任何方式,加密数据长度都等于16*(n+1);NoPadding填充情况下,CBC、ECB和PCBC三种模式是不支持的,CFB、OFB两种模式下则加密数据长度等于原始数据长度。


下面举例演示各个填充方式:

NoPadding: 不填充

PKCS5Padding: 填充字符串由一个字节序列组成,每个字节填充该字节序列的长度,假定数据长度为9,则需要填充的长度为16 - 9 = 7,数据等于 FF FF FF FF FF FF FF FF FF, 填充后数据为FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07

ISO10126Padding: 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节填充随机数据。假定数据长度为9,则需要填充的长度为16 - 9 = 7,数据等于 FF FF FF FF FF FF FF FF FF, 填充后数据为FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07


aes.h

/*************************************************************************** AES declarations **************************************************************************/#define AES_MAXROUNDS			14
#define AES_BLOCKSIZE           16
#define AES_IV_SIZE             16typedef struct aes_key_st 
{uint16_t rounds;uint16_t key_size;uint32_t ks[(AES_MAXROUNDS+1)*8];uint8_t iv[AES_IV_SIZE];
} AES_CTX;typedef enum
{AES_MODE_128,AES_MODE_256
} AES_MODE;void AES_set_key(AES_CTX *ctx, const uint8_t *key, const uint8_t *iv, AES_MODE mode);
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length);
void AES_cbc_decrypt(AES_CTX *ks, const uint8_t *in, uint8_t *out, int length);


aes.c
static const uint8_t aes_sbox[256] =
{0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16,
};/** AES is-box*/
static const uint8_t aes_isbox[256] = 
{0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};static const unsigned char Rcon[30]=
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,
};#define rot1(x) (((x) << 24) | ((x) >> 8))
#define rot2(x) (((x) << 16) | ((x) >> 16))
#define rot3(x) (((x) <<  8) | ((x) >> 24))/* * This cute trick does 4 'mul by two' at once.  Stolen from* Dr B. R. Gladman <brg@gladman.uk.net> but I'm sure the u-(u>>7) is* a standard graphics trick* The key to this is that we need to xor with 0x1b if the top bit is set.* a 1xxx xxxx   0xxx 0xxx First we mask the 7bit,* b 1000 0000   0000 0000 then we shift right by 7 putting the 7bit in 0bit,* c 0000 0001   0000 0000 we then subtract (c) from (b)* d 0111 1111   0000 0000 and now we and with our mask* e 0001 1011   0000 0000*/
#define mt  0x80808080
#define ml  0x7f7f7f7f
#define mh  0xfefefefe
#define mm  0x1b1b1b1b
#define mul2(x,t)	((t)=((x)&mt), \((((x)+(x))&mh)^(((t)-((t)>>7))&mm)))#define inv_mix_col(x,f2,f4,f8,f9) (\(f2)=mul2(x,f2), \(f4)=mul2(f2,f4), \(f8)=mul2(f4,f8), \(f9)=(x)^(f8), \(f8)=((f2)^(f4)^(f8)), \(f2)^=(f9), \(f4)^=(f9), \(f8)^=rot3(f2), \(f8)^=rot2(f4), \(f8)^rot1(f9))/** AES S-box*/
static const uint8_t aes_sbox[256] =
{0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16,
};/** AES is-box*/
static const uint8_t aes_isbox[256] = 
{0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};static const unsigned char Rcon[30]=
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,
};/* ----- static functions ----- */
static void AES_encrypt(const AES_CTX *ctx, uint32_t *data);
static void AES_decrypt(const AES_CTX *ctx, uint32_t *data);/* Perform doubling in Galois Field GF(2^8) using the irreducible polynomialx^8+x^4+x^3+x+1 */
static unsigned char AES_xtime(uint32_t x)
{return x = (x&0x80) ? (x<<1)^0x1b : x<<1;
}/*** Set up AES with the key/iv and cipher size.*/
void AES_set_key(AES_CTX *ctx, const uint8_t *key, const uint8_t *iv, AES_MODE mode)
{int i, ii;uint32_t *W, tmp, tmp2;const unsigned char *ip;int words;switch (mode){case AES_MODE_128:i = 10;words = 4;break;case AES_MODE_256:i = 14;words = 8;break;default:        /* fail silently */return;}ctx->rounds = i;ctx->key_size = words;W = ctx->ks;for (i = 0; i < words; i+=2){W[i+0]=	((uint32_t)key[ 0]<<24)|((uint32_t)key[ 1]<<16)|((uint32_t)key[ 2]<< 8)|((uint32_t)key[ 3]    );W[i+1]=	((uint32_t)key[ 4]<<24)|((uint32_t)key[ 5]<<16)|((uint32_t)key[ 6]<< 8)|((uint32_t)key[ 7]    );key += 8;}ip = Rcon;ii = 4 * (ctx->rounds+1);for (i = words; i<ii; i++){tmp = W[i-1];if ((i % words) == 0){tmp2 =(uint32_t)aes_sbox[(tmp    )&0xff]<< 8;tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<<16;tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<24;tmp2|=(uint32_t)aes_sbox[(tmp>>24)     ];tmp=tmp2^(((unsigned int)*ip)<<24);ip++;}if ((words == 8) && ((i % words) == 4)){tmp2 =(uint32_t)aes_sbox[(tmp    )&0xff]    ;tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<< 8;tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<16;tmp2|=(uint32_t)aes_sbox[(tmp>>24)     ]<<24;tmp=tmp2;}W[i]=W[i-words]^tmp;}/* copy the iv across */memcpy(ctx->iv, iv, 16);
}/*** Change a key for decryption.*/
void AES_convert_key(AES_CTX *ctx)
{int i;uint32_t *k,w,t1,t2,t3,t4;k = ctx->ks;k += 4;for (i= ctx->rounds*4; i > 4; i--){w= *k;w = inv_mix_col(w,t1,t2,t3,t4);*k++ =w;}
}/*** Encrypt a byte sequence (with a block size 16) using the AES cipher.*/
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{int i;uint32_t tin[4], tout[4], iv[4];memcpy(iv, ctx->iv, AES_IV_SIZE);for (i = 0; i < 4; i++)tout[i] = ntohl(iv[i]);for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE){uint32_t msg_32[4];uint32_t out_32[4];memcpy(msg_32, msg, AES_BLOCKSIZE);msg += AES_BLOCKSIZE;for (i = 0; i < 4; i++)tin[i] = ntohl(msg_32[i])^tout[i];AES_encrypt(ctx, tin);for (i = 0; i < 4; i++){tout[i] = tin[i]; out_32[i] = htonl(tout[i]);}memcpy(out, out_32, AES_BLOCKSIZE);out += AES_BLOCKSIZE;}for (i = 0; i < 4; i++)iv[i] = htonl(tout[i]);memcpy(ctx->iv, iv, AES_IV_SIZE);
}/*** Decrypt a byte sequence (with a block size 16) using the AES cipher.*/
void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{int i;uint32_t tin[4], xor[4], tout[4], data[4], iv[4];memcpy(iv, ctx->iv, AES_IV_SIZE);for (i = 0; i < 4; i++)xor[i] = ntohl(iv[i]);for (length -= 16; length >= 0; length -= 16){uint32_t msg_32[4];uint32_t out_32[4];memcpy(msg_32, msg, AES_BLOCKSIZE);msg += AES_BLOCKSIZE;for (i = 0; i < 4; i++){tin[i] = ntohl(msg_32[i]);data[i] = tin[i];}AES_decrypt(ctx, data);for (i = 0; i < 4; i++){tout[i] = data[i]^xor[i];xor[i] = tin[i];out_32[i] = htonl(tout[i]);}memcpy(out, out_32, AES_BLOCKSIZE);out += AES_BLOCKSIZE;}for (i = 0; i < 4; i++)iv[i] = htonl(xor[i]);memcpy(ctx->iv, iv, AES_IV_SIZE);
}/*** Encrypt a single block (16 bytes) of data*/
static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
{/* To make this code smaller, generate the sbox entries on the fly.* This will have a really heavy effect upon performance.*/uint32_t tmp[4];uint32_t tmp1, old_a0, a0, a1, a2, a3, row;int curr_rnd;int rounds = ctx->rounds; const uint32_t *k = ctx->ks;/* Pre-round key addition */for (row = 0; row < 4; row++)data[row] ^= *(k++);/* Encrypt one block. */for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++){/* Perform ByteSub and ShiftRow operations together */for (row = 0; row < 4; row++){a0 = (uint32_t)aes_sbox[(data[row%4]>>24)&0xFF];a1 = (uint32_t)aes_sbox[(data[(row+1)%4]>>16)&0xFF];a2 = (uint32_t)aes_sbox[(data[(row+2)%4]>>8)&0xFF]; a3 = (uint32_t)aes_sbox[(data[(row+3)%4])&0xFF];/* Perform MixColumn iff not last round */if (curr_rnd < (rounds - 1)){tmp1 = a0 ^ a1 ^ a2 ^ a3;old_a0 = a0;a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0);}tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3);}/* KeyAddition - note that it is vital that this loop is separate fromthe MixColumn operation, which must be atomic...*/ for (row = 0; row < 4; row++)data[row] = tmp[row] ^ *(k++);}
}/*** Decrypt a single block (16 bytes) of data*/
static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
{ uint32_t tmp[4];uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6;uint32_t a0, a1, a2, a3, row;int curr_rnd;int rounds = ctx->rounds;const uint32_t *k = ctx->ks + ((rounds+1)*4);/* pre-round key addition */for (row=4; row > 0;row--)data[row-1] ^= *(--k);/* Decrypt one block */for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++){/* Perform ByteSub and ShiftRow operations together */for (row = 4; row > 0; row--){a0 = aes_isbox[(data[(row+3)%4]>>24)&0xFF];a1 = aes_isbox[(data[(row+2)%4]>>16)&0xFF];a2 = aes_isbox[(data[(row+1)%4]>>8)&0xFF];a3 = aes_isbox[(data[row%4])&0xFF];/* Perform MixColumn iff not last round */if (curr_rnd<(rounds-1)){/* The MDS cofefficients (0x09, 0x0B, 0x0D, 0x0E)are quite large compared to encryption; this operation slows decryption down noticeably. */xt0 = AES_xtime(a0^a1);xt1 = AES_xtime(a1^a2);xt2 = AES_xtime(a2^a3);xt3 = AES_xtime(a3^a0);xt4 = AES_xtime(xt0^xt1);xt5 = AES_xtime(xt1^xt2);xt6 = AES_xtime(xt4^xt5);xt0 ^= a1^a2^a3^xt4^xt6;xt1 ^= a0^a2^a3^xt5^xt6;xt2 ^= a0^a1^a3^xt4^xt6;xt3 ^= a0^a1^a2^xt5^xt6;tmp[row-1] = ((xt0<<24)|(xt1<<16)|(xt2<<8)|xt3);}elsetmp[row-1] = ((a0<<24)|(a1<<16)|(a2<<8)|a3);}for (row = 4; row > 0; row--)data[row-1] = tmp[row-1] ^ *(--k);}
}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

protobuf流的反解析Message

0x01 protobuf的基本概念 protobuf通过定义".proto"文件来描述数据的结构。.proto文件中用"Message"所表示所需要序列化的数据的格式。Message由field组成&#xff0c;Field类似JAVA或者C中成员变量&#xff0c;通常一个field的定义包含修饰符、类型、名称…

勒索病毒傀儡进程脱壳

样本是&#xff1a;wallet勒索病毒 环境&#xff1a;虚拟机VMWARE win7 32位 工具&#xff1a;OD&#xff0c;winhex 初次拿到样本&#xff0c;先用火绒剑工具监控下病毒样本的流程&#xff0c;可以看到有一个自创建进程的行为。 我们等找到OEP后&#xff0c;在CreateProcessA下…

arm64动态链接库通过函数名获取函数偏移

基本思路是分析elf文件, 首先遍历节区头部Elf32_Shdr查看sh_type属性值&#xff0c;得到属性值为SHT_DYNSYM的节区。 其次通过名字遍历节区结点&#xff0c;找到类型为STT_FUNC并且名字与其相同的结点。 代码如下&#xff1a; static void * xmalloc(size_t size) {void *p…

arm32和arm64常用指令B BL BLX机器码计算

现在大部分手机cpu架构是ARM v7-A和ARMV8-A,&#xff0c;在ARM-v7A中常使用32位ARM指令集并且支持thumb指令集与arm的切换&#xff0c;而在ARMV8中使用的是64位ARM指令集且不再有thumb指令集状态的切换了。在调用函数时&#xff0c;会有常用的调用方式&#xff1a;BL和B&#x…

arm shellcode 编写详析1

在编写arm shell code 之前&#xff0c;先介绍下arm中r0-r15寄存器的主要用途&#xff1a; Register Alt. Name Usage r0 a1 First function argument Integer function result Scratch register r1 a2 Second function …

arm shellcode 编写详析2

前一篇中介绍了arm shellcode基本用法&#xff0c;现在涉及到arm和thumb状态 在前一篇中默认为arm32模式&#xff1a; text:00008074 ; Segment type: Pure code .text:00008074 AREA .text, CODE .text:00008074 ; ORG 0x8074 .text:0000807…

openssl c++实现bouncycastle中AES加解密

0x01 为什么要用bouncycastle 先说说JCE&#xff08;Java Cryptography Extension&#xff09;是一组包&#xff0c;它们提供用于加密、密钥生成和协商以及 Message Authentication Code&#xff08;MAC&#xff09;算法的框架和实现。 它提供对对称、不对称、块和流密码的加密…

zlib数据格式及解压缩实现

0x01 zlib和其他压缩的魔术头 一般来说压缩文件都有个魔术头&#xff0c;用于区分不同的压缩文件对应不同的解压缩算法。 7z文件: 00000000 37 7A BC AF 27 1C 00 03 CD F7 CC 2E 66 6A 33 00 7z集 枉?fj3 tar.xz文件 00000000 FD 37 7A 58 5A 00 00 04 E6 D6 B4 …

python3 Crypto环境

前言 最开始想尝试在windows下面安装python3.6&#xff0c;虽然python安装成功&#xff0c;但在安装Cryto模块用pip3 install pycrypto老是会报错。老夫搞了半天&#xff0c;最终决定在linux下面去做。 以下流程限于linux系统&#xff1a; 0x00 安装python apt-get install p…

win10用Eclipse+OpenJTag对S3C2440开发板进行动态调试

0 背景在S3C2400开发板裸板调试程序中&#xff0c;常用调试手段有三种&#xff1a;点灯法&#xff0c;串口打印&#xff0c;OpenOCD。OpenOCD又分命令行和图形界面(Eclipse)。点灯发和串口打印调试效率都很低&#xff0c;若能掌握第三种调试方法&#xff0c;会让开发过程变得高…

无源码情况下动态调试混淆的java程序

逆向工程JAVA通常是非常简单的&#xff0c;因为优秀的JAVA二进制反编译器已经存在多年。类似于jd-gui工具和恢复java二进制文件源代码功能也做的非常出色的。在这种情况下我们需要动态调试java反编译java程序的情况下&#xff0c;可以从反编译导出然后导入java IDE如Eclipse作为…

mdb access2000 中文密码破解

access数据库破解工具很多&#xff0c;密码能不用费多大功夫就能破解出来&#xff0c;但是对于包含特殊字符包括中文字符的密码&#xff0c;就算破解出来后想通过数据库工具查看&#xff0c;复制粘贴到密码输入框实际都起不了作用 已迁移到&#xff1a;分享最前沿的安全信息-a…

OpenJTAG调试S3C2440裸板程序

0x00 懵逼当你写好的初始化代码head.S和链接脚本uart.lds共同编译出来的*.bin&#xff0c;烧录到NandFlash中的时候&#xff0c;发现串口输出一片空白&#xff0c;这时你的想法是什么&#xff0c;砸电脑还是干点其他有用的事&#xff1f;还是老实的搭建调试环境吧&#xff0c;上…

APK逆向之静态分析篇

0x00 APK包结构0x01 APK反编译-apktool啰嗦一句&#xff0c;反编译之前配置好java环境&#xff0c;具体JDK安装过程&#xff0c;请参照之前的文章。下载最新版本的apktool.jar&#xff0c;并在当前目录下编辑脚本apktool.bat&#xff0c;内容如下&#xff1a; echo off set PAT…

S3C2440 lds链接脚本解析

1. SECTIONS到底意味着什么在一个裸版程序里面含有*.lds文件&#xff0c;而lds文件意味着如果你的程序烧录在nandflash&#xff0c;那在nandflash的内存将根据lds文件指定偏移来分布&#xff0c;下面从不同场景来解释SECTIONS的内容。2. 小于4K程序若程序小于4K&#xff0c;那…

安装qt5.9.5 windows环境

下载&#xff1a;用国外链接下载慢&#xff0c;还是乖乖用国内链接地址吧&#xff0c;我这里5.9.5http://mirrors.ustc.edu.cn/qtproject/archive/qt/5.9/5.9.5/qt-opensource-windows-x86-5.9.5.exe。安装&#xff1a; 在安装的时候需要创建qt账号&#xff0c;然后根据你的vis…

qt在visual studio 2015下的使用

创建工程&#xff1a; 打开visual studio&#xff0c;按上一篇文章的方式创建新工程QtGuiApplication1&#xff0c;默认我们可以看到里面会出现QtGuiApplication1这个类是继承于QMainWindow这个类的。在创建过程中注意下图选项&#xff1a;有三个对象分别是QMainwindow&#xf…

qt 收缩窗体

效果图&#xff1a;功能拆分图&#xff1a;代码&#xff1a; QtStubOption.cpp QtSubOption::QtSubOption(QWidget *parent): QLabel(parent) {ui.setupUi(this);m_GuiShow SHOWGUI;setMouseTracking(true);m_PicStatus[SHOWGUI] ":/QtGuiApplication3/tile";m_Pic…

Android的ELF文件重定位详解,包括64位

0x01 引言 ELF文件格式&#xff0c;主要基于两种&#xff0c;一种是基于链接视图&#xff0c;链接视图即是基于节(Section)来进行解析&#xff0c;一种是基于执行视图&#xff0c;执行视图即是基于段(Segment)来进行解析。前一种是用于静态分析的时候&#xff0c;譬如IDA载入。…

lua安全之关于lua扩展第三方库

android lua require第三方扩展库有三种方式&#xff1a; 1. 用c实现独立的lua模块作为android的第三方动态库来引入&#xff0c;优点是lua扩展库独立方便更新替换&#xff0c;缺点是需要修改虚拟机&#xff0c;开启宏支持dlopen调用的方式&#xff0c;并且还需要设置lua寻找so…