KTC보안인증 C# SHA-1 해시값 비교

김철현·2021년 5월 24일
0

Encryption

목록 보기
1/5
post-thumbnail

📝 KTC 보안인증

배경

여신전문금융업법에 의해 KTC보안인증을 받아야 한다는 협력사 안내에 따라 개발했던 내용중 클라이언트에서 프로그램 업데이트 시 실행파일 해시값 비교한 부분이다

목적

신용카드 단말기 보안시험(KTC인증)은 여신전문금융업법에 의거 금융위원회가 정하는 기술기준에 따라 보안기능의 안전성과 신뢰성이 시험, 인증되어 안심하고 제품을 사용할 수 있도록 지원하는 제도로 신용카드 단말기를 사용하는 모든 업체에서 받아야 하는 인증심사이며 인증받은 기업(단말기)은 여신금융협회에 등록된다고 한다

심사내용

  1. DB 저장 시 개인을 특정할 수 있는 민감데이터(핸드폰번호 등) 암호화
  2. H/W 또는 S/W 간 통신 시 각각 통신 구간 암호화
  3. 민감데이터가 있는 전문의 로그 기록은 하지 않거나 마스킹 처리하도록 수정
  4. 민감데이터를 저장한 모든 변수 사용 후 명시적인 메모리 초기화
  5. 응용프로그램의 경우 배포 시 프로그램의 무결성 검사

개발환경

  1. 클라이언트 : Windows Embedded, .NET Framework 3.5 (C#), SQLite
  2. 중계서버 : Windows Server 2012 R2, IOCP를 이용한 MFC (C++), MSSQL
    Windows Embedded .NET Framework 3.5를 사용하던 클라이언트 개발환경에선 MD5, SHA1 클래스만을 지원하여 SHA1을 사용

💡 SHA-1

정해진 고정 길이로 임의의 해시값을 갖는 단방향 암호화 방식으로 무결성 검사에 사용
두 개의 다른 메세지가 같은 해시값을 갖게 되는 것을 충돌(collision)이라 하는데 SHA1은 충돌내성 깨져 현재는 잘 사용하지 않는다고 하며 SHA2(SHA256, SHA512)로 마이그레이션 되고 있다고 한다

알고리즘 해시값 크기 내부 상태 크기 블록 크기 길이 한계 워드 크기 과정 수 충돌
SHA-0 160 160 512 64 32 80 발견됨
SHA-1 160 160 512 64 32 80 발견됨
SHA-256/224 256/224 256 512 64 32 64 -
SHA-512/384 512/384 512 1024 128 64 80 -

✍ 해시값 비교

//업데이트 받는 파일 중 파일명이 MainProgram 이면 진입
if (tmpFile.Equals("MainProgram.exe"))
{
	//SHA-1 클래스 선언
	SHA1 mySHA1 = SHA1.Create();
	//파일 읽기
	FileStream target = File.OpenRead(ProgramPath + "MainProgram.exe");
	//다운받은 파일의 해시값 byte[]에 저장
	byte[] byteTarget = mySHA1.ComputeHash(target);
	//해시값 문자열로 변환
	string strTargetHash = GetStringFromHash(byteTarget);
	//파일 닫기
	target.Close();

	//업데이트 받는 8개 파일의 해시값을 저장해 놓은 텍스트파일 읽기
	StreamReader hashValue = new StreamReader(ProgramPath + "hash_values.bb");
	//저장된 해시값 저장할 변수 선언
	string strHash = string.Empty;

	for (int i = 0; i < 8; i++)
	{
		//8개 해시값 중 MainProgram 해시값은 8번째
		if (i == 7)
			//해시값 변수 저장
			strHash = hashValue.ReadLine();
		else
			hashValue.ReadLine();
	}
	//파일 닫기
	hashValue.Close();

	//다운받은 파일해시값과 텍스트파일내의 해시값 비교
	if (!strTargetHash.Equals(strHash))
	{
		//비교값이 다르면 메세지 출력 및 파일 삭제
		MessageBox.Show("무결성 검사 실패 - MainProgram.exe");
		File.Delete(ProgramPath + "MainProgram.exe");
	}
}

private static string GetStringFromHash(byte[] hash)
{
	StringBuilder result = new StringBuilder();
	for (int i = 0; i < hash.Length; i++)
	{
		//byte[]를 16진수 문자열로
		result.Append(hash[i].ToString("X2"));
	}
	return result.ToString();
}
profile
리팩토링만이 살 길이다

0개의 댓글