摘取自https://www.cnblogs.com/Junbo20141201/p/9369860.html,感谢原作者的详细解读。

#include <stdio.h>

static const int S[][] = {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}; /**
* 逆S盒
*/
static const int S2[][] = {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}; //S盒字节变换
uint8_t byteTransformation(uint8_t a, uint8_t x) {
uint8_t tmp[] = {}; for (uint8_t i = ; i < ; i++) {
tmp[i] = (((a >> i) & 0x1) ^ ((a >> ((i + ) % )) & 0x1) ^ ((a >> ((i + ) % )) & 0x1) ^
((a >> ((i + ) % )) & 0x1) ^ ((a >> ((i + ) % )) & 0x1) ^ ((x >> i) & 0x1)) << i;
}
tmp[] = tmp[] + tmp[] + tmp[] + tmp[] + tmp[] + tmp[] + tmp[] + tmp[];
return tmp[];
} //逆S盒字节变换
uint8_t invByteTransformation(uint8_t a, uint8_t x) {
uint8_t tmp[] = {}; for (uint8_t i = ; i < ; i++) {
tmp[i] = (((a >> ((i + ) % )) & 0x1) ^ ((a >> ((i + ) % )) & 0x1) ^ ((a >> ((i + ) % )) & 0x1) ^
((x >> i) & 0x1)) << i;
}
tmp[] = tmp[] + tmp[] + tmp[] + tmp[] + tmp[] + tmp[] + tmp[] + tmp[];
return tmp[];
} //找到最高位
uint8_t findHigherBit(uint16_t val) {
int i = ;
while (val) {
i++;
val = val >> ;
}
return i;
} //GF(2^8)的多项式除法
uint8_t gf28_div(uint16_t div_ed, uint16_t div, uint16_t *remainder) {
uint16_t r0 = ;
uint8_t qn = ;
int bitCnt = ; r0 = div_ed; bitCnt = findHigherBit(r0) - findHigherBit(div);
while (bitCnt >= ) {
qn = qn | ( << bitCnt);
r0 = r0 ^ (div << bitCnt);
bitCnt = findHigherBit(r0) - findHigherBit(div);
}
*remainder = r0;
return qn;
} //GF(2^8)的多项式乘法
uint16_t polynomialMutil(uint8_t a, uint8_t b) {
uint16_t tmp[] = {};
uint8_t i;
for (i = ; i < ; i++) {
tmp[i] = (a << i) * ((b >> i) & 0x1);
} tmp[] = tmp[] ^ tmp[] ^ tmp[] ^ tmp[] ^ tmp[] ^ tmp[] ^ tmp[] ^ tmp[]; return tmp[];
} //GF(2^8)多项式的扩展欧几里得算法
uint8_t extEuclidPolynomial(uint8_t a, uint16_t m) {
uint16_t r0, r1, r2;
uint8_t qn, v0, v1, v2, w0, w1, w2; r0 = m;
r1 = a; v0 = ;
v1 = ; w0 = ;
w1 = ; while (r1 != ) {
qn = gf28_div(r0, r1, &r2); v2 = v0 ^ polynomialMutil(qn, v1);
w2 = w0 ^ polynomialMutil(qn, w1); r0 = r1;
r1 = r2; v0 = v1;
v1 = v2; w0 = w1;
w1 = w2;
}
return w1;
} //S盒产生
void s_box_gen(void) {
uint8_t i, j;
uint8_t s_box_ary[][] = {}; //初始化S盒
for (i = ; i < 0x10; i++) {
for (j = ; j < 0x10; j++) {
s_box_ary[i][j] = ((i << ) & 0xF0) + (j & (0xF));
}
} printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for (i = ; i < 0x10; i++) {
printf("\r\n%2x", i);
for (j = ; j < 0x10; j++) {
printf(" %2x", s_box_ary[i][j]);
}
}
//求在GF(2^8)域上的逆,0映射到自身
printf("\r\n");
for (i = ; i < 0x10; i++) {
for (j = ; j < 0x10; j++) {
if (s_box_ary[i][j] != ) {
s_box_ary[i][j] = extEuclidPolynomial(s_box_ary[i][j], 0x11B);
}
}
} printf("\r\n\r\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for (i = ; i < 0x10; i++) {
printf("\r\n%2x", i);
for (j = ; j < 0x10; j++) {
printf(" %2x", s_box_ary[i][j]);
}
}
//对每个字节做变换
for (i = ; i < 0x10; i++) {
for (j = ; j < 0x10; j++) {
s_box_ary[i][j] = byteTransformation(s_box_ary[i][j], 0x63);
}
} printf("\r\n\r\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for (i = ; i < 0x10; i++) {
printf("\r\n%2x", i);
for (j = ; j < 0x10; j++) {
printf(" %2x", s_box_ary[i][j]);
}
}
} //逆S盒产生
void inv_s_box_gen(void) {
uint8_t i, j;
uint8_t s_box_ary[][] = {};
uint8_t b = , bb = ; //初始化S盒
for (i = ; i < 0x10; i++) {
for (j = ; j < 0x10; j++) {
s_box_ary[i][j] = ((i << ) & 0xF0) + (j & (0xF));
}
} printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for (i = ; i < 0x10; i++) {
printf("\r\n%2x", i);
for (j = ; j < 0x10; j++) {
printf(" %2x", s_box_ary[i][j]);
}
}
//对每个字节做变换
for (i = ; i < 0x10; i++) {
for (j = ; j < 0x10; j++) {
s_box_ary[i][j] = invByteTransformation(s_box_ary[i][j], 0x05);
}
} printf("\r\n\r\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for (i = ; i < 0x10; i++) {
printf("\r\n%2x", i);
for (j = ; j < 0x10; j++) {
printf(" %2x", s_box_ary[i][j]);
}
} //求在GF(2^8)域上的逆,0映射到自身
printf("\r\n");
for (i = ; i < 0x10; i++) {
for (j = ; j < 0x10; j++) {
if (s_box_ary[i][j] != ) {
s_box_ary[i][j] = extEuclidPolynomial(s_box_ary[i][j], 0x11B);
}
}
} printf("\r\n\r\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for (i = ; i < 0x10; i++) {
printf("\r\n%2x", i);
for (j = ; j < 0x10; j++) {
printf(" %2x", s_box_ary[i][j]);
}
}
} int main(int argc, char const *argv[]) {
// s_box_gen();
inv_s_box_gen();
return ;
}

AES加密的S盒和逆S盒的推导代码备份(C实现)的更多相关文章

  1. AES128加密-S盒和逆S盒构造推导及代码实现

    文档引用了<密码编码学与网络安全--原理和实践>里边的推导过程,如有不妥,请与我联系修改. 文档<FIPS 197>高级加密标准AES,里边有个S盒构造,涉及到了数论和有限域的 ...

  2. AES加密基本原理图解

    AES加密 Fright-Moch整理 AES简介 高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的).对 ...

  3. AES加密【转】

    .   此时就一定要使用如下代码步骤 : 1.SecureRandom的key定下来. SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又 ...

  4. 信息安全-加密:AES 加密

    ylbtech-信息安全-加密:AES 加密 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一 ...

  5. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  6. iOS客户端学习之AES加密

    数据加密在解密在软件开发过程中举足轻重的作用,可能有的公司在加密的时候有自己公司内部一套设计的算法,而在这方面不想浪费太大精力就可以去考虑使用第三方提供的加密算法,如AES加密算法,本篇内容介绍开源中 ...

  7. AES加密原理和AOE工程实践

    在AI业务的开发的过程中,我们常常需要对模型文件进行加密.我们从以下几个方面来说一说AES的加密原理以及AOE里的工程实践. 常见的加密算法 AOE对模型加密需求的思考 AES的加密原理 AOE工程实 ...

  8. C语言的AES加密

    C语言的AES加密 稍微封装了几个函数 方便使用 #if 1 #include <stdio.h> #include <stdlib.h> #include <strin ...

  9. PHP对称加密-AES加密、DES加密

    对称加密 对称加密算法是指,数据发信方将明文(原始数据)和密钥一起经过加密处理后,使其变成复杂的加密密文发送出去.收信方收到密文后,若要解读原文,则需要使用加密密钥及相关算法的逆算法对密文进行解密,使 ...

随机推荐

  1. 帆软报表(finereport) 折叠树

    在进行展现数据时,希望模板的数据是可以动态折叠的,即点击数据前面的加号才展开对应下面的数据,可通过树节点按钮实现折叠树效果 实现思路: 1.这里建立一个内置数据集 添加数据 设置模板样式,添加颜色和对 ...

  2. 帆软报表(finereport)图表——扇形图/等弧度的玫瑰图

    扇形图/等弧度的玫瑰图,展示的是展示数据所占的比例,需要所有数据的和加起来为1. 下面利用一个实例说明玫瑰图的用法和设置起始角度和终止角度,操作如下: 1.配置一个内置数据集 新增一个等弧度的玫瑰图模 ...

  3. DataStructure-链表实现指数非递减一元多项式的求和

    // 2-链表实现多项式的求和.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> #inclu ...

  4. Django ----- app 和 ORM的操作和介绍

    创建APP ORM 介绍 ORM的操作 说明一下 GET 和 POST 的区别: , GET ①获取一个页面 ②提交数据 数据显示在URL ?user=alex&pwd=alexdsb ,PO ...

  5. C# 最牛逼的Utility工具类

    完整代码: using System; using System.Collections.Specialized; using System.IO; using System.Net; using S ...

  6. Java_运算符

    目录 一.算术运算符 二.关系运算符 三.位运算符 四.赋值运算符 五.条件运算符 六.instanceof 运算符 七.逻辑运算符 一.算术运算符 加 减 乘 除 取余 自增 自减(+ - * / ...

  7. 阿里云服务器Ubuntu 14.04.2和centos7.5实现nfs挂载

    前提条件,确保两个ip可以正常通信 确认服务端是否安装nfs-utils和rpcbind[root@localhost /]# rpm -qa|grep "nfs"nfs4-acl ...

  8. Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  9. 单元测试如何覆盖internal的方法

    在类的设计中经常会有类或者方法要设置成private或者internal等方式,在使用中这么做无可厚非,但是对单元测试的影响也颇大 对于private方法,那只有做一个副本然后改成internal或p ...

  10. css-tips

    div的height:100%有作用 其父元素设置height:100% 包括html,body