리눅스 환경에서 kisa에서 제공하는 c sha256 적용중 질문드립니다.

sincerely0의 이미지

http://seed.kisa.or.kr/iwt/ko/bbs/EgovReferenceDetail.do?bbsId=BBSMSTR_000000000002&nttId=79

해당 페이지 kisa에서 제공하는 c 모듈을 제공 받아 컴파일 중입니다.

샘플코드가 없어서 모듈만 받고 샘플 코드는 작성하고 해당 명령어로 컴파일 하였습니다.

=========== 샘플 코드 (sample_main.c) ===========================

#include <stdio.h>
#include <string.h>
 
typedef unsigned char   BYTE;
typedef unsigned int    UINT;
 
int main()
{
        BYTE pong[32];
        BYTE nong[32];
        UINT pong_leng = 0;
        int i = 0;
 
        memset(pong, 0x00, sizeof(pong));
        memset(nong, 0x00, sizeof(nong));
 
        printf("평문데이터:");
 
        gets(pong);
        pong_leng = strlen(pong);
 
        SHA256_Encrpyt(pong, pong_leng, nong);
 
        printf("해쉬데이터:");
 
        for (i = 0; i < 32; i++)
        {
                printf("%02X", nong[i]);
        }
 
        printf("\n");
 
 
        return 0;
}

=================================================================

해당 명령어로 컴파일 하였습니다.

gcc -o sha256_test KISA_SHA256.h KISA_SHA256.c sample_main.c -DUSER_LITTLE_ENDIAN

=================================================================
실행 결과 입니다.

$ ./sha256_test
평문데이터:abc
해쉬데이터:D392283157A5BDE4462EE1753AD30E32D7159B3230B8673108BA07ECCFB4C745

매뉴얼에 있는 샘플 그림과 해쉬데이터가 다른값이 나옵니다.
해쉬는 따로 키값이 없어서 평문이 같으면 같은 해쉬데이터가 나와야하는걸로 알고 있는데 제가 잘못 알고 있는걸까요?
방법이 잘못되었으면 어디서부터 확인해서 처리해야 할지 도움 요청 드립니다.

감사합니다.

익명 사용자의 이미지

일단 한 번 찍어보겠습니다.

기대는 너무 많이 하지 마시고, gets(pong); 대신 fgets(pong, 32, stdin);로 바꿔보시고 결과 확인해보세요.
이 편이 프로그램 안정성 측면에서도 더 낫고(버퍼 오버런은 유명한 취약점이죠) 의도치 않게 개행문자가 달라붙는 문제도 없어집니다.

잘 되면 다행이고, 못 되면 모른 척 하시면 됩니다(무책임)

익명 사용자의 이미지

진지하게 검토하려다가, 도저히 제 능력으로는 범접할 수 없는 코드여서 그만 뒀습니다. 저 그냥 나갈게요. ㅜㅜ.

void SHA256_Process( OUT SHA256_INFO *Info, IN const BYTE *pszMessage, IN UINT uDataLen )
{
	if ((Info->uLowLength += (uDataLen << 3)) < 0)
		Info->uHighLength++;

이 부분이 특히 인상깊었어요. uLowLength 멤버와 uDataLen이 모두 unsigned이므로, 최소한 제가 외우고 있는 integer promotion rule에 의하면 그 결과 역시 unsigned이고, 절대 0보다 작을 수 없습니다. C언어 표준 뒤적거려서 규칙을 확인해 볼 수도 있겠지만 귀찮아서 그냥 gcc한테 물어보니 저랑 똑같은 생각을 하는 모양이네요. 최적화된 코드에서 if문 body가 통째로 날라가있는 걸 보면. -_-;

결코 무시할 수 없는 로직의 일부가 의도치 않게 날라가는 셈인데, 나중에 SHA256_Close에서 uHighLength 값을 쓴다는 걸 생각해 보면 뭐 여기서 이미 제대로 나오긴 틀렸죠. 평문이 짧아서 uHighLength가 어차피 0일 경우엔 상관 없겠지만.

한 가지 더. typedef unsigned long ULONG;이라고 해놓고 sizeof(ULONG) == 4로 암묵적으로 가정 및 하드코딩해 놓은 코드가 계속 보이는데, x86_64 gcc에선 unsigned long이 8바이트인거 아시죠? 이거 때문에 해당 플랫폼에서 로직 와장창 깨집니다. 배열 초기화가 덜 되서 매번 다른 결과가 나오는 거죠. _MSC_VER를 검사하는 등 "호환성을 위한 코드인 척" 하긴 했지만 정작 코드를 제대로 견고하게 짜지는 않았다는 증거입니다. 최소한 이 문제를 바로잡으면(typedef uint32_t ULONG; 으로 고치는 등) 매번 동일한 결과가 나오기는 합니다. 근데 그래도 여전히 예제와 다르네요.

아몰랑. -_-. 다른 거 쓰세요. 이거 디버그한다고 삽질하느니 아예 새로 짜는 게 낫겠네요.

hernian의 이미지

저도 원인을 한참 찾다가 포기하고

오픈소스로 구현 했습니다.

bushi의 이미지

endian 가지고 헤메는 전통을 이어받고, int 와 long 을 구분못하는 새로운 혁신을 이뤄냈네요.

[schoi0@sel-schoi0-d2 net]$ diff -urNp KISA_bug KISA_new/|iconv -f euckr -t utf8
diff -urNp KISA_bug/KISA_SHA256.c KISA_new/KISA_SHA256.c
--- KISA_bug/KISA_SHA256.c	2016-05-02 20:18:34.241007575 +0900
+++ KISA_new/KISA_SHA256.c	2016-05-02 20:17:16.460366901 +0900
@@ -29,12 +29,12 @@ const UINT SHA256_K[64] =
 #define ENDIAN_REVERSE_ULONG(dwS)	( (ROTL_ULONG((dwS),  8) & 0x00ff00ff)	\
 									| (ROTL_ULONG((dwS), 24) & 0xff00ff00) )
 
-#if defined(BIG_ENDIAN)
+#if defined(USER_BIG_ENDIAN)
 	#define BIG_B2D(B, D)		D = *(ULONG_PTR)(B)
 	#define BIG_D2B(D, B)		*(ULONG_PTR)(B) = (ULONG)(D)
 	#define LITTLE_B2D(B, D)	D = ENDIAN_REVERSE_ULONG(*(ULONG_PTR)(B))
 	#define LITTLE_D2B(D, B)	*(ULONG_PTR)(B) = ENDIAN_REVERSE_ULONG(D)
-#elif defined(LITTLE_ENDIAN)
+#elif defined(USER_LITTLE_ENDIAN)
 	#define BIG_B2D(B, D)		D = ENDIAN_REVERSE_ULONG(*(ULONG_PTR)(B))
 	#define BIG_D2B(D, B)		*(ULONG_PTR)(B) = ENDIAN_REVERSE_ULONG(D)
 	#define LITTLE_B2D(B, D)	D = *(ULONG_PTR)(B)
@@ -62,7 +62,7 @@ const UINT SHA256_K[64] =
 //						  ChainVar		- 연쇄변수의 포인터 변수
 // o 출력				: 
 //*********************************************************************************************************************************
-void SHA256_Transform(ULONG_PTR Message, ULONG_PTR ChainVar)
+void SHA256_Transform(ULONG_PTR Message, UINT_PTR ChainVar)
 {
 	ULONG a, b, c, d, e, f, g, h, T1, X[64];
 	ULONG j;
@@ -73,7 +73,7 @@ void SHA256_Transform(ULONG_PTR Message,
 	h = T1 + Sigma0(a) + Maj(a, b, c);						\
 }
 
-#if defined(BIG_ENDIAN)
+#if defined(USER_BIG_ENDIAN)
 	#define GetData(x)	x
 #else
 	#define GetData(x)	ENDIAN_REVERSE_ULONG(x)
@@ -182,7 +182,7 @@ void SHA256_Close( OUT SHA256_INFO *Info
 	else
 		memset((UCHAR_PTR)Info->szBuffer + Index, 0, (SINT)(SHA256_DIGEST_BLOCKLEN - Index - 8));
 
-#if defined(LITTLE_ENDIAN)
+#if defined(USER_LITTLE_ENDIAN)
 	Info->uLowLength = ENDIAN_REVERSE_ULONG(Info->uLowLength);
 	Info->uHighLength = ENDIAN_REVERSE_ULONG(Info->uHighLength);
 #endif
diff -urNp KISA_bug/KISA_SHA256.h KISA_new/KISA_SHA256.h
--- KISA_bug/KISA_SHA256.h	2016-05-02 20:18:12.730830398 +0900
+++ KISA_new/KISA_SHA256.h	2016-05-02 20:16:41.347077674 +0900
@@ -24,24 +24,18 @@ extern "C" {
 #define INOUT
 #endif
 
-#undef BIG_ENDIAN
-#undef LITTLE_ENDIAN
-
 #if defined(USER_BIG_ENDIAN)
-	#define BIG_ENDIAN
 #elif defined(USER_LITTLE_ENDIAN)
-	#define LITTLE_ENDIAN
 #else
 	#if 0
-		#define BIG_ENDIAN
 	#elif defined(_MSC_VER)
-		#define LITTLE_ENDIAN
+		#define USER_LITTLE_ENDIAN
 	#else
 		#error
 	#endif
 #endif
 
-typedef unsigned long ULONG;
+typedef unsigned int ULONG;
 typedef ULONG* ULONG_PTR;
 
 typedef unsigned int UINT;
세벌의 이미지

kisa에서 받은 거면 kisa에 물어보는 게 낫지 않나요? KISA가 인터넷진흥원 맞나요? 그곳에서 인터넷을 얼마나 진흥시켰는지는 잘 모르겠지만.

sincerely0의 이미지

당황스러운 소스 였습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.