stdin
から読み取られた文字列のSHA-256を計算するプログラムを作成しています。 私のプログラムにopenssl/sha.h
が提供する機能を使用しています。私は "普通のハッシュ"と "塩漬けのハッシュ"を実装しました。sizeofまたはstrlenで入力を測定するかどうかによって、SHA-256ハッシュが異なる
ノーマルハッシュ
私は言葉をハッシュした場合password
は、私は次の出力を得る:シェルコマンドの出力で見られるように、正しい
SHA256_Update(&sha256, string, strlen(string)) --> 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
SHA256_Update(&sha256, string, sizeof(string)) --> 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
を
echo -n "password" | sha256sum --> 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
塩漬けハッシュ
は、それから* 2000 13として計算され、26000
(塩が常に同じであることを考慮
complete = salt + string
を得る、別の文字列(塩)の後に入力された文字列を連結し、塩漬けハッシュを実装しようとしました)、私はシェルコマンドに一致する出力を期待:strlen(complete)
を使用して
echo -n "26000password" | sha256sum --> c9bcf6ab867bdff7bf2223407c6a391f5c475fb411f7eae08fb361a671d4fd0d
は私に正しい答えを与える:
SHA256_Update(&sha256, complete, strlen(complete)) --> c9bcf6ab867bdff7bf2223407c6a391f5c475fb411f7eae08fb361a671d4fd0d
しかし、sizeof(complete)
を使用して私に異なる答えを与える:
SHA256_Update(&sha256, complete, sizeof(complete)) --> ef73eaf729a0601f9d99ed0a11ef82ae82ca74042de5a724889f82e4f6e59bb0
だから私は二つの問題があります。
- を第二の場合は、(私は推測
sizeof
代わりにstrlen
の使用である間違って何かを持っていますしかし、それはなぜ2番目の問題があるのか説明していないので、私はいくつかの「一貫性のない状態」について考えています。 - プログラムをもう一度実行すると、プログラムを停止して実行するたびに間違ったハッシュが変わってしまいます。
だから、問題はstrlen
の代わりにsizeof
を使用していると仮定します。私はがそのデータ型を格納するために使用されるバイト数を返すことを知っているので(ポインタは4バイトになります)、strlen
は文字列の長さを返しますが、 2番目のケース。
コードの抜粋
#include <openssl/sha.h>
#define MAX_LENGTH 1024
unsigned long salt;
// Salted ////////////////////////////////
void compute_sha256_with_sizeof_complete(const char *string, char *sha)
{
int i;
char temp[65];
char complete[MAX_LENGTH];
char salt_str[MAX_LENGTH];
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
/* complete = salt_str + string */
if (sprintf(salt_str, "%lu", salt) < 0)
error_handler("compute_sha256 | sprintf");
if (strcpy(complete, salt_str) == NULL)
error_handler("compute_sha256 | strcpy");
if (strcat(complete, string) == NULL)
error_handler("compute_sha256 | strcat");
/* compute sha256 of 'complete' */
if (SHA256_Init(&sha256) == 0)
error_handler("compute_sha256 | SHA256_Init");
if (SHA256_Update(&sha256, complete, sizeof(complete)) == 0)
error_handler("compute_sha256 | SHA256_Update");
if (SHA256_Final(hash, &sha256) == 0)
error_handler("compute_sha256 | SHA256_Final");
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
if ((sprintf(temp + (i * 2), "%02x", hash[i])) < 0)
error_handler("compute_sha256 | sprintf");
temp[64] = 0;
if (strcpy(sha, temp) == NULL)
error_handler("compute_sha256 | strcpy");
printf("SHA256 (sizeof_complete):\t%s\n", sha);
}
void compute_sha256_with_strlen_complete(const char *string, char *sha)
{
int i;
char temp[65];
char complete[MAX_LENGTH];
char salt_str[MAX_LENGTH];
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
/* complete = salt_str + string */
if (sprintf(salt_str, "%lu", salt) < 0)
error_handler("compute_sha256 | sprintf");
if (strcpy(complete, salt_str) == NULL)
error_handler("compute_sha256 | strcpy");
if (strcat(complete, string) == NULL)
error_handler("compute_sha256 | strcat");
/* compute sha256 of 'complete' */
if (SHA256_Init(&sha256) == 0)
error_handler("compute_sha256 | SHA256_Init");
if (SHA256_Update(&sha256, complete, strlen(complete)) == 0)
error_handler("compute_sha256 | SHA256_Update");
if (SHA256_Final(hash, &sha256) == 0)
error_handler("compute_sha256 | SHA256_Final");
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
if ((sprintf(temp + (i * 2), "%02x", hash[i])) < 0)
error_handler("compute_sha256 | sprintf");
temp[64] = 0;
if (strcpy(sha, temp) == NULL)
error_handler("compute_sha256 | strcpy");
printf("SHA256 (strlen_complete):\t%s\n", sha);
}
// Normal ////////////////////////////////
void compute_sha256_with_sizeof_string(const char *string, char *sha)
{
int i;
char temp[65];
char complete[MAX_LENGTH];
char salt_str[MAX_LENGTH];
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
/* complete = salt_str + string */
if (sprintf(salt_str, "%lu", salt) < 0)
error_handler("compute_sha256 | sprintf");
if (strcpy(complete, salt_str) == NULL)
error_handler("compute_sha256 | strcpy");
if (strcat(complete, string) == NULL)
error_handler("compute_sha256 | strcat");
/* compute sha256 of 'string' */
if (SHA256_Init(&sha256) == 0)
error_handler("compute_sha256 | SHA256_Init");
if (SHA256_Update(&sha256, string, sizeof(string)) == 0)
error_handler("compute_sha256 | SHA256_Update");
if (SHA256_Final(hash, &sha256) == 0)
error_handler("compute_sha256 | SHA256_Final");
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
if ((sprintf(temp + (i * 2), "%02x", hash[i])) < 0)
error_handler("compute_sha256 | sprintf");
temp[64] = 0;
if (strcpy(sha, temp) == NULL)
error_handler("compute_sha256 | strcpy");
printf("SHA256 (sizeof_string):\t\t%s\n", sha);
}
void compute_sha256_with_strlen_string(const char *string, char *sha)
{
int i;
char temp[65];
char complete[MAX_LENGTH];
char salt_str[MAX_LENGTH];
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
/* complete = salt_str + string */
if (sprintf(salt_str, "%lu", salt) < 0)
error_handler("compute_sha256 | sprintf");
if (strcpy(complete, salt_str) == NULL)
error_handler("compute_sha256 | strcpy");
if (strcat(complete, string) == NULL)
error_handler("compute_sha256 | strcat");
/* compute sha256 of 'string' */
if (SHA256_Init(&sha256) == 0)
error_handler("compute_sha256 | SHA256_Init");
if (SHA256_Update(&sha256, string, strlen(string)) == 0)
error_handler("compute_sha256 | SHA256_Update");
if (SHA256_Final(hash, &sha256) == 0)
error_handler("compute_sha256 | SHA256_Final");
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
if ((sprintf(temp + (i * 2), "%02x", hash[i])) < 0)
error_handler("compute_sha256 | sprintf");
temp[64] = 0;
if (strcpy(sha, temp) == NULL)
error_handler("compute_sha256 | strcpy");
printf("SHA256 (strlen_string):\t\t%s\n", sha);
}
void match_password(const char *line)
{
char hash[MAX_LENGTH];
salt *= 13;
compute_sha256_with_strlen_complete(line, hash);
compute_sha256_with_sizeof_complete(line, hash);
compute_sha256_with_strlen_string(line, hash);
compute_sha256_with_sizeof_string(line, hash);
}
void read_password_from_stdin(void)
{
char line[MAX_LENGTH];
salt = 2000;
printf("> ");
if (fgets(line, MAX_LENGTH, stdin) == NULL)
error_handler("read_password_from_stdin | fgets");
if (line[strlen(line)-1] == '\n')
line[strlen(line)-1] = '\0';
match_password(line);
}
int main(int argc, char **argv)
{
if (argc != 1)
{
fprintf(stderr, "Usage: %s <no arguments>\n", argv[0]);
return EXIT_FAILURE;
}
while (!feof(stdin))
read_password_from_stdin();
return EXIT_SUCCESS;
}