前言:
在伟大的计算机科学家研究下,发明了许多的加密算法,以下做个简答的描述:
一、分类
加密算法分为两种:单向加密、双向加密。
单向加密,不可逆的加密算法,只能加密不能解密;
双向加密,由对称性加密算法和非对称性加密算法;
对称性加密:约定好的密钥和统一的加密算法,双发对数据进行加密、解密;
// 加密解密用的是同样的“钥匙”
张无忌将一个加了锁的盒子寄给了赵敏,
赵敏收到盒子后用相同的钥匙打开,然后同样的方式寄回给张无忌;
非对称性加密:公钥和私钥组成,公钥加密私钥解密;
// 加密解密用的是不同的“钥匙”
张无忌和赵敏各有自己的盒子。赵敏要跟张无忌秘密通信,她先让张无忌把盒子打开通过邮局发给她。
赵敏拿到盒子后放入信息锁上,然后发给张无忌。张无忌就可以用他自己的钥匙打开了。回复的话就用同样的方式。
二、SSL(HTTPS 协议)加密原理
SSL 就是典型的非对称性加密方式,结合上面的描述,简单描述一下 SSL 原理:
1、当你的浏览器向服务器请求一个安全的网页(通常是 https://);
2、服务器就把它的证书和(非对称性加密的)公钥发回来;
3、浏览器检查证书是不是由可以信赖的机构颁发的,确认证书有效和此证书是此网站的;
4、浏览器使用服务器给的公钥加密了一个随机对称密钥 (浏览器随机生成一个对称性密钥,采用服务器的公钥进行加密),
包括加密的URL一起发送到服务器
5、服务器用自己的私钥解密了浏览器发送的密钥,然后用这个对称性加密的密钥解密浏览器的请求信息;
6、服务器用你发的对称钥匙给你请求的网页加密。你也有相同的钥匙就可以解密发回来的网页了;
// 非对称算法在加密和解密时用的是不同的钥匙。
信息接受者有两把钥匙:一把“公匙”,一把“私匙”。
公匙是给信息发送者用来加密的,私匙是自己用来解密的这样最大的好处是:
不必通过不安全的渠道发送私密的东西。公匙本来就是给别人用的,不用藏好。
你的私匙在你产生私匙的电脑里保存着。
// 如果还是没能完全理解,把非对称性加密中的 "张无忌、赵敏" 分别换成客户端(浏览器)与服务器(Web)
三、常用的算法
对称性加密算法:AES、DES、3DES
非对称性加密算法:RSA、DSA、ECC
线性散列算法(不是加密算法):MD5、SHA1、HMAC
四、AES 加密算法
AES 又称“矩阵加密算法”其原理采用字节矩阵上进行“或与非”的操作(置换和替代),
达到数据被重新排列、或者替换成为另一个完全不相同的数据;
从而达到可以采用相同的密钥进行“回转”;
AES 加密的区块长度固定为 128、192、256 位(bit);
(附破图一张)
AES 加密过程涉及到 4 种操作:
字节替代(SubBytes)
行移位(ShiftRows)
列混淆(MixColumns)
轮密钥加(AddRoundKey)
解密过程分别为对应的逆操作,
由于每一步操作都是可逆的,按照相反的顺序进行解密即可恢复明文。
字节替代(SubBytes)
字节代替的主要功能是通过一个固定的“矩阵”(想象成 Excel 表格上的数据)
完成一个字节到另外一个字节的映射。
行移位(ShiftRows)
行移位的功能是实现一个 4x4 矩阵内部字节之间的置换。
其实应该就是高级编程不常用的“或与非 ^ & | ”操作;
采用正向行移位和逆向行移位到达预期结果;
列混淆(MixColumns)
利用GF(28)域上算术特性的一个代替。
具体没有深究,有点小复杂,总之一句话代替就是 TM 在矩阵上根据数学公式搞来搞去;
1 /* 2 * Advanced Encryption Standard 3 * @author Dani Huertas 4 * @email huertas.dani@gmail.com 5 * 6 * Based on the document FIPS PUB 197 7 */ 8 #include9 #include 10 #include 11 12 /* 13 * Addition in GF(2^8) 14 * http://en.wikipedia.org/wiki/Finite_field_arithmetic 15 */ 16 uint8_t gadd(uint8_t a, uint8_t b) { 17 return a^b; 18 } 19 20 /* 21 * Subtraction in GF(2^8) 22 * http://en.wikipedia.org/wiki/Finite_field_arithmetic 23 */ 24 uint8_t gsub(uint8_t a, uint8_t b) { 25 return a^b; 26 } 27 28 /* 29 * Multiplication in GF(2^8) 30 * http://en.wikipedia.org/wiki/Finite_field_arithmetic 31 * Irreducible polynomial m(x) = x8 + x4 + x3 + x + 1 32 */ 33 uint8_t gmult(uint8_t a, uint8_t b) { 34 35 uint8_t p = 0, i = 0, hbs = 0; 36 37 for (i = 0; i < 8; i++) { 38 if (b & 1) { 39 p ^= a; 40 } 41 42 hbs = a & 0x80; 43 a <<= 1; 44 if (hbs) a ^= 0x1b; // 0000 0001 0001 1011 45 b >>= 1; 46 } 47 48 return (uint8_t)p; 49 } 50 51 /* 52 * Addition of 4 byte words 53 * m(x) = x4+1 54 */ 55 void coef_add(uint8_t a[], uint8_t b[], uint8_t d[]) { 56 57 d[0] = a[0]^b[0]; 58 d[1] = a[1]^b[1]; 59 d[2] = a[2]^b[2]; 60 d[3] = a[3]^b[3]; 61 } 62 63 /* 64 * Multiplication of 4 byte words 65 * m(x) = x4+1 66 */ 67 void coef_mult(uint8_t *a, uint8_t *b, uint8_t *d) { 68 69 d[0] = gmult(a[0],b[0])^gmult(a[3],b[1])^gmult(a[2],b[2])^gmult(a[1],b[3]); 70 d[1] = gmult(a[1],b[0])^gmult(a[0],b[1])^gmult(a[3],b[2])^gmult(a[2],b[3]); 71 d[2] = gmult(a[2],b[0])^gmult(a[1],b[1])^gmult(a[0],b[2])^gmult(a[3],b[3]); 72 d[3] = gmult(a[3],b[0])^gmult(a[2],b[1])^gmult(a[1],b[2])^gmult(a[0],b[3]); 73 } 74 75 /* 76 * The cipher Key. 77 */ 78 int K; 79 80 /* 81 * Number of columns (32-bit words) comprising the State. For this 82 * standard, Nb = 4. 83 */ 84 int Nb = 4; 85 86 /* 87 * Number of 32-bit words comprising the Cipher Key. For this 88 * standard, Nk = 4, 6, or 8. 89 */ 90 int Nk; 91 92 /* 93 * Number of rounds, which is a function of Nk and Nb (which is 94 * fixed). For this standard, Nr = 10, 12, or 14. 95 */ 96 int Nr; 97 98 /* 99 * S-box transformation table100 */101 static uint8_t s_box[256] = {102 // 0 1 2 3 4 5 6 7 8 9 a b c d e f103 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, // 0104 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, // 1105 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, // 2106 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, // 3107 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, // 4108 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, // 5109 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, // 6110 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, // 7111 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, // 8112 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, // 9113 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, // a114 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, // b115 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, // c116 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, // d117 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, // e118 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};// f119 120 /*121 * Inverse S-box transformation table122 */123 static uint8_t inv_s_box[256] = {124 // 0 1 2 3 4 5 6 7 8 9 a b c d e f125 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, // 0126 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, // 1127 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, // 2128 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, // 3129 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, // 4130 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, // 5131 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, // 6132 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, // 7133 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, // 8134 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, // 9135 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, // a136 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, // b137 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, // c138 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, // d139 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, // e140 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};// f141 142 143 /*144 * Generates the round constant Rcon[i]145 */146 uint8_t R[] = { 0x02, 0x00, 0x00, 0x00};147 148 uint8_t * Rcon(uint8_t i) {149 150 if (i == 1) {151 R[0] = 0x01; // x^(1-1) = x^0 = 1152 } else if (i > 1) {153 R[0] = 0x02;154 i--;155 while (i-1 > 0) {156 R[0] = gmult(R[0], 0x02);157 i--;158 }159 }160 161 return R;162 }163 164 /*165 * Transformation in the Cipher and Inverse Cipher in which a Round 166 * Key is added to the State using an XOR operation. The length of a 167 * Round Key equals the size of the State (i.e., for Nb = 4, the Round 168 * Key length equals 128 bits/16 bytes).169 */170 void add_round_key(uint8_t *state, uint8_t *w, uint8_t r) {171 172 uint8_t c;173 174 for (c = 0; c < Nb; c++) {175 state[Nb*0+c] = state[Nb*0+c]^w[4*Nb*r+4*c+0]; //debug, so it works for Nb !=4 176 state[Nb*1+c] = state[Nb*1+c]^w[4*Nb*r+4*c+1];177 state[Nb*2+c] = state[Nb*2+c]^w[4*Nb*r+4*c+2];178 state[Nb*3+c] = state[Nb*3+c]^w[4*Nb*r+4*c+3]; 179 }180 }181 182 /*183 * Transformation in the Cipher that takes all of the columns of the 184 * State and mixes their data (independently of one another) to 185 * produce new columns.186 */187 void mix_columns(uint8_t *state) {188 189 uint8_t a[] = { 0x02, 0x01, 0x01, 0x03}; // a(x) = {02} + {01}x + {01}x2 + {03}x3190 uint8_t i, j, col[4], res[4];191 192 for (j = 0; j < Nb; j++) {193 for (i = 0; i < 4; i++) {194 col[i] = state[Nb*i+j];195 }196 197 coef_mult(a, col, res);198 199 for (i = 0; i < 4; i++) {200 state[Nb*i+j] = res[i];201 }202 }203 }204 205 /*206 * Transformation in the Inverse Cipher that is the inverse of 207 * MixColumns().208 */209 void inv_mix_columns(uint8_t *state) {210 211 uint8_t a[] = { 0x0e, 0x09, 0x0d, 0x0b}; // a(x) = {0e} + {09}x + {0d}x2 + {0b}x3212 uint8_t i, j, col[4], res[4];213 214 for (j = 0; j < Nb; j++) {215 for (i = 0; i < 4; i++) {216 col[i] = state[Nb*i+j];217 }218 219 coef_mult(a, col, res);220 221 for (i = 0; i < 4; i++) {222 state[Nb*i+j] = res[i];223 }224 }225 }226 227 /*228 * Transformation in the Cipher that processes the State by cyclically 229 * shifting the last three rows of the State by different offsets. 230 */231 void shift_rows(uint8_t *state) {232 233 uint8_t i, k, s, tmp;234 235 for (i = 1; i < 4; i++) {236 // shift(1,4)=1; shift(2,4)=2; shift(3,4)=3237 // shift(r, 4) = r;238 s = 0;239 while (s < i) {240 tmp = state[Nb*i+0];241 242 for (k = 1; k < Nb; k++) {243 state[Nb*i+k-1] = state[Nb*i+k];244 }245 246 state[Nb*i+Nb-1] = tmp;247 s++;248 }249 }250 }251 252 /*253 * Transformation in the Inverse Cipher that is the inverse of 254 * ShiftRows().255 */256 void inv_shift_rows(uint8_t *state) {257 258 uint8_t i, k, s, tmp;259 260 for (i = 1; i < 4; i++) {261 s = 0;262 while (s < i) {263 tmp = state[Nb*i+Nb-1];264 265 for (k = Nb-1; k > 0; k--) {266 state[Nb*i+k] = state[Nb*i+k-1];267 }268 269 state[Nb*i+0] = tmp;270 s++;271 }272 }273 }274 275 /*276 * Transformation in the Cipher that processes the State using a non277 * linear byte substitution table (S-box) that operates on each of the 278 * State bytes independently. 279 */280 void sub_bytes(uint8_t *state) {281 282 uint8_t i, j;283 uint8_t row, col;284 285 for (i = 0; i < 4; i++) {286 for (j = 0; j < Nb; j++) {287 row = (state[Nb*i+j] & 0xf0) >> 4;288 col = state[Nb*i+j] & 0x0f;289 state[Nb*i+j] = s_box[16*row+col];290 }291 }292 }293 294 /*295 * Transformation in the Inverse Cipher that is the inverse of 296 * SubBytes().297 */298 void inv_sub_bytes(uint8_t *state) {299 300 uint8_t i, j;301 uint8_t row, col;302 303 for (i = 0; i < 4; i++) {304 for (j = 0; j < Nb; j++) {305 row = (state[Nb*i+j] & 0xf0) >> 4;306 col = state[Nb*i+j] & 0x0f;307 state[Nb*i+j] = inv_s_box[16*row+col];308 }309 }310 }311 312 /*313 * Function used in the Key Expansion routine that takes a four-byte 314 * input word and applies an S-box to each of the four bytes to 315 * produce an output word.316 */317 void sub_word(uint8_t *w) {318 319 uint8_t i;320 321 for (i = 0; i < 4; i++) {322 w[i] = s_box[16*((w[i] & 0xf0) >> 4) + (w[i] & 0x0f)];323 }324 }325 326 /*327 * Function used in the Key Expansion routine that takes a four-byte 328 * word and performs a cyclic permutation. 329 */330 void rot_word(uint8_t *w) {331 332 uint8_t tmp;333 uint8_t i;334 335 tmp = w[0];336 337 for (i = 0; i < 3; i++) {338 w[i] = w[i+1];339 }340 341 w[3] = tmp;342 }343 344 /*345 * Key Expansion346 */347 void key_expansion(uint8_t *key, uint8_t *w) {348 349 uint8_t tmp[4];350 uint8_t i, j;351 uint8_t len = Nb*(Nr+1);352 353 for (i = 0; i < Nk; i++) {354 w[4*i+0] = key[4*i+0];355 w[4*i+1] = key[4*i+1];356 w[4*i+2] = key[4*i+2];357 w[4*i+3] = key[4*i+3];358 }359 360 for (i = Nk; i < len; i++) {361 tmp[0] = w[4*(i-1)+0];362 tmp[1] = w[4*(i-1)+1];363 tmp[2] = w[4*(i-1)+2];364 tmp[3] = w[4*(i-1)+3];365 366 if (i%Nk == 0) {367 368 rot_word(tmp);369 sub_word(tmp);370 coef_add(tmp, Rcon(i/Nk), tmp);371 372 } else if (Nk > 6 && i%Nk == 4) {373 374 sub_word(tmp);375 376 }377 378 w[4*i+0] = w[4*(i-Nk)+0]^tmp[0];379 w[4*i+1] = w[4*(i-Nk)+1]^tmp[1];380 w[4*i+2] = w[4*(i-Nk)+2]^tmp[2];381 w[4*i+3] = w[4*(i-Nk)+3]^tmp[3];382 }383 }384 385 void cipher(uint8_t *in, uint8_t *out, uint8_t *w) {386 387 uint8_t state[4*Nb];388 uint8_t r, i, j;389 390 for (i = 0; i < 4; i++) {391 for (j = 0; j < Nb; j++) {392 state[Nb*i+j] = in[i+4*j];393 }394 }395 396 add_round_key(state, w, 0);397 398 for (r = 1; r < Nr; r++) {399 sub_bytes(state);400 shift_rows(state);401 mix_columns(state);402 add_round_key(state, w, r);403 }404 405 sub_bytes(state);406 shift_rows(state);407 add_round_key(state, w, Nr);408 409 for (i = 0; i < 4; i++) {410 for (j = 0; j < Nb; j++) {411 out[i+4*j] = state[Nb*i+j];412 }413 }414 }415 416 void inv_cipher(uint8_t *in, uint8_t *out, uint8_t *w) {417 418 uint8_t state[4*Nb];419 uint8_t r, i, j;420 421 for (i = 0; i < 4; i++) {422 for (j = 0; j < Nb; j++) {423 state[Nb*i+j] = in[i+4*j];424 }425 }426 427 add_round_key(state, w, Nr);428 429 for (r = Nr-1; r >= 1; r--) {430 inv_shift_rows(state);431 inv_sub_bytes(state);432 add_round_key(state, w, r);433 inv_mix_columns(state);434 }435 436 inv_shift_rows(state);437 inv_sub_bytes(state);438 add_round_key(state, w, 0);439 440 for (i = 0; i < 4; i++) {441 for (j = 0; j < Nb; j++) {442 out[i+4*j] = state[Nb*i+j];443 }444 }445 }446 447 int main(int argc, char *argv[]) {448 449 uint8_t i;450 451 /*452 * Appendix A - Key Expansion Examples453 */454 455 /* 128 bits */456 /* uint8_t key[] = {457 0x2b, 0x7e, 0x15, 0x16,458 0x28, 0xae, 0xd2, 0xa6,459 0xab, 0xf7, 0x15, 0x88,460 0x09, 0xcf, 0x4f, 0x3c}; */461 462 /* 192 bits */463 /* uint8_t key[] = {464 0x8e, 0x73, 0xb0, 0xf7,465 0xda, 0x0e, 0x64, 0x52,466 0xc8, 0x10, 0xf3, 0x2b,467 0x80, 0x90, 0x79, 0xe5,468 0x62, 0xf8, 0xea, 0xd2,469 0x52, 0x2c, 0x6b, 0x7b}; */470 471 /* 256 bits */472 /* uint8_t key[] = {473 0x60, 0x3d, 0xeb, 0x10,474 0x15, 0xca, 0x71, 0xbe,475 0x2b, 0x73, 0xae, 0xf0,476 0x85, 0x7d, 0x77, 0x81,477 0x1f, 0x35, 0x2c, 0x07,478 0x3b, 0x61, 0x08, 0xd7,479 0x2d, 0x98, 0x10, 0xa3,480 0x09, 0x14, 0xdf, 0xf4};481 */482 483 /* uint8_t in[] = {484 0x32, 0x43, 0xf6, 0xa8,485 0x88, 0x5a, 0x30, 0x8d,486 0x31, 0x31, 0x98, 0xa2,487 0xe0, 0x37, 0x07, 0x34}; // 128488 */489 490 /*491 * Appendix C - Example Vectors492 */493 494 /* 128 bit key */495 /* uint8_t key[] = {496 0x00, 0x01, 0x02, 0x03, 497 0x04, 0x05, 0x06, 0x07, 498 0x08, 0x09, 0x0a, 0x0b, 499 0x0c, 0x0d, 0x0e, 0x0f}; */500 501 /* 192 bit key */502 /* uint8_t key[] = {503 0x00, 0x01, 0x02, 0x03,504 0x04, 0x05, 0x06, 0x07,505 0x08, 0x09, 0x0a, 0x0b,506 0x0c, 0x0d, 0x0e, 0x0f,507 0x10, 0x11, 0x12, 0x13,508 0x14, 0x15, 0x16, 0x17}; */509 510 /* 256 bit key */511 uint8_t key[] = {512 0x00, 0x01, 0x02, 0x03,513 0x04, 0x05, 0x06, 0x07,514 0x08, 0x09, 0x0a, 0x0b,515 0x0c, 0x0d, 0x0e, 0x0f,516 0x10, 0x11, 0x12, 0x13,517 0x14, 0x15, 0x16, 0x17,518 0x18, 0x19, 0x1a, 0x1b,519 0x1c, 0x1d, 0x1e, 0x1f};520 521 uint8_t in[] = {522 0x00, 0x11, 0x22, 0x33,523 0x44, 0x55, 0x66, 0x77,524 0x88, 0x99, 0xaa, 0xbb,525 0xcc, 0xdd, 0xee, 0xff};526 527 uint8_t out[16]; // 128528 529 uint8_t *w; // expanded key530 531 switch (sizeof(key)) {532 default:533 case 16: Nk = 4; Nr = 10; break;534 case 24: Nk = 6; Nr = 12; break;535 case 32: Nk = 8; Nr = 14; break;536 }537 538 w = malloc(Nb*(Nr+1)*4);539 540 key_expansion(key, w);541 542 cipher(in /* in */, out /* out */, w /* expanded key */);543 544 printf("out:\n");545 546 for (i = 0; i < 4; i++) {547 printf("%x %x %x %x ", out[4*i+0], out[4*i+1], out[4*i+2], out[4*i+3]);548 }549 550 printf("\n");551 552 inv_cipher(out, in, w);553 554 printf("msg:\n");555 for (i = 0; i < 4; i++) {556 printf("%x %x %x %x ", in[4*i+0], in[4*i+1], in[4*i+2], in[4*i+3]);557 }558 559 printf("\n");560 561 exit(0);562 563 }
参考自: