【问题标题】:Comparing SHA Checksum values in C比较 C 中的 SHA 校验和值
【发布时间】:2015-06-07 01:09:39
【问题描述】:

我正在做一个用 C 语言创建 shell 的任务。程序必须读取一个配置文件,其中列出了 shell 中允许的命令。同样在此配置文件中,对于允许的每个命令,它的 sha1 校验和值也被列出。示例行如下所示:(该文件还有其他数据)

... other data ....
* /bin/ls 3848bdeada63dc59d2117a6ca1348fe0981ad2fc

当用户键入命令时,程序必须检查该命令是否在配置文件中。如果命令在列表中,则程序必须检索它的 sha1 sum 值,然后计算给定文件的 sha1 sum 值并比较它们。

我在比较这些值时遇到问题。我从文件中读取 sha1 值并将其存储在 char *pointer 中。稍后,我使用 SHA1() 来计算校验和值。但是 SHA1 返回的值是 unsigned char *pointer。而且我不知道如何比较这些值。

所以,我的问题是,我应该更改读取数据的方式吗?(考虑到该文件中还有其他数据)。如何比较这两个校验和值?

(我已经发布了另一个问题 here 这是这个问题的一部分,但是在获得 cmets 之后,我意识到我的问题有所不同)。

以下是代码的一些相关部分。

读取数据:

/** CODE DELETED */
while(fgets(line,MAXLINE,confFPtr) != NULL ){

    /** CODE DELTED */

    /** if a command line then process the command */
    else if(line[0] == CMNDSTARTER){
        char *pathCommand = NULL;               /** stores path+command string */
        char *sha = NULL;                       /** stores sha string */

        const char *separator = " ";    /** delimiter between * command sha */
        char *arrayCommand[2];          /** stores path in one index and command in another string */

        /** tokenize the string */
        strtok(line,separator);
        pathCommand = strtok(NULL,separator);
        sha = strtok(NULL,separator);

        /** Remove trailing space from end of hash */
        sha = preProcess(sha);  


        /** separate pathcommand into path and command */
        getPathCmd(arrayCommand,pathCommand);

        /** add to list */
        /** List is a linked list */
        if(!addToList(cmdList,arrayCommand,sha)){

            printError("Silent Exit: couldn't add to list");
            exit(1);
        }


    }

COMPUTING CHECKSUM FOR FILE(用户输入的命令)

    while(1){


    /**
     * Read commands
     */
    if(emitPrompt){
        printf("%s",prompt);
        fflush(stdout);
    }

    if((fgets(cmdLine, MAXLINE, stdin) == NULL) && ferror(stdin))
        printError("fgets error");

    /** if ctrl-d pressed exit */
    if(feof(stdin)){
        fflush(stdout);
        exit(0);
    }

    /**
     * Remove trailing \n and preceding white space from user command
     */
    processedCmdLine =  preProcess(cmdLine);

    /** If no command, continue */
    if(*processedCmdLine == 0)
        continue;
    /** check if the command entered by user is in the list of allowed commands */
    struct CMDList *s = searchList(cmdList,processedCmdLine);

    /** if command was in the list, run checksum on the file and compare it with the stored checksum value */
    if(s != NULL){

        unsigned char hash[SHA_DIGEST_LENGTH];
        SHA1(processedCmdLine, sizeof(processedCmdLine),hash);


    }

}

CMDList 结构

struct CMDList{

char *command;
char *path;
char *hash;
struct CMDList *next;

};

【问题讨论】:

    标签: c sha unsigned-char


    【解决方案1】:

    你需要使用

    memcmp(hash1, hash2, SHA_DIGEST_LENGTH)
    

    您的hash1hash2char* 还是unsigned char* 或它们的任何组合都没有关系。尽管为了保持一致性,最好让它们具有相同的类型:

    struct CMDList{
      ....
      unsigned char* hash;
      ...
    };
    

    由于 sha1 哈希是固定长度的,你也可以使用

      unsigned char hash[SHA_DIGEST_LENGTH];
    

    并保存动态分配。

    还要注意 SHA_DIGEST_LENGTH 是 20,但 3848bdeada63dc59d2117a6ca1348fe0981ad2fc 是 40 个字符的字符串。您需要先将可读的哈希值转换为二进制表示,然后才能使用它们。

    【讨论】:

    • 关于将哈希值转换为二进制表示的第二个建议,您能详细说明一下吗?谢谢,
    • 观察哈希字符串每个字符包含一个 ASCII 十六进制数字。您需要将每对此类数字转换为 0 到 255 范围内的单个无符号整数值,并将这些值存储在哈希数组中。
    【解决方案2】:

    我稍微更改了我的代码(代码可见here)。问题是我以不同的形式存储校验和值。来自文件的校验和值是纯文本,而计算校验和将返回一个无符号字符。所以我决定将返回的校验和值转换为纯文本表示,然后使用strncmp() 进行比较。可以看到here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 2017-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多