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

📄 aescrypt.c

📁 linux下完成任意文件的AES加密. 口令可变,加密稳定迅速.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  AES Crypt for Linux *  Copyright (C) 2007, 2008 * *  Contributors: *      Glenn Washburn <crass@berlios.de> *      Paul E. Jones <paulej@packetizer.com> *      Mauro Gilardi <galvao.m@gmail.com> * * This software is licensed as "freeware."  Permission to distribute * this software in source and binary forms is hereby granted without a * fee.  THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM * THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING, * BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. * */#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h> // getopt#include <assert.h>#include <stdlib.h> // malloc#include <time.h> // time#include <iconv.h> // iconv stuff#include <langinfo.h> // nl_langinfo#include <errno.h> // errno#include "aescrypt.h"#include "password.h"#include "version.h"/* *  encrypt_stream * *  This function is called to encrypt the open data steam "infp". */int encrypt_stream(FILE *infp, FILE *outfp, char* passwd, int passlen){    aes_context                 aes_ctx;    sha256_context              sha_ctx;    aescrypt_hdr                aeshdr;    sha256_t                    digest;    unsigned char               IV[16];    unsigned char               iv_key[48];    int                         i, j, n;    unsigned char               buffer[32];    unsigned char               ipad[64], opad[64];    time_t                      current_time;    pid_t                       process_id;    FILE                        *randfp = NULL;    unsigned char               tag_buffer[256];    // Open the source for random data.  Note that while the entropy    // might be lower with /dev/urandom than /dev/random, it will not    // fail to produce something.  Also, we're going to hash the result    // anyway.    if ((randfp = fopen("/dev/urandom", "r")) == NULL)    {        perror("Error open /dev/urandom:");        return  -1;    }    // Create the 16-bit IV and 32-bit encryption key    // used for encrypting the plaintext file.  We do    // not trust the rand() function, so we improve on    // that by also hashing the random digits and using    // only a portion of the hash.  This IV and key    // generation could be replaced with any good random    // source of data.    memset(iv_key, 0, 48);    for (i=0; i<48; i+=16)    {        memset(buffer, 0, 32);        sha256_starts(&sha_ctx);        for(j=0; j<256; j++)        {            if ((n = fread(buffer, 1, 32, randfp)) != 32)            {                fprintf(stderr, "Error: Couldn't read from /dev/urandom : %d\n",n);                fclose(randfp);                return  -1;            }            sha256_update(&sha_ctx, buffer, 32);        }        sha256_finish(&sha_ctx, digest);        memcpy(iv_key+i, digest, 16);    }    // Write an AES signature at the head of the file, along    // with the AES file format version number.    buffer[0] = 'A';    buffer[1] = 'E';    buffer[2] = 'S';    buffer[3] = (unsigned char) 0x02;   // Version 2    buffer[4] = '\0';                   // Reserved for version 0    if (fwrite(buffer, 1, 5, outfp) != 5)    {        fprintf(stderr, "Error: Could not write out header data\n");        fclose(randfp);        return  -1;    }    // Write out the CREATED-BY tag    j = 11 +                   // "CREATED-BY\0"        strlen(PROG_NAME) +    // Program name        1 +                    // Space        strlen(PROG_VERSION);  // Program version ID    // Our extension buffer is only 256 octets long, so    // let's not write an extension if it is too big    if (j < 256)    {        buffer[0] = '\0';        buffer[1] = (unsigned char) (j & 0xff);        if (fwrite(buffer, 1, 2, outfp) != 2)        {            fprintf(stderr, "Error: Could not write tag to AES file (1)\n");            fclose(randfp);            return  -1;        }        strncpy(tag_buffer, "CREATED_BY", 255);        tag_buffer[255] = '\0';        if (fwrite(tag_buffer, 1, 11, outfp) != 11)        {            fprintf(stderr, "Error: Could not write tag to AES file (2)\n");            fclose(randfp);            return  -1;        }        sprintf(tag_buffer, "%s %s", PROG_NAME, PROG_VERSION);        j = strlen(tag_buffer);        if (fwrite(tag_buffer, 1, j, outfp) != j)        {            fprintf(stderr, "Error: Could not write tag to AES file (3)\n");            fclose(randfp);            return  -1;        }    }    // Write out the "container" extension    buffer[0] = '\0';    buffer[1] = (unsigned char) 128;    if (fwrite(buffer, 1, 2, outfp) != 2)    {        fprintf(stderr, "Error: Could not write tag to AES file (4)\n");        fclose(randfp);        return  -1;    }    bzero(tag_buffer, 128);    if (fwrite(tag_buffer, 1, 128, outfp) != 128)    {        fprintf(stderr, "Error: Could not write tag to AES file (5)\n");        fclose(randfp);        return  -1;    }    // Write out 0x0000 to indicate that no more extensions exist    buffer[0] = '\0';    buffer[1] = '\0';    if (fwrite(buffer, 1, 2, outfp) != 2)    {        fprintf(stderr, "Error: Could not write tag to AES file (6)\n");        fclose(randfp);        return  -1;    }    // We will use an initialization vector comprised of the current time    // process ID, and random data, all hashed together with SHA-256.    current_time = time(NULL);    for(i = 0; i < 8; i++)    {        buffer[i] = (unsigned char)                        (current_time >> (i * 8));    }    process_id = getpid();    for(i = 0; i < 8; i++)    {        buffer[i+8] = (unsigned char)                        (process_id >> (i * 8));    }    sha256_starts(  &sha_ctx);    sha256_update(  &sha_ctx, buffer, 16);    for (i=0; i<256; i++)    {        if (fread(buffer, 1, 32, randfp) != 32)        {            fprintf(stderr, "Error: Couldn't read from /dev/random\n");            fclose(randfp);            return  -1;        }        sha256_update(  &sha_ctx,                        buffer,                        32);    }    sha256_finish(  &sha_ctx, digest);    memcpy(IV, digest, 16);    // We're finished collecting random data    fclose(randfp);    // Write the initialization vector to the file    if (fwrite(IV, 1, 16, outfp) != 16)    {        fprintf(stderr, "Error: Could not write out initialization vector\n");        return  -1;    }        // Hash the IV and password 8192 times    memset(digest, 0, 32);    memcpy(digest, IV, 16);    for(i=0; i<8192; i++)    {        sha256_starts(  &sha_ctx);        sha256_update(  &sha_ctx, digest, 32);        sha256_update(  &sha_ctx,                        (unsigned char*)passwd,                        (unsigned long)passlen);        sha256_finish(  &sha_ctx,                        digest);    }    // Set the AES encryption key    aes_set_key(&aes_ctx, digest, 256);    // Set the ipad and opad arrays with values as    // per RFC 2104 (HMAC).  HMAC is defined as    //   H(K XOR opad, H(K XOR ipad, text))    memset(ipad, 0x36, 64);    memset(opad, 0x5C, 64);    for(i=0; i<32; i++)    {        ipad[i] ^= digest[i];        opad[i] ^= digest[i];    }    sha256_starts(&sha_ctx);    sha256_update(&sha_ctx, ipad, 64);    // Encrypt the IV and key used to encrypt the plaintext file,    // writing that encrypted text to the output file.    for(i=0; i<48; i+=16)    {        // Place the next 16 octets of IV and key buffer into        // the input buffer.        memcpy(buffer, iv_key+i, 16);        // XOR plain text block with previous encrypted        // output (i.e., use CBC)        for(j=0; j<16; j++)        {            buffer[j] ^= IV[j];        }        // Encrypt the contents of the buffer        aes_encrypt(&aes_ctx, buffer, buffer);                // Concatenate the "text" as we compute the HMAC        sha256_update(&sha_ctx, buffer, 16);        // Write the encrypted block        if (fwrite(buffer, 1, 16, outfp) != 16)        {            fprintf(stderr, "Error: Could not write iv_key data\n");            return  -1;        }                // Update the IV (CBC mode)        memcpy(IV, buffer, 16);    }    // Write the HMAC    sha256_finish(&sha_ctx, digest);    sha256_starts(&sha_ctx);    sha256_update(&sha_ctx, opad, 64);    sha256_update(&sha_ctx, digest, 32);    sha256_finish(&sha_ctx, digest);    // Write the encrypted block    if (fwrite(digest, 1, 32, outfp) != 32)    {        fprintf(stderr, "Error: Could not write iv_key HMAC\n");        return  -1;    }    // Re-load the IV and encryption key with the IV and    // key to now encrypt the datafile.  Also, reset the HMAC    // computation.    memcpy(IV, iv_key, 16);    // Set the AES encryption key    aes_set_key(&aes_ctx, iv_key+16, 256);    // Set the ipad and opad arrays with values as    // per RFC 2104 (HMAC).  HMAC is defined as    //   H(K XOR opad, H(K XOR ipad, text))    memset(ipad, 0x36, 64);    memset(opad, 0x5C, 64);    for(i=0; i<32; i++)    {        ipad[i] ^= iv_key[i+16];        opad[i] ^= iv_key[i+16];    }    // Wipe the IV and encryption mey from memory    memset(iv_key, 0, 48);    sha256_starts(&sha_ctx);    sha256_update(&sha_ctx, ipad, 64);    while ((n = fread(buffer, 1, 16, infp)) > 0)    {        // XOR plain text block with previous encrypted        // output (i.e., use CBC)        for(i=0; i<16; i++)        {            buffer[i] ^= IV[i];        }        // Encrypt the contents of the buffer        aes_encrypt(&aes_ctx, buffer, buffer);                // Concatenate the "text" as we compute the HMAC        sha256_update(&sha_ctx, buffer, 16);        // Write the encrypted block        if (fwrite(buffer, 1, 16, outfp) != 16)        {            fprintf(stderr, "Error: Could not write to output file\n");            return  -1;        }                // Update the IV (CBC mode)        memcpy(IV, buffer, 16);        // Assume this number of octets is the file modulo        aeshdr.last_block_size = n;    }    // Check to see if we had a read error    if (n < 0)    {        fprintf(stderr, "Error: Couldn't read input file\n");        return  -1;    }    // Write the file size modulo    buffer[0] = (char) (aeshdr.last_block_size & 0x0F);    if (fwrite(buffer, 1, 1, outfp) != 1)    {        fprintf(stderr, "Error: Could not write the file size modulo\n");        return  -1;    }    // Write the HMAC    sha256_finish(&sha_ctx, digest);    sha256_starts(&sha_ctx);    sha256_update(&sha_ctx, opad, 64);    sha256_update(&sha_ctx, digest, 32);    sha256_finish(&sha_ctx, digest);    if (fwrite(digest, 1, 32, outfp) != 32)    {        fprintf(stderr, "Error: Could not write the file HMAC\n");        return  -1;    }    return 0;}

⌨️ 快捷键说明

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