C 为什么这段代码不能生成正确的散列?
我不得不用C语言编写一个小小的解密程序,从一个文件(这里是“resource.bin”)强制获取一个密钥,然后用这个文件用DES-EDE对另一个文件(这里是“rom_dump.bin”)进行解密。正确密钥的指示是,解密的文件内容以一个以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上完成的。可在此处找到这些文件: 现在,解密工作正常,
\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