리눅스 환경에서 kisa에서 제공하는 c sha256 적용중 질문드립니다.
글쓴이: sincerely0 / 작성시간: 월, 2016/05/02 - 4:10오후
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
매뉴얼에 있는 샘플 그림과 해쉬데이터가 다른값이 나옵니다.
해쉬는 따로 키값이 없어서 평문이 같으면 같은 해쉬데이터가 나와야하는걸로 알고 있는데 제가 잘못 알고 있는걸까요?
방법이 잘못되었으면 어디서부터 확인해서 처리해야 할지 도움 요청 드립니다.
감사합니다.
Forums:
진지하게 검토하기에 앞서...
일단 한 번 찍어보겠습니다.
기대는 너무 많이 하지 마시고,
gets(pong);
대신fgets(pong, 32, stdin);
로 바꿔보시고 결과 확인해보세요.이 편이 프로그램 안정성 측면에서도 더 낫고(버퍼 오버런은 유명한 취약점이죠) 의도치 않게 개행문자가 달라붙는 문제도 없어집니다.
잘 되면 다행이고, 못 되면 모른 척 하시면 됩니다(무책임)
진지하게 검토하려다가, 도저히 제 능력으로는 범접할
진지하게 검토하려다가, 도저히 제 능력으로는 범접할 수 없는 코드여서 그만 뒀습니다. 저 그냥 나갈게요. ㅜㅜ.
이 부분이 특히 인상깊었어요. 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;
으로 고치는 등) 매번 동일한 결과가 나오기는 합니다. 근데 그래도 여전히 예제와 다르네요.아몰랑. -_-. 다른 거 쓰세요. 이거 디버그한다고 삽질하느니 아예 새로 짜는 게 낫겠네요.
저도 한참 찾다가...
저도 원인을 한참 찾다가 포기하고
오픈소스로 구현 했습니다.
endian 가지고 헤메는 전통을 이어받고, int
endian 가지고 헤메는 전통을 이어받고, int 와 long 을 구분못하는 새로운 혁신을 이뤄냈네요.
kisa에서 받은 거면 kisa에 물어보는 게 낫지
kisa에서 받은 거면 kisa에 물어보는 게 낫지 않나요? KISA가 인터넷진흥원 맞나요? 그곳에서 인터넷을 얼마나 진흥시켰는지는 잘 모르겠지만.
세벌 https://sebuls.blogspot.kr/
삽질 결과 다른거 쓰는걸루 결론을 냈습니다.
당황스러운 소스 였습니다.
댓글 달기