测试文件按预期读取,但完整代码不起作用 [英] Tested File Reads as expected but on Complete Code Not Working

查看:94
本文介绍了测试文件按预期读取,但完整代码不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经测试了以下代码来读取 tester.txt 文件并输出了我的期望,但是,当我在我的完整代码中插入类似的代码时,它只是停留在:"来自文件的数据:"为什么它没有输出我的期望?

I have tested the following code to read the tester.txt file and it outputted my expectation, however, when I inserted similar code in my complete code, it just stuck at: "Data from the file:" Why it is not outputting my expectation?

#include <stdio.h>
#include <stdlib.h>

char c[1000];
FILE *fptr;

int fileReader(){
    if ((fptr = fopen("tester.txt", "r")) == NULL) {
        printf("Error! File cannot be opened.");
        // Program exits if the file pointer returns NULL.
        exit(1);
    }
    // reads text until newline is encountered
    fscanf(fptr, "%[^\n]", c);
    fclose(fptr);
}
int main() {

    fileReader();
    printf("Data from the file:\n%s", c);
    char* anotherone = (char*) c; 
    printf(anotherone);

    return 0;
}

另一个读取文件的代码:

Another code to read file:

int fileReader() {

   fp = fopen("tester.txt", "r");
   fscanf(fp, "%s", c);
   fclose(fp);

}

完整代码为:

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int success = 0;

void handleOpenSSLErrors(void)
{
    ERR_print_errors_fp(stderr);
    abort();
}

unsigned char* decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv ){

    EVP_CIPHER_CTX *ctx;
    unsigned char *plaintexts;
    int len;
    int plaintext_len;
    
    unsigned char* plaintext = malloc(ciphertext_len);
    bzero(plaintext,ciphertext_len);

  
    if(!(ctx = EVP_CIPHER_CTX_new())) handleOpenSSLErrors();

    
    if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
        handleOpenSSLErrors();

  
    EVP_CIPHER_CTX_set_key_length(ctx, EVP_MAX_KEY_LENGTH);

    if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        handleOpenSSLErrors();
   
    plaintext_len = len;
    
    // return 1 if decryption successful, otherwise 0
    if(1 == EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) 
        success = 1;
    plaintext_len += len;

   
    /* Add the null terminator */
    plaintext[plaintext_len] = 0;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);
    //delete [] plaintext;
    return plaintext;
}


size_t calcDecodeLength(char* b64input) {
    size_t len = strlen(b64input), padding = 0;

    if (b64input[len-1] == '=' && b64input[len-2] == '=') //last two chars are =
        padding = 2;
    else if (b64input[len-1] == '=') //last char is =
        padding = 1;
    return (len*3)/4 - padding;
}

void Base64Decode( char* b64message, unsigned char** buffer, size_t* length) {

    
    BIO *bio, *b64;  // A BIO is an I/O strean abstraction

    int decodeLen = calcDecodeLength(b64message);
    *buffer = (unsigned char*)malloc(decodeLen + 1);
    (*buffer)[decodeLen] = '\0';

    bio = BIO_new_mem_buf(b64message, -1);
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_push(b64, bio);

    //BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer
    *length = BIO_read(bio, *buffer, strlen(b64message));
    BIO_free_all(bio);
}

void initAES(const unsigned char *pass, unsigned char* salt, unsigned char* key, unsigned char* iv )
{
    //initialisatio of key and iv with 0
    bzero(key,sizeof(key)); 
    bzero(iv,sizeof(iv));
  
    EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt, pass, strlen(pass), 1, key, iv);
}


int checkPlaintext(char* plaintext, char* result){

    int length = 10; // we just check the first then characters
    return strncmp(plaintext, result, length);

}

char *cas[1000];
FILE *fptr;

int fileReader(){
    if ((fptr = fopen("tester.txt", "r")) == NULL) {
        printf("Error! File cannot be opened.");
        // Program exits if the file pointer returns NULL.
        exit(1);
    }
    // reads text until newline is encountered
    fscanf(fptr, "%[^\n]", cas);
    fclose(fptr);

}

int main (void)
{
    
    fileReader();
    printf("Data from the file:\n%s", cas);
    char* ciphertext_base64 = (char*) cas;   

    char* plaintext = "to be or not to be is the question";
    char dict[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        
    int decryptedtext_len, ciphertext_len, dict_len;

    // cipher (binary) pointer and length
    size_t cipher_len; // size_t is sizeof(type)
    unsigned char* ciphertext;
  
    unsigned char salt[8];
    
    ERR_load_crypto_strings();
    
    Base64Decode(ciphertext_base64, &ciphertext, &cipher_len);

    unsigned char key[16];
    unsigned char iv[16];

    unsigned char plainpassword[] = "00000";
    unsigned char* password = &plainpassword[0];
    
    // retrive the slater from ciphertext (binary)
    if (strncmp((const char*)ciphertext,"Salted__",8) == 0) { // find the keyword "Salted__"
        
        memcpy(salt,&ciphertext[8],8);
        ciphertext += 16; 
        cipher_len -= 16;
    
    }

    dict_len = strlen(dict);
    
    time_t begin = time(NULL);


    for(int i=0; i<dict_len; i++)
        for(int j=0; j<dict_len; j++)
            for(int k=0; k<dict_len; k++)
                for(int l=0; l<dict_len; l++)
                    for(int m=0; m<dict_len; m++){
                        *password = dict[i];
                        *(password+1) = dict[j];
                        *(password+2) = dict[k];
                        *(password+3) = dict[l];
                        *(password+4) = dict[m];

                        
                        initAES(password, salt, key, iv);
                        unsigned char* result = decrypt(ciphertext, cipher_len, key, iv);
                        
                        if (success == 1){
                            if(checkPlaintext(plaintext, result)==0){
                                
                                printf("Password is %s\n", password);
                                
                                time_t end = time(NULL);
                                printf("Time elpased is %ld seconds", (end - begin));
 
                                return 0;
                            }

                        }
                       
                        free(result);
                        
                        
                    }

            
    // Clean up
    
    EVP_cleanup();
    ERR_free_strings();


    return 0;
}

推荐答案

  1. char *cas[1000]; 应该是 char cas[1000];,我会说这是主要问题,您使用的是指针数组如果是字符数组,这很可能是导致程序失败的原因.
  1. char *cas[1000]; should be char cas[1000];, I would say this is the main issue, you are using an array of pointers as if it was a character array, this is very likely what's causing your program to fail.


  1. 修复bzero,将数组的大小作为参数传递.当您在 initAES() 中使用 sizeof(key) 时,您实际得到的是指针的大小,而不是它指向的容器的大小.如何找到sizeof"(指向数组的指针)?
  1. Fix bzero, pass the size of the array as argument. When you use sizeof(key) in initAES(), what you are actually getting is the size of the pointer, not the size of the container it points to. More oh this in How to find the 'sizeof' (a pointer pointing to an array)?

您可以使用宏将数组的大小添加为全局常量:

You can add size of the array as a global constant with a macro:

#define SIZE 16 // size of the arrays

//...

void initAES(const unsigned char *pass, unsigned char* salt, unsigned char* key, unsigned char* iv )
{
    //initialisatio of key and iv with 0
    bzero(key, SIZE); 
    bzero(iv, SIZE);
  
    EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt, pass, strlen(pass), 1, key, iv);
}

您可以使用它来定义 main 中的大小,使您的代码更加一致.

You can use it to define the size in main making your code more consistent.

int main (void)
{
    //...
    unsigned char key[SIZE];
    unsigned char iv[SIZE];
    //...
}


  1. 如果你不想让 fileReader 返回一个 int,那么最好让 fileReadervoid 返回类型.
  1. For good measure make fileReader have void return type if you don't want it to return an int.

我总是建议全面使用编译器警告,最好将警告视为错误.

I always advise the use of compiler warnings at full blast and preferably to treat warnings as errors.

这篇关于测试文件按预期读取,但完整代码不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆