c - 加密性能

标签 c algorithm encryption polarssl

我有兴趣了解加密对硬件性能的影响,因此我编写了一个测试程序来实现这一效果(抱歉出现大量代码转储)。它使用 PolarSSl 对其创建的许多文件执行加密和解密。我(暂时)只记录加解密的时间,结果如下图所示。然而,这不是我期望看到的。我只是想知道是否有人可以发现程序中的问题或向我提供对图表的解释。 编辑 抱歉,图表上的一些标签会提供巨大的帮助,y 上的秒数,x 上的文件大小(兆字节)。干杯 Results

    #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h> //high percission

#include <polarssl/aes.h>
#include <polarssl/sha256.h> // This in the real version should be a higher 512

struct timespec diff(struct timespec start, struct timespec end);

/**
 * @brief createFiles Creates a series of files of various sizes (512KB, 1mb,2mb,3mb,4mb) for encryption, and then to be decrypted
 */
void createFiles(u_int64_t* sizes, u_int8_t noOfFiles)
{


    u_int8_t i = 0;

    for(i = 0; i < noOfFiles; i++)
    {
        char str[noOfFiles];
        sprintf(str, "%d", i);
        FILE *fp = fopen(str, "wb");

        char *buffer= malloc(sizes[i]);
        memset(buffer,'a',sizes[i]);
        fprintf(fp,buffer);

        fclose(fp);
        memset(buffer,0,sizes[i]);
    }
}

int encryptFile(int fileNo, struct timespec* timeTaken)
{


    int returnvalue = -1;
    unsigned char key[32] = {'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1'}; // Holds the key
    unsigned char IV[16];
    FILE * fin = NULL; //The temp file we created
    FILE* fout  = NULL; //The temp file to open
    u_int64_t fileSize = 0;

    struct timespec start,end, timeDiff;

    //Create the contex objects
    aes_context aes_ctx;
    int i;
    char str[1];
    sprintf(str, "%d", fileNo);

    //file name is i value prepended by c
    char* out;
    const char* extension = "c";
    out = malloc(strlen(str)+2);
    strcpy(out, str);
    strcat(out, extension);

    //Open the relevent file
    if((fin = fopen(str, "rb" ) ) != NULL)
    {
        //Open the output file
        if((fout = fopen( out, "wb" )) != NULL)
        {

            //get the size of the file, and check it is not empty
            if(!( ( fileSize = lseek( fileno(fin ), 0, SEEK_END ) ) < 0 ))
            {
                //reset the seek position
                if(fseek( fin, 0, SEEK_SET ) < 0 )
                {
                    fprintf( stderr, "fseek(0,SEEK_SET) failed\n" );
                }
                else
                {
                    returnvalue = 0;

                    //generate IV
                    srand(time(NULL));
                    for( i = 0; i < 16; i++)
                    {
                        IV[i] = rand();
                    }

                    //create a buffer large enough to hold the file -- on a real system i susspect we would do this incormentaly 16bytes at time for example
                    int addition = ((fileSize +15)/16) *16;
                    char* buffer = malloc(addition);
                    char* encryptBuffer= malloc(addition);
                    fread(buffer,sizeof(char),addition,fin); // read the file
                    clock_gettime(CLOCK_MONOTONIC,  &start);

                    int error =  aes_setkey_enc(&aes_ctx, key, 256 );//Set up the ctx object -- setting the key

                    if(error != POLARSSL_ERR_AES_INVALID_KEY_LENGTH)
                    {


                        error == aes_crypt_cbc( &aes_ctx, AES_ENCRYPT, addition, IV, buffer, encryptBuffer ); //--encrypt the data
                        clock_gettime(CLOCK_MONOTONIC,  &end);
                        if(error != POLARSSL_ERR_AES_INVALID_INPUT_LENGTH)
                        {
                            fwrite(IV, sizeof(char), 16, fout);
                            fwrite(encryptBuffer, sizeof(char), sizeof(char)*fileSize, fout);

                        }
                        else
                        {
                            printf("error");
                        }

                        memset(buffer,0,addition);
                        memset(encryptBuffer,0,addition);
                        memset( &aes_ctx, 0, sizeof(  aes_context ) );
                    }
                    else
                    {
                        printf("Invalid key length");
                    }

                    // Calculate the difference
                    timeDiff = diff(start,end);


     //            printf("For file %i, with a size of %i bytes, the time taken to encrypt was ", fileNo,fileSize);
       //            printf("%d.%d seconds\n", timeDiff.tv_sec, timeDiff.tv_nsec);
                    fflush(stdout);
                    timeTaken->tv_sec = timeDiff.tv_sec;
                    timeTaken->tv_nsec = timeDiff.tv_nsec;
                }
            }

            fclose(fout);
        }
        fclose(fin);
    }


    return returnvalue;
}


int decryptfile(int fileNumber, struct timespec* timeTaken)
{
    u_int64_t fileSize = 0;
    int returnvalue = -1;
    char str[1];
    unsigned char key[32] = {'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1'}; // Holds the key

    unsigned char IV[16];
    struct timespec start,end, timeDiff;


    //Create the contex objects
    aes_context aes_ctx;
    sprintf(str, "%d", fileNumber);

    //file name is i vavlue prepended by c
    char* in;
    const char* extension = "c";
    in = malloc(strlen(str)+2);
    strcpy(in, str);
    strcat(in, extension);

    char* out;
    //decrypt to fine number +d
    const char* extension2 = "d";
    out = malloc(strlen(str)+2);
    strcpy(out, str);
    strcat(out, extension2);


    FILE * fin = NULL; //The temp file we created
    FILE* fout  = NULL; //The temp file to open

    if((fin = fopen(in, "rb" ) ) != NULL)
    {
        //Open the output file
        if((fout = fopen( out, "wb" )) != NULL)
        {


            //get the size of the file, and check it is not empty
            if(!( ( fileSize = lseek( fileno(fin ), 0, SEEK_END ) ) < 0 ))
            {

                if(fseek( fin, 0, SEEK_SET ) < 0 )
                {
                    fprintf( stderr, "fseek(0,SEEK_SET) failed\n" );
                }
                else
                {

                    int addition = ((fileSize +15)/16) *16;
                    char* buffer = malloc(addition);
                    char* decryptBuffer = malloc((addition - 16));
                    char* resultBuffer = malloc((addition - 16));


                    fflush(stdout);
                    fread(buffer,sizeof(char),fileSize,fin); // read the file

                    memcpy(IV,buffer,16);
                    memcpy(decryptBuffer,(buffer + 16),addition);
                    memset(buffer,0,addition);  // Clear this to save on memory
                    clock_gettime(CLOCK_MONOTONIC,  &start);
                    int error =  aes_setkey_dec(&aes_ctx, key, 256 );//Set up the ctx object -- setting the key

                    if(error != POLARSSL_ERR_AES_INVALID_KEY_LENGTH)
                    {
                        error == aes_crypt_cbc( &aes_ctx, AES_DECRYPT, addition-16, IV, decryptBuffer, resultBuffer); //--encrypt the data
                        clock_gettime(CLOCK_MONOTONIC,  &end);
                        if(error != POLARSSL_ERR_AES_INVALID_INPUT_LENGTH)
                        {
                            fwrite(resultBuffer, sizeof(char), sizeof(char)*(addition - 16), fout);

                        }
                    }
                    returnvalue = 0;

                    memset(buffer,0,sizeof(buffer));
                    memset(decryptBuffer,0,sizeof(decryptBuffer));
                    memset(resultBuffer,0,sizeof(resultBuffer));
                }

            }
        }
    }

    // Calculate the difference
    timeDiff = diff(start,end);


 //   printf("For file %i, with a size of %i bytes, the time taken to decrypt was ", fileNumber,fileSize);
  //  printf("%d.%d seconds\n", timeDiff.tv_sec, timeDiff.tv_nsec);
    timeTaken->tv_sec = timeDiff.tv_sec;
    timeTaken->tv_nsec = timeDiff.tv_nsec;

    fflush(stdout);

    return returnvalue;
}


struct timespec diff(struct timespec start, struct timespec end)
{
    struct timespec temp;
    if ((end.tv_nsec-start.tv_nsec)<0) {
        temp.tv_sec = end.tv_sec-start.tv_sec-1;
        temp.tv_nsec = (1000000000+end.tv_nsec)-start.tv_nsec;
    } else {
        temp.tv_sec = end.tv_sec-start.tv_sec;
        temp.tv_nsec = end.tv_nsec-start.tv_nsec;
    }
    return temp;
}


/**
 *This is just to demo encryption times, the actuall methods used in tis should not be addopted as a final solution
 */
int main()
{

    //1048576 = 1mb
    u_int32_t kb = 1024; //bits;
    u_int64_t mb = 1024 * kb;
    const u_int8_t noOfFiles = 5;
    const u_int8_t noOfTests = 5;

    struct timespec encryptTimes[noOfTests][noOfFiles];
    struct timespec decryptTimes[noOfTests][noOfFiles];

    u_int64_t sizes[5] = {(500*kb),mb,(mb*5),(mb*15),(mb*30)}; // Create the sizes of the files to be written

    createFiles(sizes,noOfFiles);

    u_int8_t i =0;
    u_int8_t k = 0;

    for(k = 0; k < noOfTests; k++)
    {
        for( i = 0; i < noOfFiles; i++)
        {

            struct timespec encryptTime;
            if(encryptFile(i,&encryptTime) ==-1)
            {

                printf("Failed to open encrypted files ensure that the file encryption has been run first!");
            }
            else
            {
                encryptTimes[k][i]= encryptTime;

                struct timespec decryptTime;

                if(decryptfile(i,&decryptTime) == -1)
                {
                    printf("failed to open encrypted file to perform decryption!");
                }
                else
                {
                    decryptTimes[k][i] = decryptTime;
                }

            }
        }
    }

    for(i = 0; i < noOfFiles; i++)
    {
        printf("\nTime taken to encrypt file size of %i bytes:\n",sizes[i]);
     struct timespec encryptTime;

        for(k = 0; k < noOfTests; k++)
        {
            encryptTime = encryptTimes [k][i];

                printf("%d.%d\n", encryptTime.tv_sec, encryptTime.tv_nsec);
        }
    }

    for(i = 0; i < noOfFiles; i++)
    {
        printf("\nTime taken to decrypt file size of %i bytes:\n",sizes[i]);
     struct timespec decryptTime;

        for(k = 0; k < noOfTests; k++)
        {
            decryptTime = decryptTimes [k][i];

                printf("%i.%i \n", decryptTime.tv_sec, decryptTime.tv_nsec);
        }
    }
    return 0;
}

最佳答案

这可能与 Linux 内核缓存有关。我建议在运行测试之前清理它们:

echo 3 | sudo tee /proc/sys/vm/drop_caches

附言您可以使用 time 命令来节省一些代码来测量执行时间。

关于c - 加密性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21230832/

相关文章:

android - BitmapFactory 无法对 CipherInputStream 解码两次

c - SocketCAN连续读写

c - 在c中打印字符串指针

algorithm - 如何检查其中存储的无限自然数的8个文件之和是否能被8整除?

python - 如何快速创建不替换总体的随机样本?

encryption - Bouncy CaSTLe 的加密级别是多少

c++ - 帮忙解决这个问题吗?

c - C中的递归结构定义,错误 "forward declaration"

python - 如何在 Python 3 中将迭代过程扩展到大尺寸

SQL 使用 SSL 加密单个连接