为什么这段代码不能生成正确的哈希?

时间:2015-01-31 08:57:03

标签: c linux encryption hash hashcode

我不得不在C中编写一个小的解密程序来强制一个文件中的密钥,这里是“resource.bin”,并使用DES-EDE来解密另一个文件,这里是“rom_dump.bin”。正确密钥的指示是解密的文件内容以由\0终止的十位数字开头。之后,解密的内容应该写入另一个文件,这里是“decrypted.bin”,文件应该用ECDSA(函数EVP_ecdsa())进行散列。所有这些都是在SUSE Linux上完成的。这些文件可以在这里找到:

https://spideroak.com/browse/share/see/stack/StackOverflow/

现在,解密工作正常,但哈希值不正确:

a493af52c1a000fcace34de8b0a74a9cf9067ffc

但即使经过几天的搜索,我也找不到问题。这可能只是我正在监督的事情,但如果有人能帮助我,我会很高兴。提前谢谢。

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <unistd.h>
#include <fcntl.h>

const unsigned long long bufferSize = 0x10000;

int checkOutput(unsigned char *output) {
    int i = 0;
    for (i; i < 6; i++) {
        if (!isdigit(output[i])) {
            return 0;
        }
    }

    return 1;
}

void changeKey(unsigned char *key, unsigned char *fileContent, long keyLength,
long initVectorLength) {
    int i = 0;
    for (i; i < keyLength + initVectorLength; i++) {
        key[i] = fileContent[i];
    }
}

void toHashFile(FILE *hashFile, unsigned char *hash, int hashLength) {
    int i = 0;
    for (i; i < hashLength; i++) {
        fprintf(hashFile, "%02x", hash[i]);
    }

    fprintf(hashFile, "\n");
}

void toOutputFile(FILE *fileName, unsigned char *output,
int outputLength) {
    int i = 0;
    for (i; i < outputLength; i++) {
        fprintf(fileName, "%c", output[i]);
    }

    fprintf(fileName, "\n");
}

void writeToFile(const unsigned char *fileName, unsigned char *content,
int contentLength,
void (*functionPointer)(FILE *, unsigned char *, int)) {
    FILE *file = fopen(fileName, "w");
    (*functionPointer)(file, content, contentLength);
    fclose(file);
}

void createHash(unsigned char *hash, unsigned char *output, int length,
int *hashLength) {
    EVP_MD_CTX hashContext;
    EVP_MD_CTX_init(&hashContext);
    EVP_DigestInit(&hashContext, EVP_ecdsa());
    EVP_DigestUpdate(&hashContext, output, length);
    EVP_DigestFinal(&hashContext, hash, hashLength);
}

int main() {
    /* output stuff */
    unsigned char keyAndInitVector[24] = {0x00};
    unsigned char output[bufferSize];
    unsigned char outputFinal[bufferSize];
    int outputLength;

    /* determine key length and init vector */
    int initVectorLength = EVP_CIPHER_iv_length(EVP_des_ede_ecb());
    int keyLength = EVP_CIPHER_key_length(EVP_des_ede_ecb());

    /* read resource files */
    unsigned char romFileContent[bufferSize];
    unsigned char resFileContent[bufferSize];
    int romLength = read(open("rom_dump.bin", O_RDONLY), romFileContent,
        bufferSize);
    int resLength = read(open("resource.bin", O_RDONLY), resFileContent,
        bufferSize);

    /* init context */
    EVP_CIPHER_CTX cypherContext;
    EVP_CIPHER_CTX_init(&cypherContext);

    int i = 0, j;
    int isDecrypted = 0;

    for (i; i < romLength - (keyLength + initVectorLength) &&
    !isDecrypted; i++) {
        changeKey(keyAndInitVector, romFileContent + i, keyLength,
            initVectorLength);

        EVP_DecryptInit(&cypherContext, EVP_des_ede_ecb(),
            keyAndInitVector, keyAndInitVector + keyLength);
        EVP_DecryptUpdate(&cypherContext, output, &outputLength,
            resFileContent, resLength);

        for (j = 0; j < resLength; j++) {
            if (checkOutput(output + j) == 1) {
                isDecrypted = 1;
                break;
            }
        }
    }

    if (isDecrypted) {
        int postfixLength;
        EVP_DecryptFinal(&cypherContext, outputFinal,
            &postfixLength);

        writeToFile("decrypted.bin", output,
            outputLength + postfixLength, &toOutputFile);

        int hashLength = 0;
        unsigned char hash[bufferSize];
        createHash(hash, output, outputLength + postfixLength,
            &hashLength);
        writeToFile("hash.txt", hash, hashLength, &toHashFile);
    }

    EVP_CIPHER_CTX_cleanup(&cypherContext);
    return isDecrypted;
}

2 个答案:

答案 0 :(得分:1)

您无法连接输出和后缀输出。当您编写解密文件并计算哈希时,您正在使用输出的第一个 outputLength 字节加上 postfixLength 字节的垃圾。

main 中删除 outputFinal 数组声明,最后写下:

    if (isDecrypted) {
        int postfixLength;
->        EVP_DecryptFinal(&cypherContext, output + outputLength,
            &postfixLength);

        ...

答案 1 :(得分:1)

toOutputFile()功能中,您向文件添加了\n,但在main()中您没有散列文件,而是output。< / p>

这意味着,您的decrypted.bin还有一个\n,而output中不存在这种情况,这就是为什么在对文件进行哈希处理时,哈希值与您创建的哈希值不同该计划。