2012-02-14 3 views
23

SHA1이 거의 충돌이없는 것으로 증명하는 C 프로그램을 작성하려고하지만 실제로 입력 값에 해시를 만드는 방법을 알 수 없습니다. 해시를 만들고 배열에 16 진수 값을 저장하면됩니다. 일부 Google 검색 후, 나는이 사용하는 저를 지시 OpenSSL이 문서를 발견했습니다 : 내가 서명 숯불의 *의 SHA1 또는 SHA1_Init를 사용해야한다 생각하지만, 내가 인수가 어떻게 될지 확실하지 않다C 프로그래밍에서 SHA1 해싱을 사용하는 방법

#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); 

을 제공 x는 해시 할 입력 값입니다. 누군가 나 한테 이걸 정리 해줄 수 있겠 니? 감사.

+0

입력 값 : 메모리 내 문자열 또는 파일 내용은 무엇입니까? –

+0

나는 배열을 지울 때마다 새로운 해시를 생성하고 끝까지 추가해야하는 생일 공격을 씁니다. 나는 그것을 단순하게 유지하고 i의 가치를 해싱하려고했습니다. 메모리 문자열의 빠른 대답. – spassen

+1

SHA1이 거의 충돌이 없다는 것을 증명한다는 것은 무엇을 의미합니까? SHA1은 160 비트 해시이므로 2^160 개의 가능한 값이 있지만 2^160 개가 넘는 가능한 문자열 (예 : 1MB 미만)이 있으므로 충돌이 많이 발생합니다. 무작위로 생성 된 여러 문자열에서 충돌이 발생했는지 여부를 테스트하기를 원할 경우 중간에 안정적인 응답에 필요한 문자열의 수는 실제적으로 높지 않습니다 (충돌을 일찍 발견하지 않는 한 SHA1은 무시할 정도로 작은 확률). –

답변

39

, 그냥 SHA1 함수를 사용

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

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

다른 한편으로는, 당신은 단지 데이터를 한 번에 한 조각을 얻을 당신은을 계산하려는 경우 이 데이터는 다음 다른 기능을 사용하는 것이 받기로 해시 :

첫 번째 함수 ( SHA1())
// 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); 
+0

sha1 함수를 사용하여 시도했지만 터미널에서 컴파일 할 때 SHA1에 대한 정의되지 않은 참조가 표시됩니다. 나는 다른 것에 대한 불만을 전혀 느끼지 않는다. 내가 뭘 놓쳤는가? – spassen

+7

OpenSSL 런타임 라이브러리와 링크해야합니다. gcc를 사용한다고 가정하면, 링커 명령 행에'-lcrypto'를 추가하십시오. –

+0

어떻게 hmacsha1을 생성합니까? – Cmag

11

두 가지 방법으로 동일한 결과를 얻을 수 있습니다.

특히, 필요하면 중 하나 사용 SHA_Init 다음 SHA_Update 많은 시간 다이제스트, 또는 당신 SHA1을 얻기 위해 다음 SHA_Final을 통해 데이터를 전달하고있다.

두 가지 모드의 이유는 대용량 파일을 해시 할 때 대용량 메모리를 사용하기 때문에 파일을 청크로 읽는 것이 일반적이기 때문입니다. 따라서 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 진수 표현이 포함됩니다 - 그것은 문자열이 아닌 그리고 하나로서 사용할 수 없습니다. 당신이 한 번에 모든 데이터가있는 경우

+0

어떻게 hmacsha1을 생성합니까? – Cmag

+0

@Clustermagnet hmacsha1은 SHA1을 해시로 사용하는 HMAC 알고리즘입니다. 이것은 내 대답과 같은 생각입니다. ([here] (http://www.openssl.org/docs/crypto/hmac.html) 참조), HMAC에 특정한'EVP_MD' 인자는'EVP_sha1() '. –

+0

@Cmag - [EVP 서명 및 확인 | HMAC] (http://wiki.openssl.org/index.php/EVP_Signing_and_Verifying#HMAC)를 참조하십시오. 또한 스택 오버플로에 대한 [OpenSSL에서 HMAC와 EVP 기능 사용] (http://stackoverflow.com/a/20322002/608639)을 참조하십시오. – jww

3

는 높은 수준의 하나입니다, 아마 당신이 원하는 하나입니다. 의사가 사용법을 잘 알고 있습니다. d이 입력되면 n이 크기이고 md은 결과가 배치 된 곳입니다.

다른 3 가지 기능은 낮은 레벨이며 처음에는 내부적으로 사용됩니다. 블록 단위로 처리해야하는 더 큰 입력에 더 적합합니다.

2

은 내가, 1.0.2와 1.1.0과 같은 프로젝트가 EVP 인터페이스를 사용하는 것이 좋습니다 unsigned char *SHA1 또는 SHA1_Init ...에서 OpenSSL 라이브러리의 이후 버전

를 사용한다 생각합니다.SHA256로 EVP Message Digests를 사용하는 예에는 OpenSSL 위키로 볼 수 있습니다 :

#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); 
0

아담 로젠 필드의 대답은 괜찮지 만, 오히려 sizeof 연산자보다 나 strlen 사용, null 종결을 포함하여 계산됩니다 그렇지 않으면 해시. 이 경우에는 괜찮을 지 모르지만 다른 도구에서 생성 된 해시와 해시를 비교해야하는 경우는 아닙니다.

// 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 
관련 문제