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