AES加密算法是对称加密算法(symmetric-key algorithm)的一种。对称加密就意味着加密,解密中使用的key是相同的。从实现的算法来看,在加密解密的过程中,不需要动态分配内存,算法比较简捷,对于嵌入式系统来说好处多多。
这里主要是针对128-bit的AES加密算法的分析与实现。
- 原理
请先看下面一段flash(来自http://www.formaestudio.com/rijndaelinspector/archivos/Rijndael_Animation_v4_eng.swf)
NOTE:
- 演示中的数值可能存在错误,具体请看:http://coolshell.cn/articles/3161.html#comment-114419
Key Schedule 这一步里面,Round key 2 的第三列错了。
23,a3,39,39 应该为 59,25,80,7a;前面的步骤出现过正确的值,可以对照。
- P3中的State表示的是明文,而Cipher key表示的是16字节(128-bit的密钥)
对于128-bit的加密算法来说, 16字节的Cipher key会通过Key Schedule扩展成176字节,具体的扩展方法请看:http://www.samiam.org/key-schedule.html, 当然在进行Key扩展时,会使用到:
a. S-box – https://en.wikipedia.org/wiki/Rijndael_S-box
b. Rcon – https://en.wikipedia.org/wiki/Rijndael_key_schedule
c. Finite field arithmetic – https://en.wikipedia.org/wiki/Finite_field_arithmetic#Rijndael.27s_finite_field
权威文档:http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
中文文档请看:http://www.cnblogs.com/luop/p/4334160.html
- 加密算法C语言实现 – 辅助定义
#define AES_MAXNR 14 #define ROTL8(x,shift) ((uint8_t) ((x) << (shift)) | ((x) >> (8 - (shift)))) #undef ROTATE #if defined(_MSC_VER) || defined(__ICC) # define ROTATE(a,n) _lrotl(a,n) #elif defined(__GNUC__) && __GNUC__>=2 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) # define ROTATE(a,n) ({ register unsigned int ret; \ asm ( \ "roll %1,%0" \ : "=r"(ret) \ : "I"(n), "0"(a) \ : "cc"); \ ret; \ }) # endif #endif typedef struct { uint32_t rd_key[4 * (AES_MAXNR + 1)]; int32_t rounds; uint8_t sbox[256]; } AES_KEY;
- 加密算法C语言实现 – 加密过程
1. 计算sbox
// https://en.wikipedia.org/wiki/Rijndael_S-box static void initialize_aes_sbox(uint8_t *sbox) { /* loop invariant: p * q == 1 in the Galois field */ uint8_t p = 1, q = 1; do { /* multiply p by x+1 */ p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0); /* divide q by x+1 */ q ^= q << 1; q ^= q << 2; q ^= q << 4; q ^= q & 0x80 ? 0x09 : 0; /* compute the affine transformation */ sbox[p] = 0x63 ^ q ^ ROTL8(q, 1) ^ ROTL8(q, 2) ^ ROTL8(q, 3) ^ ROTL8(q, 4); } while (p != 1); /* 0 is a special case since it has no inverse */ sbox[0] = 0x63; }
2. Rcon实现
static uint8_t rcon(uint8_t i) { uint8_t c; for (c = 1; i != 1; i--) c = c << 1 ^ (c & 0x80 ? 0x1b : 0); return c; }
3. 乘法运算实现
// https://en.wikipedia.org/wiki/Finite_field_arithmetic /* Multiply two numbers in the GF(2^8) finite field defined * by the polynomial x^8 + x^4 + x^3 + x + 1 = 0 * using the Russian Peasant Multiplication algorithm * (the other way being to do carry-less multiplication followed by a modular reduction) */ static uint8_t gmul(uint8_t a, uint8_t b) { uint8_t p = 0; /* the product of the multiplication */ while (b) { if (b & 1) /* if b is odd, then add the corresponding a to p (final product = sum of all a's corresponding to odd b's) */ p ^= a; /* since we're in GF(2^m), addition is an XOR */ if (a & 0x80) /* GF modulo: if a >= 128, then it will overflow when shifted left, so reduce */ a = (a << 1) ^ 0x11b; /* XOR with the primitive polynomial x^8 + x^4 + x^3 + x + 1 (0b1_0001_1011) -- you can change it but it must be irreducible */ else a <<= 1; /* equivalent to a*2 */ b >>= 1; /* equivalent to b // 2 */ } return p; }
4. 加密使用的key扩展
int AES_set_encrypt_key(const uint8_t *userKey, const uint32_t bits, AES_KEY *key) { uint32_t i, v1, v2, v3, v4, v5; if (bits != 128) return -1; key->rounds = 10; initialize_aes_sbox(key->sbox); v1 = key->rd_key[0] = *(uint32_t *)(userKey + 0); v2 = key->rd_key[1] = *(uint32_t *)(userKey + 4); v3 = key->rd_key[2] = *(uint32_t *)(userKey + 8); v4 = key->rd_key[3] = *(uint32_t *)(userKey + 12); uint8_t *sbox = key->sbox; for (i = 1; i <= key->rounds; i++) { v5 = sbox[(v4 >> 24) & 0xff] << 0 | sbox[(v4 >> 16) & 0xff] << 24 | sbox[(v4 >> 8) & 0xff] << 16 | sbox[(v4 >> 0) & 0xff] << 8; v1 = rcon(i) << 24 ^ v5 ^ v1; v2 = v1 ^ v2; v3 = v2 ^ v3; v4 = v3 ^ v4; key->rd_key[4 * i + 0] = v1; key->rd_key[4 * i + 1] = v2; key->rd_key[4 * i + 2] = v3; key->rd_key[4 * i + 3] = v4; } return 0; }
NOTE:
这里加密所使用的rcon并非标准:
unsigned char rcon[256] = { 0x8d, 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, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 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, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 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, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 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, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 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, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d }
而是将对应的数值向左移了24位,所以经过这个算法加密的数据,不能通过openssl这种标准的算法来进行解密。
与标准算法的区别请看这篇:
5. 加密算法
void AES_encrypt(const uint8_t *text, uint8_t *cipher, const AES_KEY *key) { uint32_t v1, v2, v3, v4; uint32_t v11, v12, v13, v14; uint32_t v17, v18, v20; v1 = key->rd_key[0] ^ *(uint32_t *)(text + 0); v2 = key->rd_key[1] ^ *(uint32_t *)(text + 4); v3 = key->rd_key[2] ^ *(uint32_t *)(text + 8); v4 = key->rd_key[3] ^ *(uint32_t *)(text + 12); const uint8_t *sbox = key->sbox; for (v20 = 1; v20 < 10; v20++) { v11 = sbox[(v1 >> 24) & 0xFF] << 24 | sbox[(v2 >> 16) & 0xFF] << 16 | sbox[(v3 >> 8) & 0xFF] << 8 | sbox[(v4 >> 0) & 0xFF] << 0; v12 = sbox[(v1 >> 0) & 0xFF] << 0 | sbox[(v2 >> 24) & 0xFF] << 24 | sbox[(v3 >> 16) & 0xFF] << 16 | sbox[(v4 >> 8) & 0xFF] << 8; v13 = sbox[(v1 >> 8) & 0xFF] << 8 | sbox[(v2 >> 0) & 0xFF] << 0 | sbox[(v3 >> 24) & 0xFF] << 24 | sbox[(v4 >> 16) & 0xFF] << 16; v14 = sbox[(v1 >> 16) & 0xFF] << 16 | sbox[(v2 >> 8) & 0xFF] << 8 | sbox[(v3 >> 0) & 0xFF] << 0 | sbox[(v4 >> 24) & 0xFF] << 24; /***************************************************************************** v1 = [ a1 a2 a3 a4 ] <- 0xa1a2a3a4 v2 = [ b1 b2 b3 b4 ] <- 0xb1b2b3b4 v3 = [ c1 c2 c3 c4 ] <- 0xc1c2c3c4 v4 = [ d1 d2 d3 d4 ] <- 0xd1d2d3d4 v11 = [ a1 b2 c3 d4 ] <- 0xa1b2c3d4 v12 = [ b1 c2 d3 a4 ] <- 0xb1c2d3a4 v13 = [ c1 d2 a3 b4 ] <- 0xc1d2a3b4 v14 = [ d1 a2 b3 c4 ] <- 0xd1a2b3c4 v1 = \ [ 02 03 01 01 ] [ a1 ] [ 01 02 03 01 ] [ b2 ] [ 01 01 02 03 ] [ c3 ] [ 03 01 01 02 ] [ d4 ] = \ (02*a1 ^ 03*b2 ^ 01*c3 ^ 01*d4) << 24 | <- (02*a1 ^ 03*b2 ^ 01*c3 ^ 01*d4) << 24 (01*a1 ^ 02*b2 ^ 03*c3 ^ 01*d4) << 16 | <- (02*b2 ^ 03*c3 ^ 01*d1 ^ 01*a1) << 16 (01^a1 ^ 01*b2 ^ 02*c3 ^ 03*d4) << 8 | <- (02*c3 ^ 03*d4 ^ 01*a1 ^ 01*b2) << 8 (03*a1 ^ 01*b2 ^ 01*c3 ^ 02*d4) << 0 <- (02*d4 ^ 03*a1 ^ 01*b2 ^ 01*c3) << 0 -------------------------------------------------------------------------------------------- [ 0e 0b 0d 09 ] [ 02 03 01 01 ] [ 01 00 00 00 ] [ 09 0e 0b 0d ] [ 01 02 03 01 ] [ 00 01 00 00 ] = [ 0d 09 0e 0b ] [ 01 01 02 03 ] [ 00 00 01 00 ] [ 0b 0d 09 0e ] [ 03 01 01 02 ] [ 00 00 00 01 ] *****************************************************************************/ v17 = ROTATE(v11, 16); v18 = ROTATE(v11, 24); v1 = key->rd_key[4 * v20 + 0] ^ 0x1B * ((v11 >> 7) & 0x1010101) ^ 2 * (v11 & 0xFF7F7F7F) ^ ((2 * (v11 & 0x7F000000) ^ 0x1B * ((v11 >> 7) & 0x1010101) ^ v11) >> 24 | (0x1B * ((v11 >> 7) & 0x10101) ^ 2 * (v11 & 0xFFFF7F7F) ^ v11) << 8) ^ v18 ^ v17; v17 = ROTATE(v12, 16); v18 = ROTATE(v12, 24); v2 = key->rd_key[4 * v20 + 1] ^ 0x1B * ((v12 >> 7) & 0x1010101) ^ 2 * (v12 & 0xFF7F7F7F) ^ ((2 * (v12 & 0x7F000000) ^ 0x1B * ((v12 >> 7) & 0x1010101) ^ v12) >> 24 | (0x1B * ((v12 >> 7) & 0x10101) ^ 2 * (v12 & 0xFFFF7F7F) ^ v12) << 8) ^ v18 ^ v17; v17 = ROTATE(v13, 16); v18 = ROTATE(v13, 24); v3 = key->rd_key[4 * v20 + 2] ^ 0x1B * ((v13 >> 7) & 0x1010101) ^ 2 * (v13 & 0xFF7F7F7F) ^ ((2 * (v13 & 0x7F000000) ^ 0x1B * ((v13 >> 7) & 0x1010101) ^ v13) >> 24 | (0x1B * ((v13 >> 7) & 0x10101) ^ 2 * (v13 & 0xFFFF7F7F) ^ v13) << 8) ^ v18 ^ v17; v17 = ROTATE(v14, 16); v18 = ROTATE(v14, 24); v4 = key->rd_key[4 * v20 + 3] ^ 0x1B * ((v14 >> 7) & 0x1010101) ^ 2 * (v14 & 0xFF7F7F7F) ^ ((2 * (v14 & 0x7F000000) ^ 0x1B * ((v14 >> 7) & 0x1010101) ^ v14) >> 24 | (0x1B * ((v14 >> 7) & 0x10101) ^ 2 * (v14 & 0xFFFF7F7F) ^ v14) << 8) ^ v18 ^ v17; } // v1 v2, v3, v4 *(uint32_t *)(cipher + 0) = key->rd_key[4 * v20 + 0] ^ (sbox[(v1 >> 24) & 0xFF] << 24 | sbox[(v2 >> 16) & 0xFF] << 16 | sbox[(v3 >> 8) & 0xFF] << 8 | sbox[(v4 >> 0) & 0xFF] << 0); *(uint32_t *)(cipher + 4) = key->rd_key[4 * v20 + 1] ^ (sbox[(v1 >> 0) & 0xFF] << 0 | sbox[(v2 >> 24) & 0xFF] << 24 | sbox[(v3 >> 16) & 0xFF] << 16 | sbox[(v4 >> 8) & 0xFF] << 8); *(uint32_t *)(cipher + 8) = key->rd_key[4 * v20 + 2] ^ (sbox[(v1 >> 8) & 0xFF] << 8 | sbox[(v2 >> 0) & 0xFF] << 0 | sbox[(v3 >> 24) & 0xFF] << 24 | sbox[(v4 >> 16) & 0xFF] << 16); *(uint32_t *)(cipher + 12) = key->rd_key[4 * v20 + 3] ^ (sbox[(v1 >> 16) & 0xFF] << 16 | sbox[(v2 >> 8) & 0xFF] << 8 | sbox[(v3 >> 0) & 0xFF] << 0 | sbox[(v4 >> 24) & 0xFF] << 24); }
- 加密算法C语言实现 – 解密过程
1. 计算inv_sbox
static void initialize_aes_inv_sbox(uint8_t *inv_sbox) { uint8_t sbox[256]; int32_t i; initialize_aes_sbox(sbox); for (i = 0; i < 256; i++) inv_sbox[sbox[i]] = i; }
NOTE: 通过已知的sbox计算出inv sbox
2. 解密所需的key扩展
int AES_set_decrypt_key(const uint8_t *userKey, const uint32_t bits, AES_KEY *key) { uint32_t i, v1, v2, v3, v4, v5; if (bits != 128) return -1; key->rounds = 10; initialize_aes_sbox(key->sbox); v1 = key->rd_key[0] = *(uint32_t *)(userKey + 0); v2 = key->rd_key[1] = *(uint32_t *)(userKey + 4); v3 = key->rd_key[2] = *(uint32_t *)(userKey + 8); v4 = key->rd_key[3] = *(uint32_t *)(userKey + 12); uint8_t *sbox = key->sbox; for (i = 1; i <= key->rounds; i++) { v5 = sbox[(v4 >> 24) & 0xff] << 0 | sbox[(v4 >> 16) & 0xff] << 24 | sbox[(v4 >> 8) & 0xff] << 16 | sbox[(v4 >> 0) & 0xff] << 8; v1 = rcon(i) << 24 ^ v5 ^ v1; v2 = v1 ^ v2; v3 = v2 ^ v3; v4 = v3 ^ v4; key->rd_key[4 * i + 0] = v1; key->rd_key[4 * i + 1] = v2; key->rd_key[4 * i + 2] = v3; key->rd_key[4 * i + 3] = v4; } initialize_aes_inv_sbox(key->sbox); return 0; }
3. 解密算法
void AES_decrypt(const uint8_t *cipher, uint8_t *text, const AES_KEY *key) { uint32_t v1, v2, v3, v4, v11, v12, v13, v14; const uint8_t *inv_sbox = key->sbox; uint32_t v20 = key->rounds; v11 = *(uint32_t *)(cipher + 0) ^ key->rd_key[v20 * 4 + 0]; v12 = *(uint32_t *)(cipher + 4) ^ key->rd_key[v20 * 4 + 1]; v13 = *(uint32_t *)(cipher + 8) ^ key->rd_key[v20 * 4 + 2]; v14 = *(uint32_t *)(cipher + 12) ^ key->rd_key[v20 * 4 + 3]; v1 = inv_sbox[(v11 >> 24) & 0xff] << 24 | inv_sbox[(v14 >> 16) & 0xff] << 16 | inv_sbox[(v13 >> 8) & 0xff] << 8 | inv_sbox[(v12 >> 0) & 0xff] << 0; v2 = inv_sbox[(v12 >> 24) & 0xff] << 24 | inv_sbox[(v11 >> 16) & 0xff] << 16 | inv_sbox[(v14 >> 8) & 0xff] << 8 | inv_sbox[(v13 >> 0) & 0xff] << 0; v3 = inv_sbox[(v13 >> 24) & 0xff] << 24 | inv_sbox[(v12 >> 16) & 0xff] << 16 | inv_sbox[(v11 >> 8) & 0xff] << 8 | inv_sbox[(v14 >> 0) & 0xff] << 0; v4 = inv_sbox[(v14 >> 24) & 0xff] << 24 | inv_sbox[(v13 >> 16) & 0xff] << 16 | inv_sbox[(v12 >> 8) & 0xff] << 8 | inv_sbox[(v11 >> 0) & 0xff] << 0; for (v20--; v20 >= 1; v20--) { uint32_t *v30[4] = { &v1, &v2, &v3, &v4 }; uint8_t a1, a2, a3, a4; int32_t i; /************************************************************************ v1 = 0xa1a2a3a4 v11 = \ [ 0e 0b 0d 09 ] [ a1 ] [ 09 0e 0b 0d ] [ a2 ] [ 0d 09 0e 0b ] [ a3 ] [ 0b 0d 09 0e ] [ a4 ] = \ (0e*a1 ^ 0b*a2 ^ 0d*a3 ^ 09*a4) << 24 | (09*a1 ^ 0e*a2 ^ 0b*a3 ^ 0d*a4) << 16 | (0d*a1 ^ 09*a2 ^ 0e*a3 ^ 0b*a4) << 8 | (0b*a1 ^ 0d*a2 ^ 09*a3 ^ 0e*a4) << 0 *************************************************************************/ for (i = 0; i < 4; i++) { uint32_t *v = v30[i]; *v ^= key->rd_key[4 * v20 + i]; a1 = (*v >> 24) & 0xff; a2 = (*v >> 16) & 0xff; a3 = (*v >> 8) & 0xff; a4 = (*v >> 0) & 0xff; *v = (gmul(a1, 0x0e) ^ gmul(a2, 0x0b) ^ gmul(a3, 0x0d) ^ gmul(a4, 0x09)) << 24 | (gmul(a1, 0x09) ^ gmul(a2, 0x0e) ^ gmul(a3, 0x0b) ^ gmul(a4, 0x0d)) << 16 | (gmul(a1, 0x0d) ^ gmul(a2, 0x09) ^ gmul(a3, 0x0e) ^ gmul(a4, 0x0b)) << 8 | (gmul(a1, 0x0b) ^ gmul(a2, 0x0d) ^ gmul(a3, 0x09) ^ gmul(a4, 0x0e)) << 0; } v11 = inv_sbox[(v1 >> 24) & 0xff] << 24 | inv_sbox[(v4 >> 16) & 0xff] << 16 | inv_sbox[(v3 >> 8) & 0xff] << 8 | inv_sbox[(v2 >> 0) & 0xff] << 0; v12 = inv_sbox[(v2 >> 24) & 0xff] << 24 | inv_sbox[(v1 >> 16) & 0xff] << 16 | inv_sbox[(v4 >> 8) & 0xff] << 8 | inv_sbox[(v3 >> 0) & 0xff] << 0; v13 = inv_sbox[(v3 >> 24) & 0xff] << 24 | inv_sbox[(v2 >> 16) & 0xff] << 16 | inv_sbox[(v1 >> 8) & 0xff] << 8 | inv_sbox[(v4 >> 0) & 0xff] << 0; v14 = inv_sbox[(v4 >> 24) & 0xff] << 24 | inv_sbox[(v3 >> 16) & 0xff] << 16 | inv_sbox[(v2 >> 8) & 0xff] << 8 | inv_sbox[(v1 >> 0) & 0xff] << 0; v1 = v11; v2 = v12; v3 = v13; v4 = v14; } *(uint32_t *)(text + 0) = key->rd_key[0] ^ v1; *(uint32_t *)(text + 4) = key->rd_key[1] ^ v2; *(uint32_t *)(text + 8) = key->rd_key[2] ^ v3; *(uint32_t *)(text + 12) = key->rd_key[3] ^ v4; }
- 加密算法C语言实现 – 演示
1. 代码
int main(int argc, char *argv[]) { // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf // Expansion of a 128-bit Cipher Key uint8_t userKey[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; uint8_t text[] = { 'w', 'w', 'w', '.', 'b', 'r', 'o', 'b', 'w', 'i', 'n', 'd', '.', 'c', 'o', 'm' }; uint8_t cipher[16]; AES_KEY aes_key; memset(&aes_key, 0x00, sizeof(aes_key)); AES_set_encrypt_key(userKey, 128, &aes_key); printf(" --------------------- AES 128 ENC EXPANDED KEY -------------------------\n"); hexdump(aes_key.rd_key, sizeof(aes_key.rd_key), 0, NULL); AES_encrypt(text, cipher, &aes_key); printf(" --------------------- AES 128 ENC - CIPHER -----------------------------\n"); hexdump(cipher, sizeof(cipher), 0, NULL); AES_set_decrypt_key(userKey, 128, &aes_key); printf(" --------------------- AES 128 DEC EXPANDED KEY -------------------------\n"); hexdump(aes_key.rd_key, sizeof(aes_key.rd_key), 0, NULL); memset(text, 0x00, sizeof(text)); AES_decrypt(cipher, text, &aes_key); printf(" --------------------- AES 128 DEC - TEXT -------------------------------\n"); hexdump(text, sizeof(text), 0, NULL); return 0; }
2. 结果
--------------------- AES 128 ENC EXPANDED KEY ------------------------- 00000000: 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c +~..(.........O< 00000010: c0 7f 9f 93 e8 d1 4d 35 43 26 58 bd 4a e9 17 81 ......M5C&X.J... 00000020: cc a9 81 61 24 78 cc 54 67 5e 94 e9 2d b7 83 68 ...a$x.Tg^..-..h 00000030: 89 71 28 89 ad 09 e4 dd ca 57 70 34 e7 e0 f3 5c .q(......Wp4...\ 00000040: c3 e5 c9 8c 6e ec 2d 51 a4 bb 5d 65 43 5b ae 39 ....n.-Q..]eC[.9 00000050: d1 ff f0 78 bf 13 dd 29 1b a8 80 4c 58 f3 2e 75 ...x...)...LX..u 00000060: 4c 95 fd 69 f3 86 20 40 e8 2e a0 0c b0 dd 8e 79 L..i.. @.......y 00000070: fa 72 3c 30 09 f4 1c 70 e1 da bc 7c 51 07 32 05 .r<0...p...|Q.2. 00000080: 91 a3 f9 93 98 57 e5 e3 79 8d 59 9f 28 8a 6b 9a .....W..y.Y.(.k. 00000090: 29 97 87 f7 b1 c0 62 14 c8 4d 3b 8b e0 c7 50 11 ).....b..M;...P. 000000a0: ab 76 41 92 1a b6 23 86 d2 fb 18 0d 32 3c 48 1c .vA...#.....2<H. 000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ --------------------- AES 128 ENC - CIPHER ----------------------------- 00000000: b6 08 04 bc 5f 65 f2 b3 d7 16 f7 6f d6 6a a2 27 ...._e.....o.j.' --------------------- AES 128 DEC EXPANDED KEY ------------------------- 00000000: 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c +~..(.........O< 00000010: c0 7f 9f 93 e8 d1 4d 35 43 26 58 bd 4a e9 17 81 ......M5C&X.J... 00000020: cc a9 81 61 24 78 cc 54 67 5e 94 e9 2d b7 83 68 ...a$x.Tg^..-..h 00000030: 89 71 28 89 ad 09 e4 dd ca 57 70 34 e7 e0 f3 5c .q(......Wp4...\ 00000040: c3 e5 c9 8c 6e ec 2d 51 a4 bb 5d 65 43 5b ae 39 ....n.-Q..]eC[.9 00000050: d1 ff f0 78 bf 13 dd 29 1b a8 80 4c 58 f3 2e 75 ...x...)...LX..u 00000060: 4c 95 fd 69 f3 86 20 40 e8 2e a0 0c b0 dd 8e 79 L..i.. @.......y 00000070: fa 72 3c 30 09 f4 1c 70 e1 da bc 7c 51 07 32 05 .r<0...p...|Q.2. 00000080: 91 a3 f9 93 98 57 e5 e3 79 8d 59 9f 28 8a 6b 9a .....W..y.Y.(.k. 00000090: 29 97 87 f7 b1 c0 62 14 c8 4d 3b 8b e0 c7 50 11 ).....b..M;...P. 000000a0: ab 76 41 92 1a b6 23 86 d2 fb 18 0d 32 3c 48 1c .vA...#.....2<H. 000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ --------------------- AES 128 DEC - TEXT ------------------------------- 00000000: 77 77 77 2e 62 72 6f 62 77 69 6e 64 2e 63 6f 6d www.brobwind.com
- 加密算法C语言实现 – 源代码
完整的代码可以从这里下载:
$ git clone https://github.com/brobwind/bro_aes.git
代码结构:
bro_aes +-- Makefile +-- README.md +-- bro_aes.c +-- bro_aes.h +-- bro_util.c +-- bro_util.h `-- main.c
使用Makefile编译系统。
- 相关的参考文档:
- http://crypto.stackexchange.com/questions/2418/how-to-use-rcon-in-key-expansion-of-128-bit-advanced-encryption-standard
- http://www.cnblogs.com/luop/p/4334160.html
- http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
- http://www.samiam.org/key-schedule.html
- http://www.formaestudio.com/rijndaelinspector/archivos/Rijndael_Animation_v4_eng.swf
- http://www.adamberent.com/documents/AESbyExample.htm
- http://www.efgh.com/software/rijndael.htm