Assistance with openssl blowfish simple example inserting garbage characters

前端 未结 2 506
星月不相逢
星月不相逢 2020-12-15 14:37

If you have a good example of simply encrypting a file using openssl that is better than this one that I am having issues with I would be very grateful.

Up

相关标签:
2条回答
  • 2020-12-15 14:44

    Since you say the error seems to be coming at the decryption stage, I would look with suspicion on these lines:

    if (EVP_DecryptUpdate (&ctx, outbuf, &olen, inbuff, n) != 1)
    ...
    
    if (EVP_DecryptFinal (&ctx, outbuf + olen, &tlen) != 1)
    ...
    

    How big is the memory allocated for outbuf in relation to what the decryption functions will be putting in them? Are you sure outbuf + olen is not going to take you past the end of the buffer?

    0 讨论(0)
  • 2020-12-15 14:58

    The error is in the way the EVP_DecryptFinal and EVP_EncryptFinal are called. These functions should be called in the end of the for cycle, also the final part where to olen is added tlen and written again was duplicating output. Below is the final working version:

    #include <openssl/blowfish.h>
    #include <openssl/evp.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #define IP_SIZE 1024
    #define OP_SIZE 1024 + EVP_MAX_BLOCK_LENGTH
    unsigned char   key[16];
    unsigned char   iv[8];
    
    int
    generate_key()
    {
        int             i, fd;
        if ((fd = open("/dev/random", O_RDONLY)) == -1)
            perror("open error");
    
        if ((read(fd, key, 16)) == -1)
            perror("read key error");
    
        if ((read(fd, iv, 8)) == -1)
            perror("read iv error");
    
        printf("128 bit key:\n");
        for (i = 0; i < 16; i++)
            printf("%4d ", key[i]);
    
        printf("\nInitialization vector\n");
        for (i = 0; i < 8; i++)
            printf("%4d ", iv[i]);
        printf("\n");
    
    
        close(fd);
        return 0;
    }
    
    int
    do_decrypt(int infd, int outfd)
    {
        unsigned char           *inbuff, *outbuf;
        int             olen=0, tlen=0, n=0;
        EVP_CIPHER_CTX  ctx;
        EVP_CIPHER_CTX_init(&ctx);
        EVP_DecryptInit(&ctx, EVP_bf_cbc(), key, iv);
    
        outbuf = (unsigned char *) malloc(sizeof(unsigned char) * OP_SIZE);
        inbuff = (unsigned char *) malloc(sizeof(unsigned char) * IP_SIZE);
    
        /* keep reading until a break */
        for (;;) {
            memset(inbuff, 0, IP_SIZE);
            if ((n = read(infd, inbuff, IP_SIZE)) == -1) {
                perror("read error");
                break;
            } else if (n == 0)
                break;
    
            memset(outbuf, 0, OP_SIZE);
    
            if (EVP_DecryptUpdate(&ctx, outbuf, &olen, inbuff, n) != 1) {
                printf("error in decrypt update\n");
                return 0;
            }
            if ((n = write(outfd, outbuf, olen)) == -1)
                perror("write error");
        }
    
        tlen=0;
        if (EVP_DecryptFinal(&ctx, outbuf + olen, &tlen) != 1) {
            perror("error in decrypt final");
            return 0;
        }
    
        if ((n = write(outfd, outbuf+olen, tlen)) == -1)
            perror("write error");
    
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 1;
    }
    
    int
    do_encrypt(int infd, int outfd)
    {
        unsigned char           *inbuff, *outbuf;
    
        int             olen=0, tlen=0, n=0;
        EVP_CIPHER_CTX  ctx;
        EVP_CIPHER_CTX_init(&ctx);
        EVP_EncryptInit(&ctx, EVP_bf_cbc(), key, iv);
    
        outbuf = (unsigned char *) malloc(sizeof(unsigned char) * OP_SIZE);
        inbuff = (unsigned char *) malloc(sizeof(unsigned char) * IP_SIZE);
    
        for (;;) {
            memset(inbuff, 0, IP_SIZE);
    
            if ((n = read(infd, inbuff, IP_SIZE)) == -1) {
                perror("read error");
                break;
            } else if (n == 0)
                break;
    
            if (EVP_EncryptUpdate(&ctx, outbuf, &olen, inbuff, n) != 1) {
                printf("error in encrypt update\n");
                return 0;
            }
    
            if ((n = write(outfd, outbuf, olen)) == -1)
                perror("write error");
        }
        tlen=0;
        if (EVP_EncryptFinal(&ctx, outbuf + olen, &tlen) != 1) {
            printf("error in encrypt final\n");
            return 0;
        }
    
        if ((n = write(outfd, outbuf+olen, tlen)) == -1)
            perror("write error");
    
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 1;
    }
    
    int
    main(int argc, char *argv[])
    {
        int             flags1 = 0, flags2 = 0, outfd, infd;
        mode_t          mode;
    
        memset(key, 0, 16);
        memset(iv, 0, 8);
        memset(&mode, 0, sizeof(mode));
    
        flags1 = flags1 | O_RDONLY;
        flags2 = flags2 | O_RDONLY;
        flags2 = flags2 | O_WRONLY;
        flags2 = flags2 | O_CREAT;
    
        mode = mode | S_IRUSR;
        mode = mode | S_IWUSR;
    
    
        generate_key();
    
    
        if ((infd = open(argv[1], flags1, mode)) == -1)
            perror("open input file error");
    
        if ((outfd = open(argv[2], flags2, mode)) == -1)
            perror("open output file error");
    
        do_encrypt(infd, outfd);
    
        close(infd);
        fsync(outfd);
        close(outfd);
    
        if ((infd = open(argv[2], flags1, mode)) == -1)
            perror("open output file error");
    
        if ((outfd = open(argv[3], flags2, mode)) == -1)
            perror("open output file error");
    
        do_decrypt(infd, outfd);
    
        close(infd);
        fsync(infd);
        close(outfd);
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题