比较 C 中的 SHA 校验和值
Comparing SHA Checksum values in C
我正在做一项在 C 中创建 shell 的作业。该程序必须读取一个配置文件,其中列出了 shell 中允许的命令。同样在此配置文件中,对于允许的每个命令,还列出了它的 sha1 校验和值。示例行如下所示:(该文件也有其他数据)
... other data ....
* /bin/ls 3848bdeada63dc59d2117a6ca1348fe0981ad2fc
当用户键入命令时,程序必须检查该命令是否在配置文件中。如果命令在列表中,则程序必须检索它的 sha1 总和值,然后计算给定文件的 sha1 总和值并比较两者。
我在比较这些值时遇到问题。我从文件中读取 sha1 值并将其存储在 char *指针中。稍后,我使用 SHA1() 来计算校验和值。但是 SHA1 返回的值是 unsigned char *pointer。而且我不知道如何比较这些值。
所以,我的问题是,我是否应该更改读取数据的方式?(考虑到该文件中还有其他数据)。我如何比较这两个校验和值?
(我已经发布了另一个问题 here 是这个问题的一部分,但在收到评论后,我意识到我的问题有所不同)。
下面是代码的一些相关部分。
正在读取数据:
/** 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;
};
你需要使用
memcmp(hash1, hash2, SHA_DIGEST_LENGTH)
无论您的 hash1
和 hash2
是 char*
还是 unsigned char*
或它们的任意组合都没有关系。尽管为了保持一致性,最好让它们具有相同的类型:
struct CMDList{
....
unsigned char* hash;
...
};
由于 sha1 哈希是固定长度的,您也可以使用
unsigned char hash[SHA_DIGEST_LENGTH];
并保存动态分配。
另请注意,SHA_DIGEST_LENGTH 是 20,但 3848bdeada63dc59d2117a6ca1348fe0981ad2fc
是 40 个字符的字符串。您需要将可读的哈希值转换为二进制表示才能使用它们。
我稍微改了一下代码(代码可以看). The problem was I was storing checksum values in different forms. The checksum value from file is in plain text, while calculating the checksum would return an unsigned char. So I decided to convert the returned checksum value to its plain text reprsentation, and then compare them using strncmp()
. As it can be seen .
我正在做一项在 C 中创建 shell 的作业。该程序必须读取一个配置文件,其中列出了 shell 中允许的命令。同样在此配置文件中,对于允许的每个命令,还列出了它的 sha1 校验和值。示例行如下所示:(该文件也有其他数据)
... other data ....
* /bin/ls 3848bdeada63dc59d2117a6ca1348fe0981ad2fc
当用户键入命令时,程序必须检查该命令是否在配置文件中。如果命令在列表中,则程序必须检索它的 sha1 总和值,然后计算给定文件的 sha1 总和值并比较两者。
我在比较这些值时遇到问题。我从文件中读取 sha1 值并将其存储在 char *指针中。稍后,我使用 SHA1() 来计算校验和值。但是 SHA1 返回的值是 unsigned char *pointer。而且我不知道如何比较这些值。
所以,我的问题是,我是否应该更改读取数据的方式?(考虑到该文件中还有其他数据)。我如何比较这两个校验和值?
(我已经发布了另一个问题 here 是这个问题的一部分,但在收到评论后,我意识到我的问题有所不同)。
下面是代码的一些相关部分。
正在读取数据:
/** 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;
};
你需要使用
memcmp(hash1, hash2, SHA_DIGEST_LENGTH)
无论您的 hash1
和 hash2
是 char*
还是 unsigned char*
或它们的任意组合都没有关系。尽管为了保持一致性,最好让它们具有相同的类型:
struct CMDList{
....
unsigned char* hash;
...
};
由于 sha1 哈希是固定长度的,您也可以使用
unsigned char hash[SHA_DIGEST_LENGTH];
并保存动态分配。
另请注意,SHA_DIGEST_LENGTH 是 20,但 3848bdeada63dc59d2117a6ca1348fe0981ad2fc
是 40 个字符的字符串。您需要将可读的哈希值转换为二进制表示才能使用它们。
我稍微改了一下代码(代码可以看strncmp()
. As it can be seen