C 为什么这段代码不能生成正确的散列?

C 为什么这段代码不能生成正确的散列?,c,linux,encryption,hash,hashcode,C,Linux,Encryption,Hash,Hashcode,我不得不用C语言编写一个小小的解密程序,从一个文件(这里是“resource.bin”)强制获取一个密钥,然后用这个文件用DES-EDE对另一个文件(这里是“rom_dump.bin”)进行解密。正确密钥的指示是,解密的文件内容以一个以\0结尾的十位数开始。之后,解密的内容应该写入另一个文件,这里是“decrypted.bin”,并且应该使用ECDSA(使用函数EVP_ECDSA())对该文件进行哈希处理。所有这些都是在SUSE Linux上完成的。可在此处找到这些文件: 现在,解密工作正常,

我不得不用C语言编写一个小小的解密程序,从一个文件(这里是“resource.bin”)强制获取一个密钥,然后用这个文件用DES-EDE对另一个文件(这里是“rom_dump.bin”)进行解密。正确密钥的指示是,解密的文件内容以一个以
\0
结尾的十位数开始。之后,解密的内容应该写入另一个文件,这里是“decrypted.bin”,并且应该使用ECDSA(使用函数
EVP_ECDSA()
)对该文件进行哈希处理。所有这些都是在SUSE Linux上完成的。可在此处找到这些文件:

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

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;
}
#包括
#包括
#包括
#包括
#包括
const unsigned long bufferSize=0x10000;
int checkOutput(无符号字符*输出){
int i=0;
对于(i;i<6;i++){
如果(!isdigit(输出[i])){
返回0;
}
}
返回1;
}
void changeKey(无符号字符*键、无符号字符*文件内容、长键长度、,
长初始向量长度){
int i=0;
对于(i;i
toOutputFile()
函数中,您向文件中添加了一个
\n
,但在
main()
中,您不会对文件进行散列,而是对
输出进行散列


这意味着,您的
已解密。bin
有一个额外的
\n
,它不存在于您的
输出中
,这就是为什么对文件进行散列时,散列将与您使用该程序创建的散列不同。

PS:有人知道一个网站,我可以在那里测试这个散列的正确性吗?我找到了几乎所有已知的散列算法的散列站点,除了我必须使用的这个。你是在Windows上还是在合适的操作系统上这样做的?如果是Windows,则需要将
O_BINARY
添加到
open
调用中。这是在SUSE Linux上完成的。该文件是使用
-lcrypto
编译的。正如我所说的,解密是有效的,也会生成一个散列值,但这是错误的。好吧,没关系,这只是一个很长的机会。不过,你可能想在问题中添加一个Linux标记。我可以为你提供错误的哈希(刚刚更新),但由于我没有找到任何网站来测试正确的哈希,我不能给你,抱歉。至于文件,我可以粘贴它们,但它们包含许多无法打印的符号,所以我宁愿链接它们。等等,天哪!我怎么会忽视这一点!?!?!非常感谢您指出这一点!:D