首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenSSL只加密/解密前7个左右的字符?

OpenSSL只加密/解密前7个左右的字符?
EN

Stack Overflow用户
提问于 2016-04-30 06:14:30
回答 1查看 621关注 0票数 0

我在获得两个使用openssl加密和解密消息的程序时遇到了一些小麻烦。这两个程序编译和运行良好,但解密似乎只解密了我的plaintext.txt文件的前7个左右字符。

使文件加密和解密后,从命令行调用如下.

./enc -i plaintext.txt -o cipher.txt -p密码

./dec i- cipher.txt -o decrypt.txt -p密码

plaintext.txt输入是。这是要保密的东西

decrypt.txt输出是。我是}?w,

这是附件.c(加密)

代码语言:javascript
复制
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bio.h>
#include <openssl/evp.h>

/* AES-GCM test data from NIST public test vectors */

static const unsigned char gcm_iv[] = {
    0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84
};

unsigned char * aes_gcm_encrypt(unsigned char *pt, long size, unsigned char *myCipher, unsigned char *out)
{
    EVP_CIPHER_CTX *ctx;
    int outlen, tmplen;
    unsigned char outbuf[1024];
  //  printf("AES GCM Encrypt:\n");
//    printf("Plaintext:\n");
  //  BIO_dump_fp(stdout, pt, size);
    ctx = EVP_CIPHER_CTX_new();
    /* Set cipher type and mode */
    EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
    /* Set IV length if default 96 bits is not appropriate */
   // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(out), NULL);
    /* Initialise key and IV */
    EVP_EncryptInit_ex(ctx, NULL, NULL, out, gcm_iv);
    /* Encrypt plaintext */
    EVP_EncryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));
    /* Output encrypted block */
  //  printf("Ciphertext:\n");
  //  BIO_dump_fp(stdout, outbuf, size);
    /* Finalise: note get no output for GCM */
    EVP_EncryptFinal_ex(ctx, outbuf, &outlen);


    EVP_CIPHER_CTX_free(ctx);
    return myCipher = outbuf;
}


    extern int errno;

int main(int argc, char **argv)
{

    int ITERATION = 10000;
    FILE * fp;
    int errnum;
    long size;  
    unsigned char *pass;
    int len;
    pass = argv[6];


    fp = fopen(argv[2], "a+");
    if (fp == NULL)
    {
        errnum = errno;
        fprintf(stderr, "Value of errno: %d\n", errno);
        perror("error printed by perror");
        fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
    }

    fseek(fp, 0, SEEK_END);
    size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    unsigned char * buff;   
    buff = (unsigned char*) malloc(sizeof(unsigned char)*size + 1);
    memset(buff, '\0', sizeof(unsigned char)*size + 1);
    fread(buff, 1, size, fp);

    int SHA1_LEN = 30;
    unsigned char* out = (unsigned char*)calloc(SHA1_LEN, sizeof(unsigned char));
    //int SALT_LEN = 5;
    //RAND_bytes(salt, SALT_LEN);

    pass = argv[6];
    printf("Test print of pass: %s\n", pass);   
    PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), NULL, 0, ITERATION, SHA1_LEN, out);

    printf("PASSWORD ENCRYPT: ");   
    printf("%s\n", out);

    unsigned char *myCipher;

    myCipher = aes_gcm_encrypt(buff, size, myCipher, out);

    //printf("%s\n", myCipher);
    fclose(fp);

    fp = fopen(argv[4], "w+");
    if (fp == NULL)
    {
        errnum = errno;
        fprintf(stderr, "Value of errno: %d\n", errno);
        perror("error printed by perror");
        fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
    }

    fputs(myCipher, fp);

    printf("CIPHER TEXT: %s\n", myCipher);

    printf("\n");   
    fclose(fp); 


    return 0;
}

这是dec.c (解密)

代码语言:javascript
复制
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bio.h>
#include <openssl/evp.h>


static const unsigned char gcm_iv[] = {
    0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84
};

unsigned char * aes_gcm_decrypt(unsigned char *pt, long size, unsigned char *myPlainText, unsigned char *out)
{
    EVP_CIPHER_CTX *ctx;
    int outlen, tmplen, rv;
    unsigned char outbuf[1024];
    //printf("AES GCM Derypt:\n");
    //printf("Ciphertext:\n");
    //BIO_dump_fp(stdout, pt, size);
    ctx = EVP_CIPHER_CTX_new();
    /* Select cipher */
    EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
    /* Set IV length, omit for 96 bits */
  //  EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL);
    /* Specify key and IV */
    EVP_DecryptInit_ex(ctx, NULL, NULL, out, gcm_iv);

    /* Decrypt plaintext */
    EVP_DecryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));
    /* Output decrypted block */
  //  printf("Plaintext:\n");
    //BIO_dump_fp(stdout, outbuf, size);

    rv = EVP_DecryptFinal_ex(ctx, outbuf, &outlen);
    EVP_CIPHER_CTX_free(ctx);
    return myPlainText = outbuf;

}

    extern int errno;

int main(int argc, char **argv)
{

    int ITERATION = 10000;
    FILE * fp;
    int errnum;
    long size;  
    unsigned char *pass;
    int len;
    pass = argv[6];


    fp = fopen(argv[2], "a+");
    if (fp == NULL)
    {
        errnum = errno;
        fprintf(stderr, "Value of errno: %d\n", errno);
        perror("error printed by perror");
        fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
    }

    fseek(fp, 0, SEEK_END);
    size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    unsigned char * buff;   
    buff = (unsigned char*) malloc(sizeof(unsigned char)*size + 1);
    memset(buff, '\0', sizeof(unsigned char)*size + 1);
    fread(buff, 1, size, fp);

    int SHA1_LEN = 30;
    unsigned char* out = (unsigned char*)calloc(SHA1_LEN, sizeof(unsigned char));

    pass = argv[6];
    printf("Test print of pass: %s\n", pass);   
    PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), NULL, 0, ITERATION, SHA1_LEN, out);

    printf("PASSWORD ENCRYPT: ");   
    printf("%s\n", out);

    unsigned char *myPlainText;

    myPlainText =  aes_gcm_decrypt(buff, size, myPlainText, out);
    fclose(fp);

    fp = fopen(argv[4], "w+");
    if (fp == NULL)
    {
        errnum = errno;
        fprintf(stderr, "Value of errno: %d\n", errno);
        perror("error printed by perror");
        fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
    }

    fputs(myPlainText, fp);

    printf("PLAINTEXT: %s\n", myPlainText); 
    printf("\n");   
    fclose(fp); 


    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-30 06:33:31

在不了解ssl的情况下,我猜这些调用

EVP_EncryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));

EVP_DecryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));

应该有pt所指向的大小,而不是指针的大小。

EVP_EncryptUpdate(ctx, outbuf, &outlen, pt, ptlen);

EVP_DecryptUpdate(ctx, outbuf, &outlen, pt, ptlen);

其中ptlen是缓冲区pt指向的大小。

看着openssl手册证实了我的猜测:

EVP_EncryptUpdate()从缓冲区中加密inl字节,并将加密版本写入out。可以多次调用此函数来加密连续的数据块。写入的数据量取决于加密数据的块对齐方式:因此,写入的数据量可能是从零字节到(inl + cipher_block_size - 1)的任意值,因此out应该包含足够的空间。写入的实际字节数放在outl中。

EVP_DecryptInit_ex()、EVP_DecryptUpdate()和EVP_DecryptFinal_ex()是相应的解密操作。如果启用了填充并且未正确格式化最后一个块,EVP_DecryptFinal()将返回一个错误代码。参数和限制与加密操作相同,但如果启用填充,则传递给EVP_DecryptUpdate()的解密数据缓冲区应该有足够的空间容纳(inl + cipher_block_size)字节,除非密码块大小为1,在这种情况下,inl字节就足够了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36951474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档