Prototype Ghost
귀신일지
Prototype Ghost
전체 방문자
오늘
어제
  • 분류 전체보기 (29)
    • Hacking (1)
      • CTF (0)
      • Wargame (0)
      • Review (1)
    • C (12)
      • Crypto (12)
    • C++ (4)
    • Python (1)
    • Swift (1)
    • Blockchain (9)
      • Solidity (9)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • c언어
  • ethereum
  • 접근제어
  • C
  • 암호화
  • 정보보안
  • 암호화폐
  • openssl
  • C++
  • 이더리움
  • 프로그래밍
  • 솔리디티
  • 보안
  • 비트코인
  • solidity
  • Bitcoin
  • Blockchain
  • 복호화
  • 블록체인
  • 리눅스

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Prototype Ghost

귀신일지

Crypto Project : 1-4. C언어에서 멤버변수 접근을 막는 방법과 init, update, final의 개념
C/Crypto

Crypto Project : 1-4. C언어에서 멤버변수 접근을 막는 방법과 init, update, final의 개념

2023. 4. 15. 21:28

시작하며


  지난 글에선 암호화, 복호화 함수 enc와 dec를 살펴보았다. enc와 dec 모두 input을 받으면 패딩까지 완벽하게 처리하여 output을 내주는 함수였다. 그러나 이 함수에는 약간의 단점이 있는데, 함수를 실행시키면 무조건 암호화, 혹은 복호화를 "완료" 한다는 것이다. 무슨 말이냐면, 우선 패딩처리가 무조건 된다는 것이다. 패딩은 데이터의 마지막에만 붙이는 것을 원칙으로 한다. 즉 이 함수는 반드시 패딩에 대한 처리를 진행하므로 내가 아직 암호화할 데이터가 남아있음에도, 암호문을 완성해버린다는 것이다. 즉 데이터를 분할해서 암호화할 수 없다.              예로, 네트워크 상에서 내가 전송 받을 데이터는 한번에 다 받는 것을 보장할 수 없다. 상대방이 나에게 암호화한 데이터를 전송하고 내가 복호화를 진행한다고 할 때, 만약 네트워크가 데이터를 한번에 보내지 않고 조금 나눠서 주게 된다면, 복호화가 제대로 진행되지 않을 수 있다. 또 그렇다면, 모든 데이터를 받은 다음 복호화를 진행하면 된다고 생각할 수도 있다. 맞는 말이지만, 또 다른 문제는 네트워크 상에서 오는 데이터를 담는 변수의 크기에 대한 문제이다. 만약 변수의 크기가 256바이트인데 네트워크의 데이터가 512만큼 온다면, 이를 처리할 방법이 없다. 다른 예로는 파일 처리를 생각할 수 있는데, 만약 파일의 값을 한 줄씩 읽어온다면, 한줄씩 암호화를 진행하고 마지막 행을 만나면 패딩처리까지 하는, 그러한 기능이 필요하게 될 것이다. 즉 이러한 예들로, 데이터를 한번에 처리하는 것이 아닌, 나눠서 암복화를 진행할 수 있는 함수의 필요가 대두된다. 그것이 바로 init, update, final 함수이다. 

 

1. init, update, final의 개념


  init, update, final은 간단하게 암호화와 복호화를 나눠서 처리할 수 있도록 해주는 함수이다. inti은 간단하게 초기화 해주는 함수이고, update는 데이터를 계속해서 암호화를 한다. 여기서 중요한 것은 패딩 처리는 하지 않는다는 것이다. 내가 만약 256 바이트를 하나의 암호문으로 만든다고 가정하자. 우선 두개로 나눠 128바이트를 update를 하면 128바이트의 암호화를 진행하지만 패딩처리는 하지 않는다. 또 남은 128바이트의 암호화를 진행하면, 여기에 덧붙여 128바이트를 마저 암호화하지만 이마저도 패딩처리를 하지 않는다. 왜????

데이터를 다 받아도 암호화를 최종적으로 완료하지 않는 이유는 이 데이터의 끝은 전적으로 사용자만 알기 때문이다. update함수는 데이터가 언제끝날지 알 수 없고 그저 사용자가 준 input을 계속해서 암호화처리를 한다. 암호화할 데이터를 모두 처리해 이제 패딩까지 처리해서 암호화 작업을 완료하려면 사용자가 final이라는 함수를 호출해주어야 한다. final을 호출해야 암호화할 데이터가 더 이상 없다고 판단하고 내부에서 이에 따른 마무리 작업을 진행한다. 이것이 init, update, final의 흐름이고, 이러한 흐름으로 인해 내부에서 현재 상태를 저장하고 있어야만한다. 무슨 말이냐면, 데이터를 계속해서 암호화하려면 관련된 정보들을 계속해서 저장하고 있어야 update를 계속 진행시킬 수 있고 final에 대한 작업도 할 수 있다는 것이다. 그렇다면 이 상태정보를 저장하는 context 구조체를 살펴봄과 동시에 C언어에서 어떻게 멤버변수에 대한 사용자의 접근을 막을 수 있는지에 대한 설명을 이어가겠다.

 

2. 상태정보를 저장하는 I_CIPHER_CTX 


  위에서 설명한대로, 상태정보를 저장하는 구조체 변수 I_CIPHER_CTX이다. 그런데 설명만 써있고 구조체 멤버 변수에 대한 설명이 없다. 왜냐하면 이 문서는 헤더파일에 있는 내용을 문서화한 것인데, 헤더파일에는 이 구조체에 대한 선언만 있고 내부 내용은 .c 소스에만 있기 때문이다. 구조체를 헤더에다 박지 않고 선언과 내부 내용을 분리한 이유는 사용자에게 멤버변수 접근을 막기 위함이다. 무슨 말이냐면, update와 final을 위해 상태 정보를 계속해서 저장하고 있어야 하는데, 이 상태 정보를 사용자가 임의로 바꾼다면, 암호화와 복호화가 정상적으로 작동하지 않는다. 즉 사용자가 멤버 변수를 건드려서 좋은 점이 하나도 없다. 그러나 문제는 개발 언어가 c라는 점인데, c++ 같은 객체지향 언어라면 클래스의 멤버변수를 private으로 접근을 막을 수 있으나 c언어에는 그런 기능이 없다. 그렇기에 우리는 구조체를 .c에다 기술하고 감추는 형식을 사용한다.

 

3. 멤버변수의 접근을 막는 법


헤더파일에 기술된 I_CIPHER_CTX의 선언

 

.c 파일에 기술된 I_CIPHER_CTX구조체 전체

  이런 식으로 내부 정보를 헤더에 선언하지 않고 .c에만 기술한다면, 사용자는 내부 변수의 내용을 알지 못해 변수에 접근을 기능적으로 차단할 수 있게 된다. 그렇다면 구현하는 쪽에선 사용자가 이 구조체를 자유롭게 사용할 수 없기 때문에 해당 구조체에 대한 처리를 함수로써 그 기능을 제공해 주어야 한다. 사용자는 그럼 어떻게 이 구조체를 사용할 수 있을까?

  위의 3가지 변수 선언을 보자. 하나는 에러가 발생한다. 바로 158번 라인의 선언이 문제가 된다. 왜냐하면 헤더 정보만 갖고 I_CIPHER_CTX의 정보를 모르기 때문에, 158번처럼 구조체 변수를 선언해버리면 이 구조체 변수의 메모리를 얼만큼 잡아야할지 알지 못하기때문에 에러가 발생한다. 156, 157처럼 하는 이유는 결국 포인터 변수는 64비트 기준 무조건 8바이트이기 때문에 156은 그냥 void포인터라 당연히 되는 것이고. 157번행도 포인터 변수가 선언될 때 I_CIPHER_CTX 구조체의 크기를 알 필요가 없기 때문이다. 이렇듯 포인터 변수를 이용하여 내부 정보를 몰라도 구조체를 사용할 수 있게된다. 당연히, 이를 사용하는 것은 코드 제작자가 함수로써 제공해야 한다.

  이렇게 ctx구조체를 처리하기 위한 것들을 함수로써 제공해야 한다. new로 구조체 동적할당을 해서 반환해주고, reset기능, 또 free기능까지 제공하여 구조체를 이용할 수 있게 해야한다. 

 

3. 마치며


  원래 이번글에서 바로 init update final에 대한 구현을 살펴보려고 했지만 그러지 않았다. C++을 배우고 접근 처음 제어에 대한 개념을 배우면서 정말 좋은 기능이다, 왜 c는 이런게 없을까 생각만했는데 이런식으로 어떻게든 할 수 있다는 것을 알았을 땐 정말 놀라웠고, 또 이러한 테크닉이 이것 뿐만 아니라 여러가지로 응용할 수 있다는 생각 또한 하게 되었다. 꽤나 중요하고 재밌는 내용이기 때문에 이 내용을 이번 글에서 집중적으로 다루었고 다음 글에서 본격적으로 구현에 대한 부분을 살펴보겠다.

728x90
반응형

'C > Crypto' 카테고리의 다른 글

Crypto Project : 1-6. crypto library makefile과 테스트  (0) 2023.04.23
Crypto Project : 1-5. 암복호화 init, update, final 구현  (0) 2023.04.16
Crypto Project : 1-3. 암호화, 복호화 함수(enc, dec)  (1) 2023.04.14
Crypto Project : 1-2. 블록암호운용모드 ECB를 이용한 CBC, CTR 모드 구현  (0) 2023.04.13
Crypto Project : 1-1. i_crypto library - 구조 및 문서화 예시  (0) 2023.04.11
    'C/Crypto' 카테고리의 다른 글
    • Crypto Project : 1-6. crypto library makefile과 테스트
    • Crypto Project : 1-5. 암복호화 init, update, final 구현
    • Crypto Project : 1-3. 암호화, 복호화 함수(enc, dec)
    • Crypto Project : 1-2. 블록암호운용모드 ECB를 이용한 CBC, CTR 모드 구현
    Prototype Ghost
    Prototype Ghost

    티스토리툴바