对称加密AES算法c语言实现

什么是对称加密:对称加密就是指,加密和解密使用同一个密钥的加密方式。

发送方使用密钥将明文数据加密成密文,然后发送出去,接收方收到密文后,使用同一个密钥将密文解密成明文读取。对称加密计算量小、速度块,适合对大量数据进行加密的场景。

常见的对称加密算法有DES、3DES和AES。

对称加密的缺点

密钥传输问题:如上所说,由于对称加密的加密和解密使用的是同一个密钥,所以对称加密的安全性就不仅仅取决于加密算法本身的强度,更取决于密钥是否被安全的保管,因此加密者如何把密钥安全的传递到解密者手里,就成了对称加密面临的关键问题。密钥一般都使用非对称加密加密后再传输。

密钥管理问题:再者随着密钥数量的增多,密钥的管理问题会逐渐显现出来。比如我们在加密用户的信息时,不可能所有用户都用同一个密钥加密解密吧,这样的话,一旦密钥泄漏,就相当于泄露了所有用户的信息,因此需要为每一个用户单独的生成一个密钥并且管理,这样密钥管理的代价也会非常大。会非常的耗费资源。

对称加密的流程如下所示:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>

#define Max 1024

int S[16][16] =   ///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
};

int S2[16][16] =    ///逆s盒
{
    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
};


///文件存储区
void getString(char *str,int len) ///判断文件内容的结尾的位置
{
    int i=0;
    int slen = read(0,str,len);

    for(i=0; i<slen; i++,str++){
        if(*str=='\n'){
            *str='\0';
            break;
        }
    }
}
void readPlainText(char *str,int *len) ///读取文件内容的长度
{
    int plen;
    while(1){
        getString(str,Max);
        plen=strlen(str);
        if(plen!=0&&plen%16==0){
            printf("你输入的明文为:%s!\n",str);
            break;
        }
        else
            printf("明文长度必须为16的倍数,现在的长度为%d!\n",plen);
    }
    *len=plen;
}
void writeStrToFile(char *str, int len, char *fileName) ///将字符串写入文件
{
    FILE *fp;
    int i = 0;
    printf("Plain text is: %s\n", str);

    fp = fopen(fileName, "wb");
    for(i = 0; i < len; i++)
        putc(str[i], fp);
    fclose(fp);
}
void printASCCI(char *str, int len)///输出字符串
{
    int c, i = 0;

    for(i = 0; i < len; i++){
        c = (int)*str++;
        c = c & 0x000000ff;
        printf("The length of the plaintext must be a multiple of 16"
               ". The current length is 0x%x\n",c);
        //明文长度必须为16的倍数,现在的长度为0x%x
    }
}

int readStrFromFile(char *fileName, char *str) ///判断解密文件是否存在
{
    FILE *fp = fopen(fileName, "rb");
    if(fp == NULL){
        printf("%s %d \n",__func__,__LINE__);
        printf("open file error!\n");
        exit(0);
    }

    int i;
    for(i = 0; i < Max && (str[i] = getc(fp)) != EOF; i++);
    if(i >= Max){
        printf("%s %d \n",__func__,__LINE__);
        printf("file size too big!\n");
        exit(0);
    }
    printf("%s %d %d\n",__func__,__LINE__,i);

    str[i] = '\0';
    fclose(fp);
    return i;
}

///功能实现区
int checkKeyLen(int len) ///检查密钥长度
{
    if(len == 16)
        return 1;
    else
        return 0;
}

int getIntFromChar(char c) ///把一个字符化为整型
{
    int result = (int) c;
    return result & 0x000000ff;
}
int getWordFromStr(char *str) ///密钥扩展--密钥化为二进制
{
    int one = getIntFromChar(str[0]);
    one = one << 24;
    int two = getIntFromChar(str[1]);
    two = two << 16;
    int three = getIntFromChar(str[2]);
    three = three << 8;
    int four = getIntFromChar(str[3]);
    return one | two | three | four;
}

void splitIntToArray(int num, int array[4])
///把一个4字节的数的第一、二、三、四个字节取出,入进一个4个元素的整型数组里面。
{
    int one = num >> 24;
    array[0] = one & 0x000000ff;
    int two = num >> 16;
    array[1] = two & 0x000000ff;
    int three = num >> 8;
    array[2] = three & 0x000000ff;
    array[3] = num & 0x000000ff;
}
int mergeArrayToInt(int array[4])
///把数组中的第一、二、三和四元素分别作为4字节整型的第一、二、三和四字节,合并成一个4字节整型
{
    int one = array[0] << 24;
    int two = array[1] << 16;
    int three = array[2] << 8;
    int four = array[3];
    return one | two | three | four;
}

void leftLoop4int(int array[4], int step) ///将数组中的元素循环左移step位
{
    int temp[4];
    int i = 0;

    for(i = 0; i < 4; i++)
        temp[i] = array[i];

    int index = step % 4 == 0 ? 0 : step % 4;
    for(i = 0; i < 4; i++){
        array[i] = temp[index];
        index++;
        index = index % 4;
    }
}
void rightLoop4int(int array[4], int step) ///将数组循环右移step位
{
    int temp[4];
    int i = 0;

    for(i = 0; i < 4; i++)
        temp[i] = array[i];

    int index = step % 4 == 0 ? 0 : step % 4;
    index = 3 - index;
    for(i = 3; i >= 0; i--){
        array[i] = temp[index];
        index--;
        index = index == -1 ? 3 : index;
    }
}

int getLeft4Bit(int num) ///获取八比特的前四位,并化为十六进制
{
    int left = num & 0x000000f0;
    return left >> 4;
}
int getRight4Bit(int num) ///获取八比特的后四位,并化为十六进制
{
    return num & 0x0000000f;
}

int getNumFromSBox(int index) ///从s盒获取元素
{
    int row = getLeft4Bit(index);
    int col = getRight4Bit(index);
    return S[row][col];
}
int getNumFromS1Box(int index) ///从逆s盒获取元素
{
    int row = getLeft4Bit(index);
    int col = getRight4Bit(index);
    return S2[row][col];
}

int Rcon[10] =            ///常量轮值表
{
    0x01000000, 0x02000000,
    0x04000000, 0x08000000,
    0x10000000, 0x20000000,
    0x40000000, 0x80000000,
    0x1b000000, 0x36000000
};

int T(int num, int round) ///密钥扩展的T函数
{
    int numArray[4];
    int i = 0;
    splitIntToArray(num, numArray);
    leftLoop4int(numArray, 1);//字循环

    //字节代换
    for(i = 0; i < 4; i++){
        numArray[i] = getNumFromSBox(numArray[i]);
    }

    int result = mergeArrayToInt(numArray);
    return result ^ Rcon[round];
}

int w[45];

void extendKey(char *key) ///扩展密钥长度
{
    int i = 0,j = 0;

    for(i = 0; i < 4; i++){
        w[i] = getWordFromStr(key + i * 4);
    }

    for(i = 4, j = 0; i < 44; i++){
        if( i % 4 == 0){
            w[i] = w[i - 4] ^ T(w[i - 1], j);
            j++;//下一轮
        }else{
            w[i] = w[i - 4] ^ w[i - 1];
        }
    }
}

void convertToIntArray(char *str, int pa[4][4])
///把字符转化为字节并按矩阵排列,中字节排序,先上后下,在左后右
{
    int k = 0,i = 0,j = 0;
    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++){
            pa[j][i] = getIntFromChar(str[k]);
            k++;
        }
    }
}

void convertArrayToStr(int array[4][4], char *str) ///把字节转换为字符
{
    int i = 0,j = 0;

    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++)
            *str++ = (char)array[j][i];
    }
}

int colM[4][4] =     ///列混合所用到的矩阵
{
    2, 3, 1, 1,
    1, 2, 3, 1,
    1, 1, 2, 3,
    3, 1, 1, 2
};
int deColM[4][4] =   ///逆列混合所用到的矩阵
{
    0xe, 0xb, 0xd, 0x9,
    0x9, 0xe, 0xb, 0xd,
    0xd, 0x9, 0xe, 0xb,
    0xb, 0xd, 0x9, 0xe
};

int GFMul2(int s) ///GF上对应的值
{
    int result = s << 1;
    int a7 = result & 0x00000100;

    if(a7 != 0){
        result = result & 0x000000ff;
        result = result ^ 0x1b;
    }

    return result;
}
int GFMul3(int s)
{
    return GFMul2(s) ^ s;
}
int GFMul4(int s)
{
    return GFMul2(GFMul2(s));
}
int GFMul8(int s)
{
    return GFMul2(GFMul4(s));
}
int GFMul9(int s)
{
    return GFMul8(s) ^ s;
}
int GFMul11(int s)
{
    return GFMul9(s) ^ GFMul2(s);
}
int GFMul12(int s)
{
    return GFMul8(s) ^ GFMul4(s);
}
int GFMul13(int s)
{
    return GFMul12(s) ^ s;
}
int GFMul14(int s)
{
    return GFMul12(s) ^ GFMul2(s);
}

int GFMul(int n, int s) ///GF上的二元运算
{
    int result;

    if(n == 1)
        result = s;
    else if(n == 2)
        result = GFMul2(s);
    else if(n == 3)
        result = GFMul3(s);
    else if(n == 0x9)
        result = GFMul9(s);
    else if(n == 0xb)//11
        result = GFMul11(s);
    else if(n == 0xd)//13
        result = GFMul13(s);
    else if(n == 0xe)//14
        result = GFMul14(s);

    return result;
}


///1.加密
void addRoundKey(int array[4][4], int round) ///轮密钥加
{
    int i = 0,j = 0;
    int warray[4];
    for(i = 0; i < 4; i++){
        splitIntToArray(w[ round * 4 + i], warray);
        for(j = 0; j < 4; j++){
            array[j][i] = array[j][i] ^ warray[j];
        }
    }
}

void subBytes(int array[4][4]) ///字节代换
{
    int i = 0,j = 0;
    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++)
            array[i][j] = getNumFromSBox(array[i][j]);
    }
}

void shiftRows(int array[4][4]) ///行移位
{
    int i = 0;
    int rowTwo[4], rowThree[4], rowFour[4];
    //复制状态矩阵的第2,3,4行
    for(i = 0; i < 4; i++){
        rowTwo[i] = array[1][i];
        rowThree[i] = array[2][i];
        rowFour[i] = array[3][i];
    }
    //循环左移相应的位数
    leftLoop4int(rowTwo, 1);
    leftLoop4int(rowThree, 2);
    leftLoop4int(rowFour, 3);

    //把左移后的行复制回状态矩阵中
    for(i = 0; i < 4; i++){
        array[1][i] = rowTwo[i];
        array[2][i] = rowThree[i];
        array[3][i] = rowFour[i];
    }
}

void mixColumns(int array[4][4]) ///列混合
{
    int tempArray[4][4];
    int i = 0,j = 0;

    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++)
            tempArray[i][j] = array[i][j];
    }

    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++)
        {
            array[i][j] = GFMul(colM[i][0],tempArray[0][j]) ^ GFMul(colM[i][1],tempArray[1][j])
                          ^ GFMul(colM[i][2],tempArray[2][j]) ^ GFMul(colM[i][3], tempArray[3][j]);
        }
    }
}


///2.解密
void deSubBytes(int array[4][4]) ///逆字节变换
{
    int i = 0,j = 0;
    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++)
            array[i][j] = getNumFromS1Box(array[i][j]);
    }
}

void deShiftRows(int array[4][4]) ///逆行移位
{
    int i = 0;
    int rowTwo[4], rowThree[4], rowFour[4];
    for(i = 0; i < 4; i++){
        rowTwo[i] = array[1][i];
        rowThree[i] = array[2][i];
        rowFour[i] = array[3][i];
    }

    rightLoop4int(rowTwo, 1);
    rightLoop4int(rowThree, 2);
    rightLoop4int(rowFour, 3);

    for(i = 0; i < 4; i++){
        array[1][i] = rowTwo[i];
        array[2][i] = rowThree[i];
        array[3][i] = rowFour[i];
    }
}

void deMixColumns(int array[4][4]) ///逆列混合
{
    int i = 0,j = 0;
    int tempArray[4][4];
    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++){
            tempArray[i][j] = array[i][j];
        }
    }
    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++){
            array[i][j] = GFMul(deColM[i][0],tempArray[0][j]) ^ GFMul(deColM[i][1],tempArray[1][j])
                          ^ GFMul(deColM[i][2],tempArray[2][j]) ^ GFMul(deColM[i][3], tempArray[3][j]);
        }
    }
}

void getArrayFrom4W(int i, int array[4][4]) ///从4个32位的密钥字中获得4X4数组,用于进行逆列混合
{
    int index = i * 4;
    int colOne[4], colTwo[4], colThree[4], colFour[4];
    splitIntToArray(w[index], colOne);
    splitIntToArray(w[index + 1], colTwo);
    splitIntToArray(w[index + 2], colThree);
    splitIntToArray(w[index + 3], colFour);

    for(i = 0; i < 4; i++){
        array[i][0] = colOne[i];
        array[i][1] = colTwo[i];
        array[i][2] = colThree[i];
        array[i][3] = colFour[i];
    }

}

void addRoundTowArray(int aArray[4][4],int bArray[4][4]) ///逆轮密钥加
{
    int i = 0,j = 0;

    for(i = 0; i < 4; i++){
        for(j = 0; j < 4; j++){
            aArray[i][j] = aArray[i][j] ^ bArray[i][j];
        }
    }
}

void aes(char *p, int plen, char *key)///AES加密
{
    int keylen=strlen(key);
    int k = 0,i=0;

    printf("%s %d %d \n",__func__,__LINE__,plen);

    if(plen == 0 || plen % 16 != 0){
        printf("%s %d \n",__func__,__LINE__);
        printf("明文字符长度必须为16的倍数!\n");
        exit(0);
    }

    if(!checkKeyLen(keylen)){
        printf("%s %d \n",__func__,__LINE__);
        printf("密钥字符长度错误!长度必须为16、24和32。当前长度为%d\n",keylen);
        exit(0);
    }

    extendKey(key);//扩展密钥
    int pArray[4][4];

    for(k = 0; k < plen; k += 16){
        convertToIntArray(p + k, pArray);//变成矩阵
        addRoundKey(pArray, 0);//一开始的轮密钥加

        for(i = 1; i < 10; i++) {//前9轮
            subBytes(pArray);//字节代换
            shiftRows(pArray);//行移位
            mixColumns(pArray);//列混合
            addRoundKey(pArray, i);//轮密钥加
        }

        //第10轮
        subBytes(pArray);//字节代换
        shiftRows(pArray);//行移位
        addRoundKey(pArray, 10);//轮密钥加
        convertArrayToStr(pArray, p + k);
    }
}

void deAes(char *c, int clen, char *key) ///AES解密
{
    int keylen = strlen(key);
    int k = 0,i = 9;
    if(clen == 0 || clen % 16 != 0){
        printf("The ciphertext character must be a multiple of 16!"
               " Now the length is %d\n",clen);
        //密文字符长度必须为16的倍数!现在的长度为%d
        exit(0);
    }

    if(!checkKeyLen(keylen)){
        printf("Key character length is wrong! Must be 16, 24,"
               " and 32 in length. Current length is %d\n",keylen);
        //密钥字符长度错误!长度必须为16、24和32。当前长度为
        exit(0);
    }

    extendKey(key);//扩展密钥
    int cArray[4][4];
    for(k = 0; k < clen; k += 16){
        convertToIntArray(c + k, cArray);  //字符转化为字节,并以矩阵形式排列
        addRoundKey(cArray, 10);   //轮密钥加

        int wArray[4][4];
        for(i = 9; i >= 1; i--){
            deSubBytes(cArray); //逆字节替换
            deShiftRows(cArray);//逆行移位
            deMixColumns(cArray); //逆列混合
            getArrayFrom4W(i, wArray);
            deMixColumns(wArray);//逆列混合
            addRoundTowArray(cArray, wArray);//逆轮密钥加
        }
        deSubBytes(cArray);//逆字节替换
        deShiftRows(cArray);//逆行移位
        addRoundKey(cArray, 0);//逆密钥加
        convertArrayToStr(cArray, c + k);

    }
}

void aesStrToFile(char *key) ///s操作,输入明文,并加密后保存在文件里
{

    char p[Max] = {"qweqwerasdfzxcvbnghrasdfzxqwerasdqwerasdfzxcvbnghfzxcvbnghcvbngh"};
    int plen;

    printf("Please enter your plaintext. The length of the plaintext characters must be a multiple of 16.\n");
    //请输入你的明文,明文字符长度必须为16的倍数

    plen = strlen(p);
    printf("AES encryption..................\n");
    //进行AES加密
    aes(p, plen, key);//AES加密

    printf("The encrypted ASCCI in plaintext is\n");
    //加密完后的明文的ASCCI为
    printASCCI(p, plen);
    char fileName[64]= {"save.txt"};

    writeStrToFile(p, plen, fileName);
    //已经将密文写进%s中了,可以在运行该程序的当前目录中找到它。
    printf("The ciphertext has been written into %s, and it can be found in the current directory where the program is run.\n", fileName);
}

void deAesFile(char *key) ///p操作,将存有密文的文件进行解密,并保存在文件里
{
    char fileName[64] = {"save.txt"};
    char c[Max];//密文字符串
    printf("Please enter the name of the file to be decrypted, "
           "the file must be in the same directory as the program\n");

    int clen = readStrFromFile(fileName,c);
    printf("Start decrypting.........\n");
    //开始解密
    deAes(c, clen, key);
    printf("The decrypted plaintext ASCII is:\n");
    //解密后的明文ASCII为
    printASCCI(c, clen);
    printf("Plain text is: %s\n", c);
    //明文为:
    writeStrToFile(c,clen,fileName);
    printf("You can now open %s to view the decrypted ciphertext!\n",fileName);
    //现在可以打开%s来查看解密后的密文了
}

void aesFile(char *key)  ///f操作,将某文件里的内容进行加密
{
    char fileName[64] = {"encrypt.txt"};
    char fileP[Max];

    printf("Please enter the name of the file to be encrypted, the file must be in the same directory as the program\n");

    readStrFromFile(fileName,fileP);
    int plen = strlen(fileP);
    printf("Start encryption.....\n");//开始加密
    printf("The ASCII of the characters in the file before encryption is:%s\n",key);//加密前文件中字符的ASCII为
    printASCCI(fileP, plen);

    aes(fileP, plen, key);//开始加密

    printf("The encrypted ciphertext ASCII is:%s\n",key);//加密后的密文ASCII为
    printASCCI(fileP, plen);
    writeStrToFile(fileP,plen,fileName);
    printf("The encrypted ciphertext has been written into %s\n",fileName); //已经将加密后的密文写进%s中了
}

enum func{
    SAVE,
    ENCRYPT,
    DECODE,
};

static void usage(void)
{
    printf("./test 0      ------------Encrypt string and save to file\n"
           "./test 1      ------------Encrypted file\n"
           "./test 2      ------------Decrypt file\n");
    //输入1表示要加密输入的字符串,并将加密后的内容写入到文件
    //输入2表示要加密文件
    //输入3表示要解密文件
    exit(0);
}

int main(char argc, char *argv[])
{
    char key[17]={"abcdefghigkilmrd"};
    printf("Please enter a 16-character key\n");//输入一个16字节的密钥

    if(argc < 2){
        usage();
    }

    int klen;
    while(1){
        //getString(key,17);
        klen = strlen(key);
        if(klen != 16){
            printf("Please enter a 16-character key,the length of the current key is %d\n",klen);
            //输入一个16字节的密钥,当前密钥长度为
        }else{
            printf("The key you entered is:%s\n",key);//密钥为
            break;
        }
    }

    switch(atoi(argv[1])){
    case SAVE:
        aesStrToFile(key);//用AES加密字符串,并将字符串写进文件中
        break;
    case ENCRYPT:
        aesFile(key);//用AES加密文件
        break;
    case DECODE:
        deAesFile(key);//把文件中的密文解密,并写回文件中
        break;
    default:
        usage();
        break;
    }

    return 0;
}

测试步骤:

  1. 创建一个名为encrypt.txt的文件,并且在文件中写入一些字符,并且保证文件的长度是16的倍数
  2. 输入./aes 1会将encrypt.txt文件加密,并且将加密后的内容重新写入到encrypt.txt中,此时文件中的数据都是加密后的密文
  3. 输入./aes 2会将encrypt.txt文件解密,解密出来的就是原来的明文数据,我们再比较下加密出来的原文和之前写入到文件中的原文是否一致,如果一致则表示加密解密正常
  • 1
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
《Principles of Communication System Simulation with Wireless Aplications》书中附带的源代码,虽然可以在网上找到,但是链接不是那么好找。费了一番功夫,找出来给大家共享。 The hands-on, example-rich guide to modeling and simulating advanced communications systems. Simulation is an important tool used by engineers to design and implement advanced communication systems that deliver optimal performance. This book is a hands-on, example-rich guide to modeling and simulating advanced communications systems. The authors take a systems-level approach, integrating digital communications, channel modeling, coding, elementary statistical estimation techniques, and other essential facets of modeling and simulation. This is the first book to present complete simulation models built with MATLAB that can serve as virtual laboratories for predicting the impact of system design changes. Coverage includes: Role of simulation in communication systems engineering Simulation approaches and methodologies Signal and system representations, filter models, noise generation, Monte Carlo simulation, and postprocessing Advanced techniques for modeling and simulating nonlinear and time-varying systems Waveform level and discrete channel models Performance estimation via Monte Carlo simulation Semianalytic simulation techniques Variance reduction techniques Co-channel interference in wireless communication systems, and more The authors also present detailed case studies covering phase-locked loops, CDMA systems, multichannel nonlinear systems, as well as a start-to-finish simulation of an advanced cellular radio system. Prentice Hall Series in Communications Engineering & Emerging Technologies, Theodore S. Rappaport, Editor Support File(s) Prepared by: William H. Tranter Department of Electrical and Computer Engineering Virginia Tech - Mail Code 0350 Blacksburg, VA 24061 email: btranter@vt.edu Revision Dates: March, 20, 2004 June 14, 2004 The collection of folders contained herein provide the MATLAB source code for all programs contained in the textbook: W. H. Tranter, K. S. Shanmugan, T. S. Rappaport, and K. L. Kosbar, Principles of Communications System Simulation with Wireless Applications, Printice Hall PTR, 2004 (ISBN 0-13-494790-8) Please report any errors, omissions, or suggestions to W. H. Tranter at btranter@vt.edu. Disclaimers: The authors have used reasonable care to ensure that the MATLAB programs given in the book are correct and all programs executed properly using MATLAB Version 5.2.0.3084 (January 17, 1998). The authors realize that this is an old version of MATLAB. This was done on purpose so that the latest version of MATLAB need not be required by the user. For the most part, MATLAB programs developed on older versions of MATLAB can be properly executed on newer versions of MATLAB. Sometimes, however, this is not the case and changes in MATLAB library functions result in compatibility problems. Most of these problems are easily fixed by one familiar with MATLAB code development. Should difficulties occur one should obvious carefully examine the code in the m-file of interest. The first item to check should be the argument list. A number of compatibility issues have been traced to changes made in argument lists. The programs are developed for teaching purposes and are not intended to support the design or analysis of commercial hardware or software. In addition, many of the simulation programs are not written in the most efficient manner so that the signal processing algorithms can be easily understood by the student. Where speed of execution is a problem, the code can be written more efficiently, or the MATLAB code can rewritten in a language that can be easily compiled with the MATLAB code serving as the prototype. Program Folders and Files: The code is arranged by chapter with the code for each chapter in a separate folder. Each MATLAB program is in an individual file. The folder names are denoted Chapter_X where X denotes the chapter number. Folders are given for Chapters 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, and 18. There are no folders for Chapters 1, 2, and 11, since these three chapters contain no MATLAB code. Programs within folders follow the naming conventions given in the textbook. In some cases there will be a README file in a given folder that indicates changes made from the files given in the textbook. In addition, some programs are contained in more than one folder. These are supporting programs and are used with main programs appearing in more than one chapter. An effort was made to not require MATLAB add-on toolboxes in order to execute the programs given here. However, the Signal and Systems Toolbox is required a number of programs, especially those in Chapter 5.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值