⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aesxam.cpp

📁 算法从speakfs提取
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            if(rlen > 0 && rlen < BLOCK_LEN)
            {
                // move the previous ciphertext to top half of double buffer
                // since rlen bytes of this are output last
                for(i = 0; i < BLOCK_LEN; ++i)
                    dbuf[i + BLOCK_LEN] = dbuf[i];

                // read last part of plaintext into bottom half of buffer
                if(fread(dbuf, 1, rlen, fin) != rlen)
                    return READ_ERROR;

                // clear the remainder of the bottom half of buffer
                for(i = 0; i < BLOCK_LEN - rlen; ++i)
                    dbuf[rlen + i] = 0;

                // do CBC chaining from previous ciphertext
                for(i = 0; i < BLOCK_LEN; ++i)
                    dbuf[i] ^= dbuf[i + BLOCK_LEN];

                // encrypt the final block
                aes_enc_blk((unsigned char*)(char const*)dbuf, (unsigned char*)dbuf, ctx);

                // set the length of the final write
                len = rlen + BLOCK_LEN; rlen = 0;
            }

            // write the encrypted block
            if(fwrite(dbuf, 1, len, fout) != len)
                return WRITE_ERROR;
        }
    }

    return 0;
}

int decfile(FILE *fin, FILE *fout, aes_ctx *ctx, const char* ifn, const char* ofn)
{   char            buf1[BLOCK_LEN], buf2[BLOCK_LEN], dbuf[2 * BLOCK_LEN];
    char            *b1, *b2, *bt;
    fpos_t          flen;
    unsigned long   i, len, rlen;

    // find the file length

    fseek(fin, 0, SEEK_END);
    fgetpos(fin, &flen); 
    rlen = file_len(flen);
    // reset to start
    fseek(fin, 0, SEEK_SET);

    if(rlen <= 2 * BLOCK_LEN)
    {   // if the original file length is less than or equal to 16 bytes

        // read the bytes of the file and verify length
        len = (unsigned long)fread(dbuf, 1, 2 * BLOCK_LEN, fin);
        rlen -= len;
        if(rlen > 0)
            return READ_ERROR;

        // set the original file length
        len -= BLOCK_LEN;

        // decrypt from position len to position len + BLOCK_LEN
        aes_dec_blk((unsigned char*)(char const*)(dbuf + len), (unsigned char*)(dbuf + BLOCK_LEN), ctx);

        // undo CBC chaining
        for(i = 0; i < len; ++i)
            dbuf[i] ^= dbuf[i + BLOCK_LEN];

        // output decrypted bytes
        if(fwrite(dbuf, 1, len, fout) != len)
            return WRITE_ERROR; 
    }
    else
    {   // we need two input buffers because we have to keep the previous
        // ciphertext block - the pointers b1 and b2 are swapped once per
        // loop so that b2 points to new ciphertext block and b1 to the
        // last ciphertext block

        rlen -= BLOCK_LEN; b1 = buf1; b2 = buf2;

        // input the IV
        if(fread(b1, 1, BLOCK_LEN, fin) != BLOCK_LEN)
            return READ_ERROR;
        
        // read the encrypted file a block at a time
        while(rlen > 0 && !feof(fin))
        {
            // input a block and reduce the remaining byte count
            len = (unsigned long)fread(b2, 1, BLOCK_LEN, fin);
            rlen -= len;

            // verify the length of the read operation
            if(len != BLOCK_LEN)
                return READ_ERROR;

            // decrypt input buffer
            aes_dec_blk((unsigned char*)(char const*)b2, (unsigned char*)dbuf, ctx);

            // if there is only one more block do ciphertext stealing
            if(rlen > 0 && rlen < BLOCK_LEN)
            {
                // read last ciphertext block
                if(fread(b2, 1, rlen, fin) != rlen)
                    return READ_ERROR;

                // append high part of last decrypted block
                for(i = rlen; i < BLOCK_LEN; ++i)
                    b2[i] = dbuf[i];

                // decrypt last block of plaintext
                for(i = 0; i < rlen; ++i)
                    dbuf[i + BLOCK_LEN] = dbuf[i] ^ b2[i];

                // decrypt last but one block of plaintext
                aes_dec_blk((unsigned char*)(char const*)b2, (unsigned char*)dbuf, ctx);

                // adjust length of last output block
                len = rlen + BLOCK_LEN; rlen = 0;
            }

            // unchain CBC using the last ciphertext block
            for(i = 0; i < BLOCK_LEN; ++i)
                dbuf[i] ^= b1[i];

            // write decrypted block
            if(fwrite(dbuf, 1, len, fout) != len)
                return WRITE_ERROR;

            // swap the buffer pointers
            bt = b1, b1 = b2, b2 = bt;
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{   FILE        *fin = 0, *fout = 0;
    char        *cp, ch, key[32];
    int         i, by, key_len, err = 0;
    aes_ctx     ctx[1];

    if(argc != 5 || toupper(*argv[3]) != 'D' && toupper(*argv[3]) != 'E')
    {
        printf("usage: aesxam in_filename out_filename [d/e] key_in_hex\n");
        err = -1; goto exit;
    }

    ctx->n_rnd = 0; // ensure all flags are initially set to zero
    ctx->n_blk = 0;
    cp = argv[4];   // this is a pointer to the hexadecimal key digits
    i = 0;          // this is a count for the input digits processed

    while(i < 64 && *cp)        // the maximum key length is 32 bytes and
    {                           // hence at most 64 hexadecimal digits
        ch = toupper(*cp++);    // process a hexadecimal digit
        if(ch >= '0' && ch <= '9')
            by = (by << 4) + ch - '0';
        else if(ch >= 'A' && ch <= 'F')
            by = (by << 4) + ch - 'A' + 10;
        else                    // error if not hexadecimal
        {
            printf("key must be in hexadecimal notation\n");
            err = -2; goto exit;
        }

        // store a key byte for each pair of hexadecimal digits
        if(i++ & 1)
            key[i / 2 - 1] = by & 0xff;
    }

    if(*cp)
    {
        printf("The key value is too long\n");
        err = -3; goto exit;
    }
    else if(i < 32 || (i & 15))
    {
        printf("The key length must be 32, 48 or 64 hexadecimal digits\n");
        err = -4; goto exit;
    }

    key_len = i / 2;

    if(!(fin = fopen(argv[1], "rb")))   // try to open the input file
    {
        printf("The input file: %s could not be opened\n", argv[1]);
        err = -5; goto exit;
    }

    if(!(fout = fopen(argv[2], "wb")))  // try to open the output file
    {
        printf("The input file: %s could not be opened\n", argv[1]);
        err = -6; goto exit;
    }

    if(toupper(*argv[3]) == 'E') // encryption in Cipher Block Chaining mode
    {
        aes_enc_key((unsigned char*)(char const*)key, key_len, ctx);

        err = encfile(fin, fout, ctx, argv[1], argv[2]);
    }
    else                         // decryption in Cipher Block Chaining mode
    {
        aes_dec_key((unsigned char*)(char const*)key, key_len, ctx);

        err = decfile(fin, fout, ctx, argv[1], argv[2]);
    }
exit:
    if(err == READ_ERROR)
        printf("Error reading from input file: %s\n", argv[1]);

    if(err == WRITE_ERROR)
        printf("Error writing to output file: %s\n", argv[2]);

    if(fout)
        fclose(fout);

    if(fin)
        fclose(fin);

    return err;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -