看了wolfssl-example里面用aes加密文件的c源码,但是他是通过终端命令行编译的,我嫌命令行麻烦,修改了他的代码,然后去掉了一些不需要的部分,能成功加密本地文件。
代码用xcode编译,对0910-e.rtf文件进行加密生成0910.rtf文件,再对0910.rtf文件进行解密生成0190-de.rtf文件,代码是昨天写的,昨天是教师节祝导师教师节快乐,原文件和解密后的文件截图如下,加密后的文件由于系统字符库的原因在mac下打不开:
以下是代码在xcode运行截图:
代码只能对文件进行加密和解密以及显示帮助文件,我写的代码附上:
#include
#include
#include
#include
#include
#include
#include
#include
#define SALT_SIZE 8
/*
* Makes a cyptographically secure key by stretching a user entered key
*/
int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
{
int ret;
ret = wc_RNG_GenerateBlock(rng, salt, SALT_SIZE);
if (ret != 0)
return -1020;
if (pad == 0)
salt[0] = 0;
/* stretches key */
ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
size, SHA256);
if (ret != 0)
return -1030;
return 0;
}
/*
* Encrypts a file using AES
*/
int AesEncrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile)
{
RNG rng;
byte iv[AES_BLOCK_SIZE];
byte* input;
byte* output;
byte salt[SALT_SIZE] = {0};
int i = 0;
int ret = 0;
int inputLength;
int length;
int padCounter = 0;
inFile=fopen("/Users/QY/Desktop/temp09110/temp09110/0910-e.rtf","r");
outFile=fopen("/Users/QY/Desktop/temp09110/temp09110/0910.rtf","w");
fseek(inFile, 0, SEEK_END);
inputLength = ftell(inFile);
fseek(inFile, 0, SEEK_SET);
length = inputLength;
/* pads the length until it evenly matches a block / increases pad number*/
while (length % AES_BLOCK_SIZE != 0) {
length++;
padCounter++;
}
input = malloc(length);
output = malloc(length);
ret = wc_InitRng(&rng);
if (ret != 0) {
printf("Failed to initialize random number generator\n");
return -1030;
}
/* reads from inFile and wrties whatever is there to the input array */
ret = fread(input, 1, inputLength, inFile);
if (ret == 0) {
printf("Input file does not exist.\n");
return -1010;
}
for (i = inputLength; i < length; i++) {
/* padds the added characters with the number of pads */
input[i] = padCounter;
}
ret = wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE);
if (ret != 0)
return -1020;
/* stretches key to fit size */
ret = GenerateKey(&rng, key, size, salt, padCounter);
if (ret != 0)
return -1040;
/* sets key */
ret = wc_AesSetKey(aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
if (ret != 0)
return -1001;
/* encrypts the message to the ouput based on input length + padding */
ret = wc_AesCbcEncrypt(aes, output, input, length);
if (ret != 0)
return -1005;
/* writes to outFile */
fwrite(salt, 1, SALT_SIZE, outFile);
fwrite(iv, 1, AES_BLOCK_SIZE, outFile);
fwrite(output, 1, length, outFile);
/* closes the opened files and frees the memory*/
memset(input, 0, length);
memset(output, 0, length);
memset(key, 0, size);
free(input);
free(output);
free(key);
fclose(inFile);
fclose(outFile);
printf("encrypt success\n");
return ret;
}
/*
* Decryptsr a file using AES
*/
int AesDecrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile)
{
RNG rng;
byte iv[AES_BLOCK_SIZE];
byte* input;
byte* output;
byte salt[SALT_SIZE] = {0};
if((inFile=fopen("/Users/QY/Desktop/temp09110/temp09110/0910.rtf","r"))==NULL)
printf("Input file does not exist.\n");
if((outFile=fopen("/Users/QY/Desktop/temp09110/temp09110/0910-de.rtf","w"))==NULL)
printf("Output file does not exist.\n");
int i = 0;
int ret = 0;
int length;
int aSize;
fseek(inFile, 0, SEEK_END);
length = ftell(inFile);
fseek(inFile, 0, SEEK_SET);
aSize = length;
input = malloc(aSize);
output = malloc(aSize);
wc_InitRng(&rng);
/* reads from inFile and wrties whatever is there to the input array */
ret = fread(input, 1, length, inFile);
if (ret == 0) {
printf("Data does not exist.\n");
return -1010;
}
for (i = 0; i < SALT_SIZE; i++) {
/* finds salt from input message */
salt[i] = input[i];
}
for (i = SALT_SIZE; i < AES_BLOCK_SIZE + SALT_SIZE; i++) {
/* finds iv from input message */
iv[i - SALT_SIZE] = input[i];
}
/* replicates old key if keys match */
ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
size, SHA256);
if (ret != 0)
return -1050;
/* sets key */
ret = wc_AesSetKey(aes, key, AES_BLOCK_SIZE, iv, AES_DECRYPTION);
if (ret != 0)
return -1002;
/* change length to remove salt/iv block from being decrypted */
length -= (AES_BLOCK_SIZE + SALT_SIZE);
for (i = 0; i < length; i++) {
/* shifts message: ignores salt/iv on message*/
input[i] = input[i + (AES_BLOCK_SIZE + SALT_SIZE)];
}
/* decrypts the message to output based on input length + padding*/
ret = wc_AesCbcDecrypt(aes, output, input, length);
if (ret != 0)
return -1006;
if (salt[0] != 0) {
/* reduces length based on number of padded elements */
length -= output[length-1];
}
/* writes output to the outFile based on shortened length */
fwrite(output, 1, length, outFile);
/* closes the opened files and frees the memory*/
memset(input, 0, aSize);
memset(output, 0, aSize);
memset(key, 0, size);
free(input);
free(output);
free(key);
fclose(inFile);
fclose(outFile);
printf("dencrypt success\n");
return 0;
}
/*
* help message
*/
void help()
{
printf("\n~~~~~~~~~~~~~~~~~~~~|Help|~~~~~~~~~~~~~~~~~~~~~\n\n");
printf("Usage: ./aes-file-encrypt <-option> <-i file.in> "
"<-o file.out>\n\n");
printf("Options\n");
printf("-d Decryption\n-e Encryption\n-h Help\n");
}
int main(int argc, char** argv)
{
Aes aes;
byte* key; /* user entered key */
FILE* inFile ;
FILE* outFile ;
const char* in;
const char* out;
char option; /* choice of how to run program */
int ret = 0; /* return value */
int size = 128;
int inCheck = 0;
int outCheck = 0;
// char choice = 'n';
inFile=fopen("/Users/QY/Desktop/temp09110/temp09110/0910-e.rtf ","r");
outFile=fopen("/Users/QY/Desktop/temp09110/temp09110/0910.rtf","w");
printf("\n\nd:if entered decrypt\n");
printf("e:if entered encrypt\n");
printf("h:if entered 'help'\n");
printf("?:Ending Session\n");
printf("Please make your choice:\n");
scanf("%c",&option);
while (option != '?') {
key = malloc(size); /* sets size memory of key */
switch (option) {
case 'd': /* if entered decrypt */
AesDecrypt(&aes, key, size, inFile , outFile );
break;
case 'e': /* if entered encrypt */
AesEncrypt(&aes, key, size, inFile, outFile);
break;
case 'h': /* if entered 'help' */
help();
break;
case '?':
if (optopt) {
printf("Ending Session\n");
exit(0);
}
default:
break;
}
printf("\n\nd:if entered decrypt\n");
printf("e:if entered encrypt\n");
printf("h:if entered 'help'\n");
printf("?:Ending Session\n");
printf("Please make your choice:\n");
getchar();
scanf("%c",&option);
}
return 0;
}