【问题标题】:Why does this code not produce a correct hash?为什么这段代码不能产生正确的哈希?
【发布时间】:2015-01-31 08:57:03
【问题描述】:

我必须用 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;
}

【问题讨论】:

  • PS:有谁知道我可以测试这个哈希的正确性的网站吗?我找到了几乎所有已知哈希算法的哈希网站,除了我必须使用的这个。
  • 您是在 Windows 上还是在适当的操作系统上执行此操作?如果是 Windows,则需要将 O_BINARY 添加到 open 调用中。
  • 这是在 SUSE Linux 上完成的。该文件使用-lcrypto 编译。就像我说的,解密成功了,也生成了一个哈希值,但是它是错误的。
  • 好吧 - 没关系 - 这只是一个远射。不过,您可能希望在问题中添加 Linux 标记。
  • 我可以为您提供错误的哈希值(刚刚更新),但是由于我没有找到任何网站来测试正确的哈希值,所以我不能给您,抱歉。至于文件,我可以粘贴它们,但是它们包含许多不可打印的标志,所以我宁愿将它们链接起来。等一下。

标签: c linux encryption hash hashcode


【解决方案1】:

在您的toOutputFile() 函数中,您将\n 添加到您的文件中,但在main() 中您不会散列文件,而是output

这意味着,您的 decrypted.bin 有一个额外的 \n,这在您的 output 中不存在,这就是为什么在对文件进行哈希处理时,哈希值将与您使用该程序创建的哈希值不同。

【讨论】:

  • 天哪!我怎么可能忽略了!?!?!非常感谢您指出这一点! :D
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
相关资源
最近更新 更多