programing

How to use SHA1 hashing in C programming

telecom 2023. 10. 17. 20:00
반응형

How to use SHA1 hashing in C programming

I am trying to write a C program that proves SHA1 is nearly collision free, but I cannot figure out how to actually create the hash for my input values. I just need to create the hash, and store the hex value into an array. After some Google searches, I've found OpenSSL documentation directing me to use this:

 #include <openssl/sha.h>

 unsigned char *SHA1(const unsigned char *d, unsigned long n,
                  unsigned char *md);

 int SHA1_Init(SHA_CTX *c);
 int SHA1_Update(SHA_CTX *c, const void *data,
                  unsigned long len);
 int SHA1_Final(unsigned char *md, SHA_CTX *c);

I believe I should be using either unsigned char *SHA1 or SHA1_Init, but I am not sure what the arguments would be, given x is my input to be hashed. Would someone please clear this up for me? Thanks.

데이터를 한 번에 모두 저장할 경우에는SHA1함수:

// The data to be hashed
char data[] = "Hello, world!";
size_t length = strlen(data);

unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(data, length, hash);
// hash now contains the 20-byte SHA-1 hash

If, on the other hand, you only get your data one piece at a time and you want to compute the hash as you receive that data, then use the other functions:

// Error checking omitted for expository purposes

// Object to hold the current state of the hash
SHA_CTX ctx;
SHA1_Init(&ctx);

// Hash each piece of data as it comes in:
SHA1_Update(&ctx, "Hello, ", 7);
...
SHA1_Update(&ctx, "world!", 6);
// etc.
...
// When you're done with the data, finalize it:
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1_Final(hash, &ctx);

They're two different ways to achieve the same thing.

구체적으로, 당신이 사용하는 것은SHA_Init,그리고나서SHA_Update필요한 횟수만큼 데이터를 전달한 다음SHA_Final소화를 시키거나, 아니면 당신.SHA1.

두 가지 모드를 사용하는 이유는 큰 파일을 해시할 때 파일을 청크로 읽는 것이 일반적이기 때문입니다. 그 대안은 많은 메모리를 사용하기 때문입니다.그러므로, 그들을 추적하는 것은SHA_CTX- SHA 컨텍스트를 통해 이 문제를 해결할 수 있습니다.알고리즘은 내부적으로도 이 모델에 적합합니다. 즉, 데이터가 한 번에 블록 단위로 전달됩니다.

SHA방법은 상당히 간단해야 합니다.다른 것들은 다음과 같이 작동합니다.

unsigned char md[SHA_DIGEST_LENGTH];
SHA_CTX context;
int SHA1_Init(&context);

for ( i = 0; i < numblocks; i++ )
{
    int SHA1_Update(&context, pointer_to_data, data_length);
}
int SHA1_Final(md, &context);

결정적으로, 마지막에md는 16진수 표현이 아닌 이진 다이제스트를 포함합니다. 문자열이 아니므로 문자열로 사용하면 안 됩니다.

첫번째 함수 (SHA1())이 더 높은 수준의 것이고, 아마도 당신이 원하는 것일 것입니다.의사는 사용법에 대해 꽤 명확하게 알고 있습니다.d입력입니다.n그것의 크기와md는 결과가 배치되는 곳입니다(할당합니다).

As for the other 3 functions - these are lower level and I'm pretty sure they are internally used by the first one. They are better suited for larger inputs that need to be processed in a block-by-block manner.

둘 중 하나를 사용해야 한다고 생각합니다.unsigned char *SHA1아니면SHA1_Init...

For later versions of the OpenSSL library, like 1.0.2 and 1.1.0, the project recommends using the EVP interface. An example of using EVP Message Digests with SHA256 is available on the OpenSSL wiki:

#define handleErrors abort

EVP_MD_CTX *ctx;

if((ctx = EVP_MD_CTX_create()) == NULL)
    handleErrors();

if(1 != EVP_DigestInit_ex(ctx, EVP_sha256(), NULL))
    handleErrors();

unsigned char message[] = "abcd .... wxyz";
unsinged int message_len = sizeof(message);

if(1 != EVP_DigestUpdate(ctx, message, message_len))
    handleErrors();

unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int digest_len = sizeof(digest);

if(1 != EVP_DigestFinal_ex(ctx, digest, &digest_len))
    handleErrors();

EVP_MD_CTX_destroy(ctx);

Adam Rosenfield의 답변은 괜찮지만 크기가 아닌 strlen을 사용하면 null terminator를 포함하여 해시가 계산됩니다.이 경우에는 괜찮을 수도 있지만, 해시를 다른 도구에서 생성된 해시와 비교해야 하는 경우에는 그렇지 않습니다.

// The data to be hashed
char data[] = "Hello, world!";
size_t length = strlen(data);

unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(data, length, hash);
// hash now contains the 20-byte SHA-1 hash

해시를 이렇게 계산합니다.

// Object to hold the current state of the hash
SHA_CTX ctx;
SHA1_Init(&ctx);

// Hash each piece of data as it comes in:
SHA1_Update(&ctx, "Hello, ", 7);
...
SHA1_Update(&ctx, "world!", 6);
// etc.
...
// When you're done with the data, finalize it:
unsigned char tmphash[SHA_DIGEST_LENGTH];
SHA1_Final(tmphash, &ctx);

마지막으로 이렇게 코드로 해시를 인간이 읽을 수 있는 형태로 해독할 수 있습니다.

unsigned char hash[SHA_DIGEST_LENGTH*2];

int i = 0;
for (i=0; i < SHA_DIGEST_LENGTH; i++) {
    sprintf((char*)&(hash[i*2]), "%02x", tmphash[i]);
}
// And print to stdout
printf("Hash: %s\n", hash);

암호를 말하게 두시오.

SQLite 개발 트리에는 SHA1을 전체 데이터베이스에 적용하기 위한 도구의 소스가 들어 있습니다.SHA1 구현을 완료합니다.

그 코드를 연구하는 것이 가능할지도 모릅니다.

ps: SQLite 사용자 정의 기능으로 구현된 SHA1도 있습니다.

언급URL : https://stackoverflow.com/questions/9284420/how-to-use-sha1-hashing-in-c-programming

반응형