<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>song.3_3</title>
    <link>https://song-song.tistory.com/</link>
    <description>song-song 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Sat, 18 Jul 2026 21:18:09 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>song.3_3</managingEditor>
    <image>
      <title>song.3_3</title>
      <url>https://tistory1.daumcdn.net/tistory/8606518/attach/737e5da2bfdd41d8a145eeecbef133a4</url>
      <link>https://song-song.tistory.com</link>
    </image>
    <item>
      <title>하계 보안 세미나 6일차 - 보안적합성 검사</title>
      <link>https://song-song.tistory.com/8</link>
      <description>&lt;div&gt;
&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-6a3a1513-0ef8-83e8-a772-7f568a0759a7-14&quot;&gt;
&lt;div&gt;
&lt;div data-conversation-screenshot-content=&quot;&quot;&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-5-thinking&quot; data-turn-start-message=&quot;true&quot; data-message-id=&quot;a0918640-eac6-4bd1-aa3d-b0608995b77c&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;266&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;이번 6강에서는 &lt;b&gt;국가 보안적합성 검증 체계&lt;/b&gt;를 배웠다.&lt;/p&gt;
&lt;p data-end=&quot;413&quot; data-start=&quot;268&quot; data-ke-size=&quot;size16&quot;&gt;앞선 강의에서는 암호가 어떻게 깨지는지, 양자내성암호는 어떤 원리인지, 자동차와 임베디드 코드에는 어떤 취약점이 생기는지를 살펴봤다. 이번 강의는 기술 자체보다는, 그렇게 만든 보안 제품을 국가&amp;middot;공공기관에서 사용하려면 어떤 검증 절차를 거쳐야 하는지를 다뤘다.&lt;/p&gt;
&lt;p data-end=&quot;510&quot; data-start=&quot;415&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 보안적합성 검증, 보안기능 확인서, KCMVP, CC 인증처럼 이름이 비슷한 제도가 계속 등장해서 헷갈렸다. 하지만 강의 전체를 관통하는 질문은 비교적 단순했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&amp;ldquo;이 제품은 안전합니다&amp;rdquo;라고 개발자가 말하는 것과
국가가 실제 시험을 거쳐 검증한 것은 무엇이 다른가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;650&quot; data-start=&quot;583&quot; data-ke-size=&quot;size16&quot;&gt;CTF에서는 주로 &amp;ldquo;내가 이 시스템을 깰 수 있는가?&amp;rdquo;를 생각한다. 하지만 제품 개발과 납품 단계에서는 질문이 달라진다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이 기능을 구현했는가?
요구사항을 정확히 지켰는가?
그 사실을 누가 검증했는가?
검증 결과를 증명할 문서가 있는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;788&quot; data-start=&quot;730&quot; data-ke-size=&quot;size16&quot;&gt;즉 제품을 잘 만들었다고 주장하는 것만으로는 부족하고, 그 주장을 객관적인 시험과 문서로 증명해야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;808&quot; data-start=&quot;790&quot; data-section-id=&quot;5cvtbi&quot; data-ke-size=&quot;size26&quot;&gt;이름이 비슷한 세 가지 제도&lt;/h2&gt;
&lt;p data-end=&quot;856&quot; data-start=&quot;810&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 먼저 구분한 것은 &lt;b&gt;보안기능 확인서, KCMVP, CC 인증&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;905&quot; data-start=&quot;858&quot; data-ke-size=&quot;size16&quot;&gt;셋 다 보안과 관련된 검증 제도라서 비슷해 보이지만, 실제로 확인하는 대상이 다르다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;구분확인 대상쉽게 말하면
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1085&quot; data-start=&quot;907&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1085&quot; data-start=&quot;945&quot;&gt;
&lt;tr data-end=&quot;992&quot; data-start=&quot;945&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;956&quot; data-start=&quot;945&quot;&gt;보안기능 확인서&lt;/td&gt;
&lt;td data-end=&quot;971&quot; data-start=&quot;956&quot; data-col-size=&quot;sm&quot;&gt;제품에 구현된 보안기능&lt;/td&gt;
&lt;td data-end=&quot;992&quot; data-start=&quot;971&quot; data-col-size=&quot;sm&quot;&gt;제품 기능을 실제로 시험한 결과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1039&quot; data-start=&quot;993&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1001&quot; data-start=&quot;993&quot;&gt;KCMVP&lt;/td&gt;
&lt;td data-end=&quot;1014&quot; data-start=&quot;1001&quot; data-col-size=&quot;sm&quot;&gt;제품 안의 암호모듈&lt;/td&gt;
&lt;td data-end=&quot;1039&quot; data-start=&quot;1014&quot; data-col-size=&quot;sm&quot;&gt;암호 구현이 규격대로 만들어졌는지 검증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1085&quot; data-start=&quot;1040&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1048&quot; data-start=&quot;1040&quot;&gt;CC 인증&lt;/td&gt;
&lt;td data-end=&quot;1061&quot; data-start=&quot;1048&quot; data-col-size=&quot;sm&quot;&gt;제품 전체의 보안성&lt;/td&gt;
&lt;td data-end=&quot;1085&quot; data-start=&quot;1061&quot; data-col-size=&quot;sm&quot;&gt;제품 전체를 일정한 평가기준으로 평가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1165&quot; data-start=&quot;1087&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보안기능 확인서&lt;/b&gt;는 영상기기와 같은 IT 제품의 보안기능 시험 결과를 나타내는 증서다. 이번 강의에서 중심적으로 다룬 제도이기도 하다.&lt;/p&gt;
&lt;p data-end=&quot;1284&quot; data-start=&quot;1167&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;KCMVP&lt;/b&gt;는 제품 전체가 아니라, 제품에 탑재된 암호모듈을 검증하는 제도다. 암호 알고리즘만 사용한다고 끝나는 것이 아니라, 그 알고리즘을 구현한 모듈이 규격과 보안요구사항을 제대로 지켰는지를 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;1338&quot; data-start=&quot;1286&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CC 인증&lt;/b&gt;은 ISO/IEC 15408을 기반으로 제품 전체의 보안성을 평가하는 제도다.&lt;/p&gt;
&lt;p data-end=&quot;1359&quot; data-start=&quot;1340&quot; data-ke-size=&quot;size16&quot;&gt;한 문장으로 구분하면 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;보안기능 확인서 = 제품의 보안기능 시험
KCMVP = 제품 안의 암호모듈 검증
CC 인증 = 제품 전체의 보안성 평가&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1562&quot; data-start=&quot;1441&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 IP카메라가 국가&amp;middot;공공기관에 들어가려면 제품 보안기능 시험을 거쳐 보안기능 확인서를 받아야 한다. 그리고 카메라 안에서 영상을 암호화한다면, 그 암호화 기능에는 KCMVP 검증필 암호모듈이 요구될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1594&quot; data-start=&quot;1564&quot; data-ke-size=&quot;size16&quot;&gt;즉 하나가 다른 하나를 완전히 대신하는 관계는 아니다.&lt;/p&gt;
&lt;h2 data-end=&quot;1619&quot; data-start=&quot;1596&quot; data-section-id=&quot;10jp5x0&quot; data-ke-size=&quot;size26&quot;&gt;한 제품에도 여러 층의 검증이 붙는다&lt;/h2&gt;
&lt;p data-end=&quot;1666&quot; data-start=&quot;1621&quot; data-ke-size=&quot;size16&quot;&gt;강의 자료에서는 하나의 제품에도 세 가지 층위의 검증이 붙을 수 있다고 설명했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;운용 환경
&amp;rarr; 보안적합성 검증

제품 보안기능
&amp;rarr; 보안기능 시험제도(VSFT)

암호 구현
&amp;rarr; KCMVP 암호모듈 검증&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1811&quot; data-start=&quot;1748&quot; data-ke-size=&quot;size16&quot;&gt;제품의 암호화 코드가 정상적으로 동작한다고 해서, 제품 전체가 국가&amp;middot;공공기관에 바로 도입될 수 있는 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1905&quot; data-start=&quot;1813&quot; data-ke-size=&quot;size16&quot;&gt;반대로 제품의 로그인 기능과 감사기록이 잘 구현되어 있어도, 저장 암호화에 사용한 암호모듈이 KCMVP 검증필 목록에 없다면 관련 요구사항을 충족하지 못할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1937&quot; data-start=&quot;1907&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의에서 가장 중요하게 느껴진 부분도 이것이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;&amp;ldquo;구현이 맞다&amp;rdquo;와
&amp;ldquo;검증을 통과했다&amp;rdquo;는
서로 다른 문장이다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;1999&quot; data-start=&quot;1986&quot; data-section-id=&quot;1801ouh&quot; data-ke-size=&quot;size26&quot;&gt;보안적합성 검증이란&lt;/h2&gt;
&lt;p data-end=&quot;2056&quot; data-start=&quot;2001&quot; data-ke-size=&quot;size16&quot;&gt;보안적합성 검증은 국가&amp;middot;공공기관이 IT 제품을 도입하기 전에 해당 제품의 안전성을 검증하는 제도다.&lt;/p&gt;
&lt;p data-end=&quot;2164&quot; data-start=&quot;2058&quot; data-ke-size=&quot;size16&quot;&gt;제품을 먼저 도입한 뒤 문제가 발생하면 수정하는 것이 아니라, 도입 전에 시험하고 취약점을 보완한 뒤 사용하는 구조다. 따라서 공공기관에 제품을 납품하려는 업체에는 일종의 관문 역할을 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;제품 개발
&amp;rarr; 보안기능 시험
&amp;rarr; 취약점 발견
&amp;rarr; 보완
&amp;rarr; 결과 검토
&amp;rarr; 확인서 발급
&amp;rarr; 공공기관 도입&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2289&quot; data-start=&quot;2236&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 국가정보원법, 사이버안보업무규정, 전자정부법 등이 제도의 근거로 연결된다고 설명했다.&lt;/p&gt;
&lt;p data-end=&quot;2366&quot; data-start=&quot;2291&quot; data-ke-size=&quot;size16&quot;&gt;개인 프로젝트에서는 &amp;ldquo;기능이 실행되는가?&amp;rdquo;가 중심이 되지만, 공공기관 납품에서는 &amp;ldquo;도입 요건을 통과했는가?&amp;rdquo;가 더 중요한 질문이 된다.&lt;/p&gt;
&lt;h2 data-end=&quot;2385&quot; data-start=&quot;2368&quot; data-section-id=&quot;kzgqep&quot; data-ke-size=&quot;size26&quot;&gt;어떤 제품이 검증 대상인가&lt;/h2&gt;
&lt;p data-end=&quot;2471&quot; data-start=&quot;2387&quot; data-ke-size=&quot;size16&quot;&gt;보안적합성 검증 대상에는 방화벽, VPN, 스위치와 라우터, 안티바이러스, DB 접근통제, 양자키분배 장비, 영상정보처리기기 등 여러 종류가 포함된다.&lt;/p&gt;
&lt;p data-end=&quot;2557&quot; data-start=&quot;2473&quot; data-ke-size=&quot;size16&quot;&gt;강의 자료에서는 국가용 보안요구사항이 공통 요구사항과 제품별 요구사항으로 구성되며, 제품별 요구사항은 10개 제품군, 총 34종으로 나뉜다고 설명했다.&lt;/p&gt;
&lt;p data-end=&quot;2576&quot; data-start=&quot;2559&quot; data-ke-size=&quot;size16&quot;&gt;대표적인 제품군은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;침입차단
침입방지
구간보안
전송자료보안
보안관리
가상화
엔드포인트 보안
네트워크 장비
양자암호통신
영상정보처리기기&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2707&quot; data-start=&quot;2655&quot; data-ke-size=&quot;size16&quot;&gt;제품 종류가 달라도 인증, 데이터 보호, 업데이트 보호, 감사기록 같은 기본 뼈대는 반복된다.&lt;/p&gt;
&lt;h2 data-end=&quot;2728&quot; data-start=&quot;2709&quot; data-section-id=&quot;1ihjmok&quot; data-ke-size=&quot;size26&quot;&gt;IP카메라도 검증 대상이 된다&lt;/h2&gt;
&lt;p data-end=&quot;2771&quot; data-start=&quot;2730&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 영상정보처리기기가 검증 대상에 편입된 사례를 집중적으로 다뤘다.&lt;/p&gt;
&lt;p data-end=&quot;2843&quot; data-start=&quot;2773&quot; data-ke-size=&quot;size16&quot;&gt;2024년 4월 1일부터 TCP/IP 네트워크로 연결되어 데이터를 전송하는 영상정보처리기기는 보안적합성 검증 대상에 포함됐다.&lt;/p&gt;
&lt;p data-end=&quot;2870&quot; data-start=&quot;2845&quot; data-ke-size=&quot;size16&quot;&gt;여기서 중요한 구분은 네트워크 연결 방식이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;TCP/IP로 연결되는 IP카메라
&amp;rarr; 검증 대상

아날로그 또는 SDI 방식으로 영상을 전송하는 카메라
&amp;rarr; 해당 기준에서는 대상 제외&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3081&quot; data-start=&quot;2960&quot; data-ke-size=&quot;size16&quot;&gt;IP카메라는 인터넷이나 내부 네트워크와 연결되기 때문에 계정 탈취, 영상 유출, 펌웨어 변조, 네트워크 침입과 같은 위험이 생긴다. 그래서 단순한 촬영 장비가 아니라 하나의 네트워크 보안 제품처럼 관리할 필요가 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;3108&quot; data-start=&quot;3083&quot; data-section-id=&quot;1ma3j2d&quot; data-ke-size=&quot;size26&quot;&gt;어느 제품이든 반복되는 공통 보안요구사항&lt;/h2&gt;
&lt;p data-end=&quot;3146&quot; data-start=&quot;3110&quot; data-ke-size=&quot;size16&quot;&gt;제품마다 기능은 다르지만, 공통적으로 확인하는 보안 항목이 있다.&lt;/p&gt;
&lt;p data-end=&quot;3185&quot; data-start=&quot;3148&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 서버 공통 보안요구사항을 다음과 같은 영역으로 정리했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;식별 및 인증
보안관리
데이터 보호
자체보호
업데이트 보호
안전한 세션 관리
감사기록
암호지원
취약성 대응&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3299&quot; data-start=&quot;3260&quot; data-ke-size=&quot;size16&quot;&gt;영상정보처리기기에는 여기에 영상 보안이라는 제품 고유 항목이 추가된다.&lt;/p&gt;
&lt;p data-end=&quot;3369&quot; data-start=&quot;3301&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 방화벽과 VPN, IP카메라는 서로 전혀 다른 제품처럼 보이지만 다음과 같은 기준을 공통으로 적용받을 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;패스워드는 일정 길이 이상이어야 한다.
인증에 반복 실패하면 계정을 잠근다.
사용하지 않는 세션은 일정 시간이 지나면 종료한다.
중요한 행위는 감사기록으로 남긴다.
업데이트 파일의 무결성과 출처를 검증한다.
암호 기능은 정해진 기준에 맞게 구현한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3582&quot; data-start=&quot;3524&quot; data-ke-size=&quot;size16&quot;&gt;강의 예시에서는 패스워드 9자리 이상, 인증 실패 5회, 유휴시간 10분 같은 구체적인 수치도 등장했다.&lt;/p&gt;
&lt;p data-end=&quot;3654&quot; data-start=&quot;3584&quot; data-ke-size=&quot;size16&quot;&gt;보안요구사항은 &amp;ldquo;로그인을 안전하게 구현한다&amp;rdquo;처럼 모호한 문장이 아니라, 실제 시험할 수 있는 형태로 작성된다는 점이 중요했다.&lt;/p&gt;
&lt;h2 data-end=&quot;3677&quot; data-start=&quot;3656&quot; data-section-id=&quot;1i0byfc&quot; data-ke-size=&quot;size26&quot;&gt;보안기능 시험제도에 참여하는 기관&lt;/h2&gt;
&lt;p data-end=&quot;3713&quot; data-start=&quot;3679&quot; data-ke-size=&quot;size16&quot;&gt;보안기능 시험제도에는 여러 기관이 서로 다른 역할로 참여한다.&lt;/p&gt;
&lt;p data-end=&quot;3735&quot; data-start=&quot;3715&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 이를 네 주체로 정리했다.&lt;/p&gt;
&lt;h3 data-end=&quot;3750&quot; data-start=&quot;3737&quot; data-section-id=&quot;lrreso&quot; data-ke-size=&quot;size23&quot;&gt;NIS: 정책기관&lt;/h3&gt;
&lt;p data-end=&quot;3795&quot; data-start=&quot;3752&quot; data-ke-size=&quot;size16&quot;&gt;국가정보원은 검증 정책을 수립하고 시험기관 지정과 확인서 효력 등을 관리한다.&lt;/p&gt;
&lt;h3 data-end=&quot;3810&quot; data-start=&quot;3797&quot; data-section-id=&quot;l8pgv2&quot; data-ke-size=&quot;size23&quot;&gt;NSR: 검증기관&lt;/h3&gt;
&lt;p data-end=&quot;3862&quot; data-start=&quot;3812&quot; data-ke-size=&quot;size16&quot;&gt;국가보안기술연구소는 시험 가이드를 제공하고, 시험 결과를 검토하며 확인서 발급을 승인한다.&lt;/p&gt;
&lt;h3 data-end=&quot;3877&quot; data-start=&quot;3864&quot; data-section-id=&quot;15yb27d&quot; data-ke-size=&quot;size23&quot;&gt;TTA: 시험기관&lt;/h3&gt;
&lt;p data-end=&quot;3929&quot; data-start=&quot;3879&quot; data-ke-size=&quot;size16&quot;&gt;영상기기 분야에서는 한국정보통신기술협회가 실제 보안기능 시험을 수행하고 확인서를 발급한다.&lt;/p&gt;
&lt;h3 data-end=&quot;3945&quot; data-start=&quot;3931&quot; data-section-id=&quot;1evut5o&quot; data-ke-size=&quot;size23&quot;&gt;신청기관: 제조업체&lt;/h3&gt;
&lt;p data-end=&quot;4002&quot; data-start=&quot;3947&quot; data-ke-size=&quot;size16&quot;&gt;제품을 개발한 업체는 시험을 신청하고, 필요한 문서를 제출하며, 시험 중 발견된 취약점을 보완한다.&lt;/p&gt;
&lt;p data-end=&quot;4016&quot; data-start=&quot;4004&quot; data-ke-size=&quot;size16&quot;&gt;정리하면 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;objectivec&quot;&gt;&lt;code&gt;정책은 NIS
검증은 NSR
시험은 TTA
신청은 제조업체&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4135&quot; data-start=&quot;4064&quot; data-ke-size=&quot;size16&quot;&gt;제품을 개발한 업체가 직접 접촉하는 곳은 시험기관이지만, 그 뒤에는 결과를 검토하는 검증기관과 제도를 관리하는 정책기관이 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;4152&quot; data-start=&quot;4137&quot; data-section-id=&quot;no2ei9&quot; data-ke-size=&quot;size26&quot;&gt;시험 신청부터 도입까지&lt;/h2&gt;
&lt;p data-end=&quot;4179&quot; data-start=&quot;4154&quot; data-ke-size=&quot;size16&quot;&gt;제품은 신청 즉시 확인서를 받는 것이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;4204&quot; data-start=&quot;4181&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 설명한 전체 흐름은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. 시험 신청
2. 접수 및 계약
3. 시험수행 계획 수립
4. 보안기능 시험
5. 시험 결과 검토
6. 보안기능 확인서 발급
7. 공공기관 도입&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4352&quot; data-start=&quot;4302&quot; data-ke-size=&quot;size16&quot;&gt;시험 과정에서 부적합 판정을 받으면 신청기관이 취약점을 수정하고 다시 시험을 받아야 한다.&lt;/p&gt;
&lt;p data-end=&quot;4447&quot; data-start=&quot;4354&quot; data-ke-size=&quot;size16&quot;&gt;여기서 시험은 서류만 읽고 통과 여부를 정하는 방식이 아니다. 실제 제품을 실행해 로그인, 계정 잠금, 세션 종료, 암호화, 업데이트, 감사기록 등의 동작을 확인한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;문서에는 안전하다고 적혀 있지만
실제 제품은 다르게 동작할 수도 있다.

따라서 시험기관은 문서와 실제 동작을 함께 확인한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;4552&quot; data-start=&quot;4533&quot; data-section-id=&quot;mu8w8i&quot; data-ke-size=&quot;size26&quot;&gt;보안기능 확인서가 의미하는 것&lt;/h2&gt;
&lt;p data-end=&quot;4617&quot; data-start=&quot;4554&quot; data-ke-size=&quot;size16&quot;&gt;보안기능 확인서는 제품이 시험기준을 만족했다는 사실을 확인하여, 검증기관의 승인 아래 시험기관이 발급하는 증서다.&lt;/p&gt;
&lt;p data-end=&quot;4659&quot; data-start=&quot;4619&quot; data-ke-size=&quot;size16&quot;&gt;도입기관은 이 확인서를 통해 해당 제품이 검증 절차를 거쳤는지 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;4768&quot; data-start=&quot;4661&quot; data-ke-size=&quot;size16&quot;&gt;강의 자료에서는 확인서가 &lt;b&gt;발급일까지 알려진 취약점이 제거됐는지 확인하는 결과물&lt;/b&gt;이라고 설명했다. 하지만 확인서가 발급된 이후에 새로 발견되는 모든 취약점까지 없다고 보증하는 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;4786&quot; data-start=&quot;4770&quot; data-ke-size=&quot;size16&quot;&gt;즉 확인서는 다음을 의미한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;발급 시점의 기준과 알려진 취약점을 바탕으로
시험을 통과했다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4847&quot; data-start=&quot;4836&quot; data-ke-size=&quot;size16&quot;&gt;다음 의미는 아니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;앞으로 절대 취약점이 발견되지 않는다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5007&quot; data-start=&quot;4884&quot; data-ke-size=&quot;size16&quot;&gt;국가용 보안요구사항을 기준으로 시험한 제품은 5년, 신기술 등 구현명세서를 기반으로 시험한 경우는 2년의 유효기간이 적용될 수 있다고 강의에서 설명했다.&lt;/p&gt;
&lt;h2 data-end=&quot;5029&quot; data-start=&quot;5009&quot; data-section-id=&quot;1gbqxjp&quot; data-ke-size=&quot;size26&quot;&gt;시험을 위해 제출해야 하는 문서&lt;/h2&gt;
&lt;p data-end=&quot;5084&quot; data-start=&quot;5031&quot; data-ke-size=&quot;size16&quot;&gt;신청기관은 제품만 보내는 것이 아니라, 제품의 구조와 보안기능을 설명하는 문서도 제출해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;5110&quot; data-start=&quot;5086&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 소개한 문서는 다음 다섯 종류였다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;문서주요 내용
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;5262&quot; data-start=&quot;5112&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;5262&quot; data-start=&quot;5137&quot;&gt;
&lt;tr data-end=&quot;5158&quot; data-start=&quot;5137&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5145&quot; data-start=&quot;5137&quot;&gt;제품설명서&lt;/td&gt;
&lt;td data-end=&quot;5158&quot; data-start=&quot;5145&quot; data-col-size=&quot;sm&quot;&gt;제품 개요와 구성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5191&quot; data-start=&quot;5159&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5172&quot; data-start=&quot;5159&quot;&gt;보안기능 구현명세서&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5191&quot; data-start=&quot;5172&quot;&gt;보안기능, 인터페이스, 계정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5213&quot; data-start=&quot;5192&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5200&quot; data-start=&quot;5192&quot;&gt;운용설명서&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5213&quot; data-start=&quot;5200&quot;&gt;설치와 운용 방법&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5231&quot; data-start=&quot;5214&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5222&quot; data-start=&quot;5214&quot;&gt;시험결과서&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5231&quot; data-start=&quot;5222&quot;&gt;시험 결과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5262&quot; data-start=&quot;5232&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5244&quot; data-start=&quot;5232&quot;&gt;취약점 개선내역서&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5262&quot; data-start=&quot;5244&quot;&gt;발견된 취약점과 조치 내용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5287&quot; data-start=&quot;5264&quot; data-ke-size=&quot;size16&quot;&gt;이 문서들은 모두 한국어로 작성해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;5325&quot; data-start=&quot;5289&quot; data-ke-size=&quot;size16&quot;&gt;특히 구현명세서에는 제품의 모든 인터페이스와 계정을 적어야 한다.&lt;/p&gt;
&lt;p data-end=&quot;5399&quot; data-start=&quot;5327&quot; data-ke-size=&quot;size16&quot;&gt;시험 과정에서 명세서에 없는 인터페이스나 숨겨진 계정이 발견되면 &lt;b&gt;백도어로 간주될 수 있고, 확인서 발급이 거부될 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;숨겨진 관리자 계정
문서에 없는 디버그 포트
알려지지 않은 원격 접속 기능
개발용으로 남겨 둔 서비스

&amp;rarr; 검증 관점에서는 모두 심각한 문제&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5565&quot; data-start=&quot;5493&quot; data-ke-size=&quot;size16&quot;&gt;개발자는 편의를 위해 테스트 계정이나 디버그 기능을 남겨 둘 수 있지만, 검증 제품에서는 그런 숨겨진 기능 자체가 취약점이 된다.&lt;/p&gt;
&lt;h2 data-end=&quot;5593&quot; data-start=&quot;5567&quot; data-section-id=&quot;1r8zet6&quot; data-ke-size=&quot;size26&quot;&gt;제품 요구사항이 KCMVP를 요구하는 경우&lt;/h2&gt;
&lt;p data-end=&quot;5645&quot; data-start=&quot;5595&quot; data-ke-size=&quot;size16&quot;&gt;제품 보안요구사항에는 KCMVP 검증필 암호모듈을 사용해야 한다는 조건이 들어갈 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;5687&quot; data-start=&quot;5647&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 IP카메라가 영상을 기기 내부에 저장하는 상황을 예로 들었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;기기 내부에 영상을 저장할 때
KCMVP 검증필 암호모듈로 암호화해야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5780&quot; data-start=&quot;5745&quot; data-ke-size=&quot;size16&quot;&gt;즉 &amp;ldquo;AES로 암호화했습니다&amp;rdquo;라는 설명만으로는 부족할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;어떤 AES 구현인가?
어떤 모듈에 포함되어 있는가?
그 모듈의 버전은 무엇인가?
어떤 운영환경에서 검증됐는가?
KCMVP 검증필 목록에 등재되어 있는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5898&quot; data-start=&quot;5882&quot; data-ke-size=&quot;size16&quot;&gt;이런 부분까지 확인해야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;5909&quot; data-start=&quot;5900&quot; data-section-id=&quot;139hnja&quot; data-ke-size=&quot;size26&quot;&gt;KCMVP란&lt;/h2&gt;
&lt;p data-end=&quot;5992&quot; data-start=&quot;5911&quot; data-ke-size=&quot;size16&quot;&gt;KCMVP는 &lt;b&gt;Korea Cryptographic Module Validation Program&lt;/b&gt;의 약자로, 우리나라의 암호모듈 검증 제도다.&lt;/p&gt;
&lt;p data-end=&quot;6079&quot; data-start=&quot;5994&quot; data-ke-size=&quot;size16&quot;&gt;암호 알고리즘 이름만 확인하는 것이 아니라, 해당 알고리즘과 키 관리, 난수 생성, 자가시험 등을 포함한 암호모듈이 규격에 맞게 구현되었는지를 검증한다.&lt;/p&gt;
&lt;p data-end=&quot;6111&quot; data-start=&quot;6081&quot; data-ke-size=&quot;size16&quot;&gt;검증을 통과한 모듈은 검증필 암호모듈 목록에 등재된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;objectivec&quot;&gt;&lt;code&gt;암호모듈 개발
&amp;rarr; 시험기관 시험
&amp;rarr; NSR 검토
&amp;rarr; 검증필 목록 등재&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6191&quot; data-start=&quot;6165&quot; data-ke-size=&quot;size16&quot;&gt;실무에서 첫 번째로 확인할 질문은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;제품에 탑재한 암호모듈이
검증필 목록에 있는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;6244&quot; data-start=&quot;6233&quot; data-section-id=&quot;3kcivc&quot; data-ke-size=&quot;size26&quot;&gt;암호모듈의 경계&lt;/h2&gt;
&lt;p data-end=&quot;6274&quot; data-start=&quot;6246&quot; data-ke-size=&quot;size16&quot;&gt;KCMVP에서는 암호모듈의 &lt;b&gt;경계&lt;/b&gt;가 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;6309&quot; data-start=&quot;6276&quot; data-ke-size=&quot;size16&quot;&gt;암호모듈의 경계 안에는 다음과 같은 기능이 포함될 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;암호 알고리즘 구현
키 생성&amp;middot;저장&amp;middot;폐기 등의 키 관리
난수 생성
알고리즘 자가시험
코드 무결성 검사&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6400&quot; data-start=&quot;6380&quot; data-ke-size=&quot;size16&quot;&gt;검증은 이 경계 안을 대상으로 한다.&lt;/p&gt;
&lt;p data-end=&quot;6488&quot; data-start=&quot;6402&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 암호 라이브러리는 KCMVP 검증을 받았지만, 그 라이브러리를 호출하는 애플리케이션 코드에서 키를 로그로 출력한다면 제품 전체는 안전하지 않다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;검증필 암호모듈
&amp;ne;
그 모듈을 사용하는 모든 애플리케이션까지 자동으로 안전함&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6585&quot; data-start=&quot;6546&quot; data-ke-size=&quot;size16&quot;&gt;모듈 경계 밖의 앱 코드와 운영 설정은 별도로 안전하게 만들어야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;6604&quot; data-start=&quot;6587&quot; data-section-id=&quot;1d0ydx5&quot; data-ke-size=&quot;size26&quot;&gt;KCMVP 보안수준 1~4&lt;/h2&gt;
&lt;p data-end=&quot;6628&quot; data-start=&quot;6606&quot; data-ke-size=&quot;size16&quot;&gt;KCMVP 암호모듈에는 보안수준이 있다.&lt;/p&gt;
&lt;p data-end=&quot;6682&quot; data-start=&quot;6630&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 수준이 높아질수록 소프트웨어 구현뿐만 아니라 물리적인 침해까지 고려한다고 설명했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;수준주요 특징
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;6839&quot; data-start=&quot;6684&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;6839&quot; data-start=&quot;6709&quot;&gt;
&lt;tr data-end=&quot;6741&quot; data-start=&quot;6709&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;6719&quot; data-start=&quot;6709&quot;&gt;Level 1&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;6741&quot; data-start=&quot;6719&quot;&gt;소프트웨어 중심의 기본 구현 검증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;6773&quot; data-start=&quot;6742&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;6752&quot; data-start=&quot;6742&quot;&gt;Level 2&lt;/td&gt;
&lt;td data-end=&quot;6773&quot; data-start=&quot;6752&quot; data-col-size=&quot;sm&quot;&gt;변조 흔적과 역할 기반 접근통제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;6806&quot; data-start=&quot;6774&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;6784&quot; data-start=&quot;6774&quot;&gt;Level 3&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;6806&quot; data-start=&quot;6784&quot;&gt;물리적 침해 대응과 키 접근 보호&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;6839&quot; data-start=&quot;6807&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;6817&quot; data-start=&quot;6807&quot;&gt;Level 4&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;6839&quot; data-start=&quot;6817&quot;&gt;전압과 온도 같은 환경 이상 대응&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6907&quot; data-start=&quot;6841&quot; data-ke-size=&quot;size16&quot;&gt;무조건 가장 높은 수준이 좋은 것은 아니다. 제품이 놓이는 환경과 예상되는 공격을 고려해 적절한 수준을 선택해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;6975&quot; data-start=&quot;6909&quot; data-ke-size=&quot;size16&quot;&gt;서버에서 실행되는 소프트웨어 암호모듈과, 공격자가 직접 만질 수 있는 하드웨어 보안장비는 위협 모델이 다르기 때문이다.&lt;/p&gt;
&lt;h2 data-end=&quot;7001&quot; data-start=&quot;6977&quot; data-section-id=&quot;1qap96e&quot; data-ke-size=&quot;size26&quot;&gt;KCMVP 목록에서 확인해야 하는 정보&lt;/h2&gt;
&lt;p data-end=&quot;7049&quot; data-start=&quot;7003&quot; data-ke-size=&quot;size16&quot;&gt;검증필 목록에 비슷한 이름의 모듈이 있다고 해서 바로 사용할 수 있는 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;7086&quot; data-start=&quot;7051&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 목록에서 다음 다섯 가지를 확인해야 한다고 설명했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;모듈명과 버전
지원 알고리즘
보안수준
유효기간
운영환경&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7182&quot; data-start=&quot;7132&quot; data-ke-size=&quot;size16&quot;&gt;같은 코드라도 버전이나 운영체제, 암호모듈 경계가 다르면 다른 검증 대상으로 볼 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;7266&quot; data-start=&quot;7184&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 Linux용으로 검증된 특정 버전의 암호모듈을 다른 운영체제나 다른 버전에서 사용하면, 기존 검증의 적용 범위에 포함되지 않을 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;7293&quot; data-start=&quot;7268&quot; data-ke-size=&quot;size16&quot;&gt;그래서 실무 질문은 단순히 다음과 같지 않다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;AES를 사용했는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7340&quot; data-start=&quot;7320&quot; data-ke-size=&quot;size16&quot;&gt;조금 더 정확한 질문은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;우리가 실제로 사용하는 그 모듈과 그 버전,
그 운영환경이 검증필 목록에 있는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;7426&quot; data-start=&quot;7401&quot; data-section-id=&quot;w3sets&quot; data-ke-size=&quot;size26&quot;&gt;구현이 올바른 것과 검증필인 것은 다르다&lt;/h2&gt;
&lt;p data-end=&quot;7460&quot; data-start=&quot;7428&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 IP카메라의 영상 저장 암호화를 예시로 들었다.&lt;/p&gt;
&lt;p data-end=&quot;7560&quot; data-start=&quot;7462&quot; data-ke-size=&quot;size16&quot;&gt;AES-256-CBC를 사용하고, 프레임마다 IV를 새로 생성하며, 데이터 암호화 키인 DEK와 키 암호화 키인 KEK를 분리했다면 기술적으로는 비교적 올바른 구조일 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;AES-256-CBC
프레임 단위 암호화
DEK와 KEK 분리
IV 매번 무작위 생성&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7693&quot; data-start=&quot;7623&quot; data-ke-size=&quot;size16&quot;&gt;하지만 그 구현이 KCMVP 검증필 목록에 없는 자체 구현이라면, &amp;ldquo;검증필 암호모듈 사용&amp;rdquo;을 요구하는 조건은 충족하지 못한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;암호 사용 방법이 맞음
&amp;ne;
KCMVP 검증필 모듈임&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7823&quot; data-start=&quot;7737&quot; data-ke-size=&quot;size16&quot;&gt;수업이나 공개 예제에서는 환경 제약 때문에 일반 라이브러리를 사용할 수 있지만, 실제 제품에서는 검증필 모듈로 교체해야 한다는 점을 분명하게 적어야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;7847&quot; data-start=&quot;7825&quot; data-section-id=&quot;qsthim&quot; data-ke-size=&quot;size26&quot;&gt;KCMVP 검증 대상 암호 알고리즘&lt;/h2&gt;
&lt;p data-end=&quot;7885&quot; data-start=&quot;7849&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 KCMVP 검증 대상이 되는 암호 알고리즘도 소개했다.&lt;/p&gt;
&lt;h3 data-end=&quot;7895&quot; data-start=&quot;7887&quot; data-section-id=&quot;kj1x2b&quot; data-ke-size=&quot;size23&quot;&gt;블록암호&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;SEED
ARIA
HIGHT
LEA&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8004&quot; data-start=&quot;7930&quot; data-ke-size=&quot;size16&quot;&gt;SEED와 ARIA는 범용적인 블록암호이고, HIGHT와 LEA는 자원이 제한된 환경에서도 사용할 수 있도록 고려된 경량 블록암호다.&lt;/p&gt;
&lt;h3 data-end=&quot;8012&quot; data-start=&quot;8006&quot; data-section-id=&quot;1hrnnqm&quot; data-ke-size=&quot;size23&quot;&gt;해시&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;SHA-2
LSH&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8080&quot; data-start=&quot;8037&quot; data-ke-size=&quot;size16&quot;&gt;해시는 데이터의 무결성을 확인하거나 전자서명, 키 유도 등의 과정에 사용된다.&lt;/p&gt;
&lt;h3 data-end=&quot;8092&quot; data-start=&quot;8082&quot; data-section-id=&quot;h5jhzf&quot; data-ke-size=&quot;size23&quot;&gt;메시지 인증&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;HMAC&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8155&quot; data-start=&quot;8112&quot; data-ke-size=&quot;size16&quot;&gt;HMAC은 비밀키와 해시를 함께 사용해 메시지의 변조 여부와 인증을 확인한다.&lt;/p&gt;
&lt;h3 data-end=&quot;8169&quot; data-start=&quot;8157&quot; data-section-id=&quot;b75gpd&quot; data-ke-size=&quot;size23&quot;&gt;공개키&amp;middot;전자서명&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;RSA
KCDSA
ECDSA&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8219&quot; data-start=&quot;8200&quot; data-ke-size=&quot;size16&quot;&gt;공개키 암호와 전자서명에 사용된다.&lt;/p&gt;
&lt;h3 data-end=&quot;8233&quot; data-start=&quot;8221&quot; data-section-id=&quot;bvj9bf&quot; data-ke-size=&quot;size23&quot;&gt;키 설정과 난수&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;키 교환
키 유도
DRBG&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8314&quot; data-start=&quot;8263&quot; data-ke-size=&quot;size16&quot;&gt;DRBG는 결정론적 난수비트생성기로, 암호키와 nonce 등에 필요한 안전한 난수를 만든다.&lt;/p&gt;
&lt;p data-end=&quot;8350&quot; data-start=&quot;8316&quot; data-ke-size=&quot;size16&quot;&gt;여기서 중요한 것은 알고리즘을 하나만 골라 넣는 것이 아니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;암호화
해시
메시지 인증
키 생성과 유도
난수 생성
키 저장과 폐기
자가시험&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8440&quot; data-start=&quot;8408&quot; data-ke-size=&quot;size16&quot;&gt;이 과정이 하나의 암호모듈 안에서 안전하게 이어져야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;8466&quot; data-start=&quot;8442&quot; data-section-id=&quot;1vb8kb8&quot; data-ke-size=&quot;size26&quot;&gt;암호모듈은 스스로 상태를 점검해야 한다&lt;/h2&gt;
&lt;p data-end=&quot;8494&quot; data-start=&quot;8468&quot; data-ke-size=&quot;size16&quot;&gt;KCMVP 보안요구사항에는 자가시험도 포함된다.&lt;/p&gt;
&lt;p data-end=&quot;8518&quot; data-start=&quot;8496&quot; data-ke-size=&quot;size16&quot;&gt;대표적으로 KAT와 무결성 검사가 있다.&lt;/p&gt;
&lt;p data-end=&quot;8599&quot; data-start=&quot;8520&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;KAT(Known Answer Test)&lt;/b&gt;는 미리 정해진 입력과 정답을 가지고 암호 알고리즘이 올바른 결과를 내는지 확인하는 시험이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;정해진 입력을 암호화
&amp;rarr; 미리 알고 있는 정답과 비교
&amp;rarr; 같으면 정상
&amp;rarr; 다르면 모듈 사용 중단&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8705&quot; data-start=&quot;8668&quot; data-ke-size=&quot;size16&quot;&gt;무결성 검사는 모듈 코드나 중요 파일이 변조되지 않았는지 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;8837&quot; data-start=&quot;8707&quot; data-ke-size=&quot;size16&quot;&gt;자가시험에 실패했는데도 계속 작동하면 잘못된 암호 결과나 손상된 키가 사용될 수 있다. 그래서 실패 시 기능을 중단하는 &lt;b&gt;fail-closed&lt;/b&gt; 방식이 중요하다.&lt;/p&gt;
&lt;h2 data-end=&quot;8863&quot; data-start=&quot;8839&quot; data-section-id=&quot;ky6mk0&quot; data-ke-size=&quot;size26&quot;&gt;요구사항은 실제 코드로 구현되어야 한다&lt;/h2&gt;
&lt;p data-end=&quot;8924&quot; data-start=&quot;8865&quot; data-ke-size=&quot;size16&quot;&gt;강의 후반부에서는 IP카메라 예제 프로젝트를 통해 국가용 보안요구사항이 코드로 어떻게 연결되는지 살펴봤다.&lt;/p&gt;
&lt;p data-end=&quot;8972&quot; data-start=&quot;8926&quot; data-ke-size=&quot;size16&quot;&gt;가장 인상적이었던 점은 문서의 각 조항이 실제 조건문과 함수로 연결된다는 것이었다.&lt;/p&gt;
&lt;h3 data-end=&quot;8985&quot; data-start=&quot;8974&quot; data-section-id=&quot;1giw3nu&quot; data-ke-size=&quot;size23&quot;&gt;패스워드 정책&lt;/h3&gt;
&lt;p data-end=&quot;9078&quot; data-start=&quot;8987&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 패스워드는 9자리 이상이어야 하고, 사용자 계정과 같은 값이나 qwer, asdf, 1234처럼 단순한 키보드 연속 문자열을 제한할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;if len(password) &amp;lt; 9:
    return False

if username and password.lower() == username.lower():
    return False&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9251&quot; data-start=&quot;9206&quot; data-ke-size=&quot;size16&quot;&gt;강의 예제에서는 정방향 문자열뿐 아니라 rewq처럼 역방향 배열까지 검사했다.&lt;/p&gt;
&lt;p data-end=&quot;9350&quot; data-start=&quot;9253&quot; data-ke-size=&quot;size16&quot;&gt;결국 문서에 적힌 &amp;ldquo;취약한 패스워드를 제한한다&amp;rdquo;는 문장은 코드 안에서는 여러 개의 구체적인 조건문이 된다.&lt;/p&gt;
&lt;h3 data-end=&quot;9370&quot; data-start=&quot;9352&quot; data-section-id=&quot;o0tckv&quot; data-ke-size=&quot;size23&quot;&gt;인증 실패 5회 계정 잠금&lt;/h3&gt;
&lt;p data-end=&quot;9415&quot; data-start=&quot;9372&quot; data-ke-size=&quot;size16&quot;&gt;로그인에 연속으로 실패하면 계정을 잠그고, 그 사실을 감사기록에 남겨야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;틀린 비밀번호 5회
&amp;rarr; 계정 잠금
&amp;rarr; 잠금 사건 감사기록
&amp;rarr; 일정 시간 후 해제&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9526&quot; data-start=&quot;9475&quot; data-ke-size=&quot;size16&quot;&gt;검사기는 서버 내부 코드를 직접 보지 않고 실제 로그인을 반복해 기능이 동작하는지 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;9637&quot; data-start=&quot;9528&quot; data-ke-size=&quot;size16&quot;&gt;특히 5번 실패한 뒤 6번째 시도에서는 &lt;b&gt;정상 비밀번호&lt;/b&gt;를 입력해도 인증이 거부되어야 진짜 계정 잠금이라고 판정할 수 있다.&lt;/p&gt;
&lt;h3 data-end=&quot;9664&quot; data-start=&quot;9639&quot; data-section-id=&quot;1mma4zx&quot; data-ke-size=&quot;size23&quot;&gt;인증 실패 원인을 자세히 알려주지 않기&lt;/h3&gt;
&lt;p data-end=&quot;9717&quot; data-start=&quot;9666&quot; data-ke-size=&quot;size16&quot;&gt;로그인 실패 시 다음과 같이 구체적으로 알려주면 공격자가 계정 존재 여부를 확인할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;존재하지 않는 사용자입니다.
비밀번호가 틀렸습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9796&quot; data-start=&quot;9761&quot; data-ke-size=&quot;size16&quot;&gt;따라서 외부에는 다음처럼 같은 메시지를 보여주는 편이 안전하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;인증 실패&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9866&quot; data-start=&quot;9817&quot; data-ke-size=&quot;size16&quot;&gt;존재하는 계정과 존재하지 않는 계정의 응답을 같게 만들어 계정 열거 공격을 막는 것이다.&lt;/p&gt;
&lt;h3 data-end=&quot;9896&quot; data-start=&quot;9868&quot; data-section-id=&quot;1cbsgwz&quot; data-ke-size=&quot;size23&quot;&gt;클라이언트가 보내는 헤더를 그대로 믿지 않기&lt;/h3&gt;
&lt;p data-end=&quot;9962&quot; data-start=&quot;9898&quot; data-ke-size=&quot;size16&quot;&gt;X-Forwarded-For와 같은 HTTP 헤더는 프록시 환경에서 실제 클라이언트 IP를 전달할 때 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;10067&quot; data-start=&quot;9964&quot; data-ke-size=&quot;size16&quot;&gt;하지만 신뢰할 수 있는 프록시를 거치지 않은 상황에서는 공격자가 헤더 값을 임의로 작성할 수 있다. 따라서 IP 기반 접근통제를 구현하면서 해당 헤더를 무조건 신뢰하면 우회될 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;클라이언트가 주장하는 IP
&amp;ne;
실제로 연결한 네트워크 상대의 IP&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10198&quot; data-start=&quot;10119&quot; data-ke-size=&quot;size16&quot;&gt;강의 예제에서는 소켓에서 확인한 실제 peer 정보를 사용하도록 구현했다.&lt;/p&gt;
&lt;h3 data-end=&quot;10225&quot; data-start=&quot;10200&quot; data-section-id=&quot;1m3mcx3&quot; data-ke-size=&quot;size23&quot;&gt;구동 시 자체시험과 주기적 무결성 검사&lt;/h3&gt;
&lt;p data-end=&quot;10265&quot; data-start=&quot;10227&quot; data-ke-size=&quot;size16&quot;&gt;IP카메라가 켜질 때 다음 항목을 스스로 검사하도록 구현할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;카메라 하드웨어 접근 가능 여부
서버 연결 가능 여부
TLS 인증서 유효성
암호모듈 동작 여부&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10376&quot; data-start=&quot;10333&quot; data-ke-size=&quot;size16&quot;&gt;작동 중에는 중요 파일의 현재 해시값을 기준값과 비교해 변조 여부를 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;10517&quot; data-start=&quot;10378&quot; data-ke-size=&quot;size16&quot;&gt;강의 예제에서는 실행 시점과 24시간 주기로 무결성을 검사하고, 문제가 발생하면 안전하게 종료하는 방식을 사용했다. 이것은 KCMVP의 자가시험과 같은 방향의 설계라고 볼 수 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;10535&quot; data-start=&quot;10519&quot; data-section-id=&quot;ik7moc&quot; data-ke-size=&quot;size26&quot;&gt;감사기록도 보호해야 한다&lt;/h2&gt;
&lt;p data-end=&quot;10562&quot; data-start=&quot;10537&quot; data-ke-size=&quot;size16&quot;&gt;보안제품은 중요한 사건을 로그로 남겨야 한다.&lt;/p&gt;
&lt;p data-end=&quot;10583&quot; data-start=&quot;10564&quot; data-ke-size=&quot;size16&quot;&gt;대표적인 감사 대상은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;로그인 성공과 실패
계정 잠금
관리자 설정 변경
사용자 추가와 삭제
업데이트 수행
무결성 검사 실패
시스템 시작과 종료&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10691&quot; data-start=&quot;10665&quot; data-ke-size=&quot;size16&quot;&gt;하지만 로그를 남기는 것만으로는 충분하지 않다.&lt;/p&gt;
&lt;p data-end=&quot;10803&quot; data-start=&quot;10693&quot; data-ke-size=&quot;size16&quot;&gt;공격자가 로그를 수정하거나 삭제할 수 있다면 자신의 흔적을 없앨 수 있기 때문이다. 그래서 감사기록은 일반 사용자가 변경할 수 없도록 보호하고, 로그가 가득 찼을 때 어떻게 처리할지도 정해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;로그 생성
&amp;rarr; 권한 분리
&amp;rarr; 변경&amp;middot;삭제 방지
&amp;rarr; 저장공간 관리
&amp;rarr; 관리자 검토&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;10872&quot; data-start=&quot;10862&quot; data-section-id=&quot;770d9h&quot; data-ke-size=&quot;size26&quot;&gt;추적매트릭스란&lt;/h2&gt;
&lt;p data-end=&quot;10948&quot; data-start=&quot;10874&quot; data-ke-size=&quot;size16&quot;&gt;요구사항 문서에는 수많은 조항이 있다. 각 조항이 코드의 어느 파일과 함수에서 구현되었는지 정리한 표를 &lt;b&gt;추적매트릭스&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-end=&quot;10972&quot; data-start=&quot;10950&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같이 연결할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;요구사항구현 위치
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;11127&quot; data-start=&quot;10974&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;11127&quot; data-start=&quot;11001&quot;&gt;
&lt;tr data-end=&quot;11035&quot; data-start=&quot;11001&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;11011&quot; data-start=&quot;11001&quot;&gt;패스워드 정책&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;11035&quot; data-start=&quot;11011&quot;&gt;password_policy.py&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;11063&quot; data-start=&quot;11036&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;11050&quot; data-start=&quot;11036&quot;&gt;인증 실패 5회 잠금&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;11063&quot; data-start=&quot;11050&quot;&gt;auth.py&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;11099&quot; data-start=&quot;11064&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;11079&quot; data-start=&quot;11064&quot;&gt;유휴 10분 세션 종료&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;11099&quot; data-start=&quot;11079&quot;&gt;verify_token()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;11127&quot; data-start=&quot;11100&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;11113&quot; data-start=&quot;11100&quot;&gt;감사기록 변경 방지&lt;/td&gt;
&lt;td data-end=&quot;11127&quot; data-start=&quot;11113&quot; data-col-size=&quot;sm&quot;&gt;audit.py&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11172&quot; data-start=&quot;11129&quot; data-ke-size=&quot;size16&quot;&gt;시험관은 이 표를 따라가며 요구사항과 실제 구현이 연결되는지 확인할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;11292&quot; data-start=&quot;11174&quot; data-ke-size=&quot;size16&quot;&gt;추적매트릭스가 없다면 기능은 구현되어 있어도 어디에 있는지 찾기 어렵다. 반대로 표에 조항은 있지만 실제 코드가 없다면 미구현 상태가 드러난다.&lt;/p&gt;
&lt;h2 data-end=&quot;11314&quot; data-start=&quot;11294&quot; data-section-id=&quot;1vy5ath&quot; data-ke-size=&quot;size26&quot;&gt;조항 번호를 코드 주석에 남기기&lt;/h2&gt;
&lt;p data-end=&quot;11355&quot; data-start=&quot;11316&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 코드에 요구사항 번호를 직접 주석으로 적는 방법도 소개했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;# [NIS 2.2.1] 연속 인증 실패 시 계정 잠금
# [NIS 8.1.1] 계정 잠금 사건 감사기록&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11485&quot; data-start=&quot;11431&quot; data-ke-size=&quot;size16&quot;&gt;이런 주석을 일정한 형식으로 남기면 자동화 도구가 코드 전체를 검색해 다음 자료를 만들 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;조항별 구현 파일 목록
조항별 구현 함수 목록
미구현 조항 목록
검증 결과와 코드의 연결
구현명세서 초안&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11626&quot; data-start=&quot;11559&quot; data-ke-size=&quot;size16&quot;&gt;거창한 시스템을 처음부터 만드는 것보다, 일관된 조항 주석 한 줄이 자동화의 출발점이 될 수 있다는 설명이 인상적이었다.&lt;/p&gt;
&lt;h2 data-end=&quot;11641&quot; data-start=&quot;11628&quot; data-section-id=&quot;164ilvt&quot; data-ke-size=&quot;size26&quot;&gt;검증 자동화의 흐름&lt;/h2&gt;
&lt;p data-end=&quot;11685&quot; data-start=&quot;11643&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 요구사항을 코드와 시험으로 연결하는 과정을 여섯 단계로 정리했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. 요구사항을 체크리스트로 변환
2. 조항 주석 작성 규칙 결정
3. 조항별 기능 구현
4. 추적매트릭스 자동 생성
5. 외부 검증기 작성
6. 구현명세서와 시험결과 초안 생성&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11836&quot; data-start=&quot;11800&quot; data-ke-size=&quot;size16&quot;&gt;검증기는 내부 구현을 믿지 않고 외부에서 제품을 실제로 두드린다.&lt;/p&gt;
&lt;p data-end=&quot;11862&quot; data-start=&quot;11838&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음을 자동으로 시험할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;TLS 1.0과 1.1 연결이 거부되는가?
틀린 비밀번호를 5번 입력하면 계정이 잠기는가?
정상 비밀번호를 입력해도 잠금 상태가 유지되는가?
유휴시간이 지나면 세션이 종료되는가?
잘못된 업데이트 파일이 거부되는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;12064&quot; data-start=&quot;11997&quot; data-ke-size=&quot;size16&quot;&gt;모든 검증 결과를 PASS 또는 FAIL로 출력하고, 각 결과에 해당 조항 번호를 붙이면 시험 근거로 활용하기 쉬워진다.&lt;/p&gt;
&lt;p data-end=&quot;12096&quot; data-start=&quot;12066&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 설명한 자동화의 종료 조건은 비교적 명확했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;검증기 전 항목 PASS
+
추적매트릭스 미구현 조항 0개&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;12221&quot; data-start=&quot;12144&quot; data-ke-size=&quot;size16&quot;&gt;FAIL이 나오면 해당 조항의 구현으로 돌아가 수정하고 다시 시험한다.&lt;/p&gt;
&lt;h2 data-end=&quot;12248&quot; data-start=&quot;12223&quot; data-section-id=&quot;hbppsw&quot; data-ke-size=&quot;size26&quot;&gt;AI를 사용할 때도 원문 검수가 필요하다&lt;/h2&gt;
&lt;p data-end=&quot;12295&quot; data-start=&quot;12250&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 AI를 활용해 요구사항 구현과 검증 자동화를 보조하는 방법도 소개했다.&lt;/p&gt;
&lt;p data-end=&quot;12323&quot; data-start=&quot;12297&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음처럼 구체적으로 요청할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;IP카메라 요구사항 2.2.1을 구현한다.
연속 인증 실패 5회에서 계정을 잠근다.
5분 후 잠금을 해제한다.
잠금 발생 시 감사기록을 남긴다.
구현부마다 [NIS 2.2.1] 주석을 작성한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;12513&quot; data-start=&quot;12447&quot; data-ke-size=&quot;size16&quot;&gt;단순히 &amp;ldquo;보안을 강화해줘&amp;rdquo;라고 요청하는 것보다, 조항 번호와 수치, 필요한 산출물을 함께 알려주는 편이 훨씬 정확하다.&lt;/p&gt;
&lt;p data-end=&quot;12545&quot; data-start=&quot;12515&quot; data-ke-size=&quot;size16&quot;&gt;하지만 AI가 만든 코드와 문서는 어디까지나 초안이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;조항 번호가 맞는가?
수치를 정확히 적용했는가?
조건부 요구사항을 잘못 필수로 해석하지 않았는가?
숨겨진 인터페이스나 계정을 만들지 않았는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;12757&quot; data-start=&quot;12640&quot; data-ke-size=&quot;size16&quot;&gt;이 부분은 반드시 원문 요구사항과 대조해 사람이 검수해야 한다. 검수되지 않은 자동화는 오히려 새로운 취약점이나 문서 불일치를 만들 수 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;12776&quot; data-start=&quot;12759&quot; data-section-id=&quot;1r4fs84&quot; data-ke-size=&quot;size26&quot;&gt;이번 강의에서 기억할 핵심&lt;/h2&gt;
&lt;p data-end=&quot;12832&quot; data-start=&quot;12778&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의는 기술적으로 안전한 제품과, 공식적으로 검증된 제품 사이의 차이를 보여주는 내용이었다.&lt;/p&gt;
&lt;p data-end=&quot;12853&quot; data-start=&quot;12834&quot; data-ke-size=&quot;size16&quot;&gt;전체 흐름을 정리하면 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;보안적합성 검증
= 국가&amp;middot;공공기관 도입 전 제품 안전성 확인

보안기능 확인서
= 제품 보안기능 시험의 최종 결과물

KCMVP
= 제품 안의 암호모듈이 규격대로 구현됐는지 검증

CC 인증
= 제품 전체의 보안성 평가&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;13024&quot; data-start=&quot;12991&quot; data-ke-size=&quot;size16&quot;&gt;그리고 제품 개발자의 관점에서는 다음 흐름으로 볼 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;보안요구사항 확인
&amp;rarr; 기능 구현
&amp;rarr; 조항과 코드 연결
&amp;rarr; 자체시험과 자동 검증
&amp;rarr; 취약점 수정
&amp;rarr; 제출문서 작성
&amp;rarr; 시험기관 시험
&amp;rarr; 확인서 발급&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;13127&quot; data-start=&quot;13121&quot; data-section-id=&quot;1h9nj85&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-end=&quot;13194&quot; data-start=&quot;13129&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의를 듣기 전에는 제품에 AES나 TLS 같은 안전한 기술을 사용하면 보안제품이라고 부를 수 있다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;13319&quot; data-start=&quot;13196&quot; data-ke-size=&quot;size16&quot;&gt;하지만 어떤 알고리즘을 사용했는지만으로는 부족했다. 암호모듈의 버전과 운영환경, 키 관리, 난수 생성, 자가시험까지 확인해야 하고, 제품 차원에서는 인증과 세션, 업데이트, 감사기록, 자체보호 기능도 함께 검증해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;13359&quot; data-start=&quot;13321&quot; data-ke-size=&quot;size16&quot;&gt;무엇보다 중요한 점은 &lt;b&gt;구현과 증명은 별개의 작업&lt;/b&gt;이라는 것이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;코드를 잘 작성하는 것
요구사항을 정확히 구현하는 것
실제 동작을 시험하는 것
시험 결과를 문서로 남기는 것
공식 검증기관의 확인을 받는 것&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;13485&quot; data-start=&quot;13453&quot; data-ke-size=&quot;size16&quot;&gt;이 모든 과정이 연결되어야 비로소 &amp;ldquo;검증된 제품&amp;rdquo;이 된다.&lt;/p&gt;
&lt;p data-end=&quot;13520&quot; data-start=&quot;13487&quot; data-ke-size=&quot;size16&quot;&gt;이번 6강의 핵심은 다음 문장으로 정리할 수 있을 것 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;보안은 &amp;ldquo;안전하게 만들었다&amp;rdquo;는 주장으로 끝나지 않는다.

무엇을 구현했고,
어떻게 시험했으며,
누가 그 결과를 확인했는지를
증명할 수 있어야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>하계 보안 세미나</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/8</guid>
      <comments>https://song-song.tistory.com/8#entry8comment</comments>
      <pubDate>Fri, 10 Jul 2026 15:40:24 +0900</pubDate>
    </item>
    <item>
      <title>하계 보안 세미나 5일차 - 시큐어코딩 (임베디드&amp;middot;자동차 코딩 표준)</title>
      <link>https://song-song.tistory.com/7</link>
      <description>&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-6a3a1513-0ef8-83e8-a772-7f568a0759a7-13&quot;&gt;
&lt;div data-conversation-screenshot-content=&quot;&quot;&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-5-thinking&quot; data-turn-start-message=&quot;true&quot; data-message-id=&quot;2f7464ee-b50e-4798-b52a-d260a512ea01&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;p data-end=&quot;260&quot; data-start=&quot;219&quot; data-ke-size=&quot;size16&quot;&gt;이번 5강에서는 &lt;b&gt;시큐어 코딩과 임베디드&amp;middot;자동차 코딩 표준&lt;/b&gt;을 배웠다.&lt;/p&gt;
&lt;p data-end=&quot;365&quot; data-start=&quot;262&quot; data-ke-size=&quot;size16&quot;&gt;이전 강의에서는 암호가 어떤 원리로 깨지는지, 양자내성암호가 왜 필요한지, 자동차 안에는 어떤 장치와 통신망이 있는지를 살펴봤다. 이번 강의는 그보다 조금 더 코드에 가까운 내용이었다.&lt;/p&gt;
&lt;p data-end=&quot;491&quot; data-start=&quot;367&quot; data-ke-size=&quot;size16&quot;&gt;버퍼 오버플로우, 해제된 메모리 사용, 널 포인터 역참조, 정수 오버플로우처럼 C와 C++에서 자주 발생하는 문제를 살펴보고, 이런 코드를 MISRA, AUTOSAR, CERT C 같은 표준에서는 어떻게 설명하는지 배웠다.&lt;/p&gt;
&lt;p data-end=&quot;528&quot; data-start=&quot;493&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의의 핵심은 단순히 다음과 같이 말하는 데 있지 않았다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;이 코드는 위험하다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;586&quot; data-start=&quot;555&quot; data-ke-size=&quot;size16&quot;&gt;조금 더 구체적으로 다음과 같이 설명할 수 있어야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;어떤 경계 검사가 빠졌는가?
어떤 표준 규칙을 위반했는가?
어떻게 수정해야 하는가?
수정됐다는 사실을 어떤 도구와 테스트로 증명할 것인가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;760&quot; data-start=&quot;679&quot; data-ke-size=&quot;size16&quot;&gt;즉 시큐어 코딩은 단순히 코드를 조심해서 작성하는 것이 아니라, &lt;b&gt;위험한 코드를 공통된 규칙으로 설명하고 검증하는 과정&lt;/b&gt;이라고 볼 수 있었다.&lt;/p&gt;
&lt;h2 data-end=&quot;778&quot; data-start=&quot;762&quot; data-section-id=&quot;c5vggv&quot; data-ke-size=&quot;size26&quot;&gt;시큐어 코딩이란 무엇인가&lt;/h2&gt;
&lt;p data-end=&quot;831&quot; data-start=&quot;780&quot; data-ke-size=&quot;size16&quot;&gt;시큐어 코딩은 처음부터 취약점이 생기지 않도록 안전한 방식으로 코드를 작성하는 것을 말한다.&lt;/p&gt;
&lt;p data-end=&quot;913&quot; data-start=&quot;833&quot; data-ke-size=&quot;size16&quot;&gt;보안 문제가 발견된 후 패치하는 것도 중요하지만, 개발 단계에서부터 위험한 코드 패턴을 제한하면 취약점이 만들어질 가능성 자체를 줄일 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1023&quot; data-start=&quot;915&quot; data-ke-size=&quot;size16&quot;&gt;특히 자동차와 임베디드 환경에서는 작은 실수가 단순한 프로그램 오류에서 끝나지 않을 수 있다. 센서값을 잘못 읽거나 ECU가 중단되면 차량 기능이나 실제 안전에까지 영향을 줄 수 있기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;1063&quot; data-start=&quot;1025&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 취약점이 주로 다음 네 가지 경계에서 시작한다고 설명했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;입력 경계
메모리 수명
권한 경계
시간 예측성&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1104&quot; data-ke-size=&quot;size16&quot;&gt;입력 경계에서는 데이터의 길이와 타입을 확인해야 한다. 메모리 수명에서는 누가 메모리를 할당하고 해제하는지 분명해야 한다. 권한 경계에서는 어떤 사용자가 어떤 API나 기능을 호출할 수 있는지를 검사해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;1308&quot; data-start=&quot;1223&quot; data-ke-size=&quot;size16&quot;&gt;자동차 코드에서는 시간도 중요한 경계다. 평균적으로 빠르게 동작하는 것보다, 가장 오래 걸리는 경우에도 정해진 시간 안에 끝나는지가 더 중요할 수 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;1328&quot; data-start=&quot;1310&quot; data-section-id=&quot;ni0gyc&quot; data-ke-size=&quot;size26&quot;&gt;표준마다 하는 역할이 다르다&lt;/h2&gt;
&lt;p data-end=&quot;1408&quot; data-start=&quot;1330&quot; data-ke-size=&quot;size16&quot;&gt;강의에는 MISRA, AUTOSAR C++14, SEI CERT C, ISO 26262, ISO/SAE 21434처럼 여러 표준이 등장했다.&lt;/p&gt;
&lt;p data-end=&quot;1469&quot; data-start=&quot;1410&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 비슷한 문서들이 이름만 다르게 존재하는 것처럼 느껴졌다. 하지만 각각 보는 범위와 질문이 달랐다.&lt;/p&gt;
&lt;h3 data-end=&quot;1486&quot; data-start=&quot;1471&quot; data-section-id=&quot;1abarql&quot; data-ke-size=&quot;size23&quot;&gt;MISRA C/C++&lt;/h3&gt;
&lt;p data-end=&quot;1537&quot; data-start=&quot;1488&quot; data-ke-size=&quot;size16&quot;&gt;MISRA는 임베디드 환경에서 C와 C++의 위험한 기능을 제한하기 위한 코딩 규칙이다.&lt;/p&gt;
&lt;p data-end=&quot;1662&quot; data-start=&quot;1539&quot; data-ke-size=&quot;size16&quot;&gt;C언어는 메모리와 포인터를 직접 제어할 수 있어 빠르고 자유롭지만, 개발자가 실수하면 정의되지 않은 동작이나 메모리 손상이 발생할 수 있다. MISRA는 이런 자유를 일부 제한해서 코드의 동작을 더 예측 가능하게 만든다.&lt;/p&gt;
&lt;p data-end=&quot;1682&quot; data-start=&quot;1664&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 다음 질문을 다룬다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;brainfuck&quot;&gt;&lt;code&gt;C와 C++를 어떤 방식으로 작성해야 안전한가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1741&quot; data-start=&quot;1724&quot; data-section-id=&quot;rypyq7&quot; data-ke-size=&quot;size23&quot;&gt;AUTOSAR C++14&lt;/h3&gt;
&lt;p data-end=&quot;1795&quot; data-start=&quot;1743&quot; data-ke-size=&quot;size16&quot;&gt;AUTOSAR C++14는 자동차에서 현대적인 C++ 기능을 안전하게 사용하기 위한 지침이다.&lt;/p&gt;
&lt;p data-end=&quot;1893&quot; data-start=&quot;1797&quot; data-ke-size=&quot;size16&quot;&gt;스마트 포인터, RAII, 템플릿, 예외, 상속처럼 C++에서 제공하는 기능을 무조건 금지하는 것이 아니라, 안전성과 실행시간 예측 가능성을 유지할 수 있는 범위를 정한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;brainfuck&quot;&gt;&lt;code&gt;자동차 환경에서 C++ 기능을 어디까지, 어떻게 사용할 것인가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1958&quot; data-start=&quot;1944&quot; data-section-id=&quot;qqosu2&quot; data-ke-size=&quot;size23&quot;&gt;SEI CERT C&lt;/h3&gt;
&lt;p data-end=&quot;2003&quot; data-start=&quot;1960&quot; data-ke-size=&quot;size16&quot;&gt;CERT C는 취약점으로 이어질 수 있는 C 코드 패턴을 설명하는 데 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;2080&quot; data-start=&quot;2005&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 버퍼 오버플로우, 널 포인터 역참조, 해제 후 사용, 정수 오버플로우, 포맷 스트링 문제를 각각 규칙 번호와 함께 설명한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이 코드 패턴이 실제 보안 취약점으로 이어질 수 있는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;2155&quot; data-start=&quot;2127&quot; data-section-id=&quot;1cnjaws&quot; data-ke-size=&quot;size23&quot;&gt;ISO 26262와 ISO/SAE 21434&lt;/h3&gt;
&lt;p data-end=&quot;2213&quot; data-start=&quot;2157&quot; data-ke-size=&quot;size16&quot;&gt;ISO 26262는 자동차 기능안전 표준이고, ISO/SAE 21434는 자동차 사이버보안 표준이다.&lt;/p&gt;
&lt;p data-end=&quot;2294&quot; data-start=&quot;2215&quot; data-ke-size=&quot;size16&quot;&gt;이 두 표준은 특정 함수나 문법을 어떻게 작성할지 알려주는 코딩 규칙이라기보다, 위험을 어떻게 분석하고 관리하며 검증 근거를 남길지를 다룬다.&lt;/p&gt;
&lt;p data-end=&quot;2320&quot; data-start=&quot;2296&quot; data-ke-size=&quot;size16&quot;&gt;정리하면 다음 세 층으로 구분할 수 있었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;언어 규칙
MISRA, AUTOSAR

취약점 설명
CERT C

안전&amp;middot;보안 프로세스와 증거
ISO 26262, ISO/SAE 21434&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;2435&quot; data-start=&quot;2412&quot; data-section-id=&quot;l28ngr&quot; data-ke-size=&quot;size26&quot;&gt;Safety와 Security의 차이&lt;/h2&gt;
&lt;p data-end=&quot;2504&quot; data-start=&quot;2437&quot; data-ke-size=&quot;size16&quot;&gt;ISO 26262와 ISO/SAE 21434를 구분하면서 Safety와 Security의 차이도 다시 정리할 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2602&quot; data-start=&quot;2506&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Safety&lt;/b&gt;는 시스템의 고장이나 오작동이 사람을 해치지 않도록 하는 것이다.&lt;br /&gt;반면 &lt;b&gt;Security&lt;/b&gt;는 외부 공격자가 시스템을 침해하지 못하도록 막는 것이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;Safety
시스템 &amp;rarr; 바깥세상
시스템이 사람을 해치지 않도록 관리

Security
바깥세상 &amp;rarr; 시스템
공격자가 시스템을 뚫지 못하도록 관리&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2783&quot; data-start=&quot;2697&quot; data-ke-size=&quot;size16&quot;&gt;ISO 26262에서는 HARA를 통해 위험을 분석하고 ASIL 등급을 정한다. ISO/SAE 21434에서는 TARA를 통해 사이버보안 위협을 분석한다.&lt;/p&gt;
&lt;p data-end=&quot;2869&quot; data-start=&quot;2785&quot; data-ke-size=&quot;size16&quot;&gt;둘은 서로 다른 분야처럼 보이지만 자동차에서는 연결되어 있다. 보안 공격으로 ECU나 차량 기능이 오작동하면 결국 안전사고로 이어질 수 있기 때문이다.&lt;/p&gt;
&lt;h2 data-end=&quot;2897&quot; data-start=&quot;2871&quot; data-section-id=&quot;6rq1v&quot; data-ke-size=&quot;size26&quot;&gt;TARA는 위협을 위험도로 바꾸는 과정이다&lt;/h2&gt;
&lt;p data-end=&quot;2967&quot; data-start=&quot;2899&quot; data-ke-size=&quot;size16&quot;&gt;TARA는 Threat Analysis and Risk Assessment의 약자로, 위협 분석 및 위험 평가를 의미한다.&lt;/p&gt;
&lt;p data-end=&quot;3047&quot; data-start=&quot;2969&quot; data-ke-size=&quot;size16&quot;&gt;단순히 &amp;ldquo;이 시스템에 취약점이 있다&amp;rdquo;고 말하는 것이 아니라, 그 취약점이 얼마나 위험한지 평가하고 어떤 대응이 필요한지를 결정하는 과정이다.&lt;/p&gt;
&lt;p data-end=&quot;3077&quot; data-start=&quot;3049&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 TARA의 흐름을 다음과 같이 설명했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;자산 식별
&amp;rarr; 위협 시나리오 식별
&amp;rarr; 영향 평가
&amp;rarr; 공격 경로 분석
&amp;rarr; 공격 실현 가능성 평가
&amp;rarr; 리스크 결정
&amp;rarr; 리스크 처리&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3257&quot; data-start=&quot;3163&quot; data-ke-size=&quot;size16&quot;&gt;먼저 보호해야 할 자산을 찾고, 어떤 공격이 가능한지 생각한다. 이후 공격이 실제로 일어났을 때 안전, 재정, 운영, 개인정보 측면에서 어떤 피해가 발생하는지 평가한다.&lt;/p&gt;
&lt;p data-end=&quot;3344&quot; data-start=&quot;3259&quot; data-ke-size=&quot;size16&quot;&gt;공격에 필요한 시간, 지식, 장비, 접근 기회도 함께 고려한다. 마지막에는 위험을 회피할지, 줄일지, 다른 곳으로 전가할지, 아니면 수용할지를 결정한다.&lt;/p&gt;
&lt;p data-end=&quot;3433&quot; data-start=&quot;3346&quot; data-ke-size=&quot;size16&quot;&gt;이 과정이 필요한 이유는 모든 취약점을 같은 수준으로 처리할 수 없기 때문이다. 단순한 화면 오류와 원격 차량 제어 가능성을 같은 우선순위로 볼 수는 없다.&lt;/p&gt;
&lt;h2 data-end=&quot;3465&quot; data-start=&quot;3435&quot; data-section-id=&quot;6gfm9g&quot; data-ke-size=&quot;size26&quot;&gt;Shift Left: 보안을 개발 초기에 적용하기&lt;/h2&gt;
&lt;p data-end=&quot;3506&quot; data-start=&quot;3467&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 기억에 남았던 개념 중 하나가 &lt;b&gt;Shift Left&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;3542&quot; data-start=&quot;3508&quot; data-ke-size=&quot;size16&quot;&gt;일반적인 개발 흐름을 왼쪽에서 오른쪽으로 적으면 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;요구사항 &amp;rarr; 설계 &amp;rarr; 구현 &amp;rarr; 분석 &amp;rarr; 검증&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3629&quot; data-start=&quot;3582&quot; data-ke-size=&quot;size16&quot;&gt;Shift Left는 보안 검사와 테스트를 가능한 한 앞 단계로 옮기는 것을 말한다.&lt;/p&gt;
&lt;p data-end=&quot;3716&quot; data-start=&quot;3631&quot; data-ke-size=&quot;size16&quot;&gt;완성된 제품에서 취약점이 발견되면 설계나 구조까지 다시 바꿔야 할 수 있다. 반면 요구사항이나 설계 단계에서 발견하면 더 적은 비용으로 수정할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;3768&quot; data-start=&quot;3718&quot; data-ke-size=&quot;size16&quot;&gt;따라서 정적 분석이나 보안 테스트를 개발 마지막에 한 번 실행하는 것으로 끝내면 안 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;요구사항
보안 요구와 금지 사항 작성

설계
위협 모델과 권한 경계 정의

구현
코딩 표준과 코드 리뷰 적용

분석
정적 분석과 Sanitizer 실행

검증
테스트 결과와 수정 근거 기록&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3935&quot; data-start=&quot;3889&quot; data-ke-size=&quot;size16&quot;&gt;도구는 최종 검사관이 아니라 개발 과정에 계속 붙어 있어야 한다는 의미로 이해했다.&lt;/p&gt;
&lt;h2 data-end=&quot;3949&quot; data-start=&quot;3937&quot; data-section-id=&quot;jjbu9p&quot; data-ke-size=&quot;size26&quot;&gt;스택과 힙의 차이&lt;/h2&gt;
&lt;p data-end=&quot;3984&quot; data-start=&quot;3951&quot; data-ke-size=&quot;size16&quot;&gt;메모리 취약점을 이해하려면 스택과 힙의 차이를 알아야 한다.&lt;/p&gt;
&lt;h3 data-end=&quot;3992&quot; data-start=&quot;3986&quot; data-section-id=&quot;1hroczj&quot; data-ke-size=&quot;size23&quot;&gt;스택&lt;/h3&gt;
&lt;p data-end=&quot;4060&quot; data-start=&quot;3994&quot; data-ke-size=&quot;size16&quot;&gt;스택은 함수가 호출될 때마다 만들어지는 임시 공간이다. 지역 변수, 함수의 반환 주소, 저장된 레지스터 등이 들어간다.&lt;/p&gt;
&lt;p data-end=&quot;4085&quot; data-start=&quot;4062&quot; data-ke-size=&quot;size16&quot;&gt;함수가 끝나면 해당 공간의 수명도 끝난다.&lt;/p&gt;
&lt;p data-end=&quot;4174&quot; data-start=&quot;4087&quot; data-ke-size=&quot;size16&quot;&gt;스택의 고정 길이 배열에 너무 긴 값을 복사하면 주변 메모리까지 덮어쓸 수 있다. 경우에 따라 반환 주소가 변조되어 프로그램의 실행 흐름이 바뀔 수도 있다.&lt;/p&gt;
&lt;h3 data-end=&quot;4181&quot; data-start=&quot;4176&quot; data-section-id=&quot;1mnllr&quot; data-ke-size=&quot;size23&quot;&gt;힙&lt;/h3&gt;
&lt;p data-end=&quot;4231&quot; data-start=&quot;4183&quot; data-ke-size=&quot;size16&quot;&gt;힙은 malloc이나 new처럼 프로그램 실행 중에 동적으로 할당하는 공간이다.&lt;/p&gt;
&lt;p data-end=&quot;4299&quot; data-start=&quot;4233&quot; data-ke-size=&quot;size16&quot;&gt;스택보다 객체의 수명을 자유롭게 관리할 수 있지만, 개발자가 직접 할당과 해제를 관리해야 하므로 문제가 발생하기 쉽다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;irpf90&quot;&gt;&lt;code&gt;스택에서 자주 발생하는 문제
스택 버퍼 오버플로우

힙에서 자주 발생하는 문제
힙 오버플로우
Use-After-Free
Double Free
메모리 누수&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4506&quot; data-start=&quot;4400&quot; data-ke-size=&quot;size16&quot;&gt;자동차와 임베디드 코드에서는 실행 중 동적 메모리 할당을 아예 금지하거나 초기화 단계에서만 허용하는 경우도 있다고 한다. 실행시간을 예측하기 어렵고 메모리 단편화가 발생할 수 있기 때문이다.&lt;/p&gt;
&lt;h2 data-end=&quot;4522&quot; data-start=&quot;4508&quot; data-section-id=&quot;1xj9144&quot; data-ke-size=&quot;size26&quot;&gt;스택 버퍼 오버플로우&lt;/h2&gt;
&lt;p data-end=&quot;4552&quot; data-start=&quot;4524&quot; data-ke-size=&quot;size16&quot;&gt;다음 코드는 강의에서 나온 대표적인 위험 패턴이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;void handle_name(const char *input)
{
    char name[16];

    strcpy(name, input);

    printf(&quot;hello %s\n&quot;, name);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4784&quot; data-start=&quot;4682&quot; data-ke-size=&quot;size16&quot;&gt;name은 16바이트 배열인데, input의 길이는 검사하지 않는다. 만약 16바이트보다 긴 문자열이 들어오면 남은 문자가 사라지는 것이 아니라 배열 옆의 메모리까지 덮어쓴다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;입력 길이 &amp;gt; 버퍼 크기
&amp;rarr; 인접 메모리 덮어쓰기
&amp;rarr; 다른 변수 또는 반환 주소 손상
&amp;rarr; 프로그램 중단이나 실행 흐름 변조&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4944&quot; data-start=&quot;4868&quot; data-ke-size=&quot;size16&quot;&gt;이 문제의 핵심은 strcpy()라는 함수 이름만이 아니다. &lt;b&gt;복사되는 데이터의 최대 크기를 코드가 보장하지 않는 것&lt;/b&gt;이 문제다.&lt;/p&gt;
&lt;p data-end=&quot;4985&quot; data-start=&quot;4946&quot; data-ke-size=&quot;size16&quot;&gt;조금 더 안전한 형태는 다음과 같이 대상 버퍼 크기를 지정하는 것이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;void better(const char *input)
{
    char name[16];

    snprintf(name, sizeof(name), &quot;%s&quot;, input);
    name[sizeof(name) - 1] = '\0';
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5206&quot; data-start=&quot;5134&quot; data-ke-size=&quot;size16&quot;&gt;하지만 snprintf()를 사용했다고 자동으로 모든 문제가 해결되는 것은 아니다. 문자열이 잘렸는지 반환값도 확인해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;5225&quot; data-start=&quot;5208&quot; data-ke-size=&quot;size16&quot;&gt;결국 중요한 질문은 이것이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이 복사의 최대 길이는 어디에서 보장되는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;5274&quot; data-start=&quot;5265&quot; data-section-id=&quot;1rfn0ak&quot; data-ke-size=&quot;size26&quot;&gt;스택 카나리&lt;/h2&gt;
&lt;p data-end=&quot;5311&quot; data-start=&quot;5276&quot; data-ke-size=&quot;size16&quot;&gt;스택 버퍼 오버플로우를 탐지하는 방어 기법 중 하나가 카나리다.&lt;/p&gt;
&lt;p data-end=&quot;5384&quot; data-start=&quot;5313&quot; data-ke-size=&quot;size16&quot;&gt;카나리는 지역 버퍼와 반환 주소 사이에 넣어 두는 특별한 값이다. 버퍼가 넘쳐 반환 주소까지 덮으려면 카나리 값이 먼저 바뀐다.&lt;/p&gt;
&lt;p data-end=&quot;5436&quot; data-start=&quot;5386&quot; data-ke-size=&quot;size16&quot;&gt;함수가 종료될 때 카나리 값이 원래 값과 같은지 확인하고, 달라졌다면 프로그램을 중단한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;지역 버퍼
&amp;rarr; 카나리
&amp;rarr; 프레임 포인터
&amp;rarr; 반환 주소&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5551&quot; data-start=&quot;5481&quot; data-ke-size=&quot;size16&quot;&gt;카나리는 전형적인 연속 덮어쓰기 공격을 탐지하는 데 도움이 된다. 그러나 논리 버그, 힙 오염, 정보 유출까지 막지는 못한다.&lt;/p&gt;
&lt;p data-end=&quot;5590&quot; data-start=&quot;5553&quot; data-ke-size=&quot;size16&quot;&gt;공격자가 카나리 값을 먼저 알아낸다면 우회 가능성도 생길 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;5626&quot; data-start=&quot;5592&quot; data-ke-size=&quot;size16&quot;&gt;따라서 카나리는 근본적인 해결책이 아니라 추가적인 안전장치다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;잘못된 생각
카나리가 있으므로 오버플로우가 있어도 괜찮다.

올바른 방향
오버플로우가 발생하지 않도록 경계를 검사하고,
카나리는 추가 방어로 사용한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;5751&quot; data-start=&quot;5726&quot; data-section-id=&quot;9wy90b&quot; data-ke-size=&quot;size26&quot;&gt;Use-After-Free와 메모리 수명&lt;/h2&gt;
&lt;p data-end=&quot;5788&quot; data-start=&quot;5753&quot; data-ke-size=&quot;size16&quot;&gt;힙에서는 포인터의 수명을 잘못 관리해서 문제가 발생할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;char *make_token(void)
{
    char *p = malloc(32);

    if (p == NULL) {
        return NULL;
    }

    strcpy(p, &quot;session&quot;);
    free(p);

    return p;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6008&quot; data-start=&quot;5957&quot; data-ke-size=&quot;size16&quot;&gt;이 코드에서는 p가 가리키는 메모리를 free()로 해제한 뒤 그 포인터를 반환한다.&lt;/p&gt;
&lt;p data-end=&quot;6100&quot; data-start=&quot;6010&quot; data-ke-size=&quot;size16&quot;&gt;포인터 변수 자체에는 예전 주소가 남아 있지만, 그 메모리는 더 이상 이 코드가 사용할 수 있는 공간이 아니다. 이후 다른 데이터가 그 위치를 사용할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;6151&quot; data-start=&quot;6102&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 해제된 메모리에 다시 접근하는 문제를 &lt;b&gt;Use-After-Free&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;irpf90&quot;&gt;&lt;code&gt;malloc
&amp;rarr; 정상 사용
&amp;rarr; free
&amp;rarr; 포인터는 남아 있지만 메모리 수명 종료
&amp;rarr; 다시 접근하면 Use-After-Free&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6334&quot; data-start=&quot;6237&quot; data-ke-size=&quot;size16&quot;&gt;이를 막으려면 누가 메모리를 해제할 책임이 있는지 명확해야 한다. C++에서는 스마트 포인터나 컨테이너를 사용하여 소유권과 해제를 객체 수명에 묶는 RAII 방식이 권장된다.&lt;/p&gt;
&lt;h2 data-end=&quot;6348&quot; data-start=&quot;6336&quot; data-section-id=&quot;k3xkgk&quot; data-ke-size=&quot;size26&quot;&gt;널 포인터 역참조&lt;/h2&gt;
&lt;p data-end=&quot;6386&quot; data-start=&quot;6350&quot; data-ke-size=&quot;size16&quot;&gt;포인터가 항상 정상적인 객체를 가리킨다고 가정하는 것도 위험하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;int read_sensor(struct sensor *s)
{
    return s-&amp;gt;value;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6511&quot; data-start=&quot;6457&quot; data-ke-size=&quot;size16&quot;&gt;s가 NULL이라면 s-&amp;gt;value에 접근하는 순간 프로그램이 비정상 종료될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;6561&quot; data-start=&quot;6513&quot; data-ke-size=&quot;size16&quot;&gt;자동차 시스템에서는 단순한 크래시도 서비스 거부나 안전 기능 중단으로 이어질 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;int safe_read_sensor(struct sensor *s, int *out)
{
    if ((s == NULL) || (out == NULL)) {
        return -1;
    }

    *out = s-&amp;gt;value;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6770&quot; data-start=&quot;6727&quot; data-ke-size=&quot;size16&quot;&gt;중요한 것은 정상적인 입력뿐만 아니라 실패 경로도 설계하고 테스트하는 것이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;센서 포인터가 NULL이면 어떻게 할 것인가?
읽기 함수가 실패하면 받은 데이터는 사용할 수 있는가?
일부만 초기화된 상태에서는 어떻게 정리할 것인가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;6888&quot; data-start=&quot;6870&quot; data-section-id=&quot;u1xuiq&quot; data-ke-size=&quot;size26&quot;&gt;정수 오버플로우와 값의 절단&lt;/h2&gt;
&lt;p data-end=&quot;6929&quot; data-start=&quot;6890&quot; data-ke-size=&quot;size16&quot;&gt;정수 오버플로우는 계산 결과가 변수의 표현 범위를 넘어설 때 발생한다.&lt;/p&gt;
&lt;p data-end=&quot;7016&quot; data-start=&quot;6931&quot; data-ke-size=&quot;size16&quot;&gt;특히 메모리 크기를 계산할 때 정수 오버플로우가 발생하면 실제 필요한 크기보다 작은 메모리를 할당하고, 그보다 많은 데이터를 쓰는 문제가 생길 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;uint16_t count = get_count();
uint16_t size = count * sizeof(struct item);

struct item *buf = malloc(size);
read_items(buf, count);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7233&quot; data-start=&quot;7161&quot; data-ke-size=&quot;size16&quot;&gt;count * sizeof(struct item)의 결과가 16비트 범위를 넘으면 size에는 잘린 값이 저장될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;7329&quot; data-start=&quot;7235&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 실제로는 70,000바이트가 필요하지만 변수에는 훨씬 작은 값이 들어갈 수 있다. 그러면 작은 공간만 할당한 뒤 많은 데이터를 써서 힙 오버플로우가 발생한다.&lt;/p&gt;
&lt;p data-end=&quot;7371&quot; data-start=&quot;7331&quot; data-ke-size=&quot;size16&quot;&gt;수정할 때는 계산 전 상한을 검사하고, 더 넓은 타입으로 계산해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;if (count &amp;gt; MAX_COUNT) {
    return ERR_RANGE;
}

size_t size = (size_t)count * sizeof(struct item);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7575&quot; data-start=&quot;7484&quot; data-ke-size=&quot;size16&quot;&gt;여기서 연산 결과가 타입 범위를 넘어 다시 처음부터 시작하는 것을 래핑이라고 한다. 큰 타입의 값을 작은 타입에 넣으면서 상위 비트가 사라지는 것은 절단에 가깝다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;INT30-C
덧셈이나 곱셈 같은 연산 결과가 범위를 넘는 문제

INT31-C
큰 값을 작은 타입으로 변환하면서 값이 손실되는 문제&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7702&quot; data-start=&quot;7665&quot; data-ke-size=&quot;size16&quot;&gt;둘은 비슷해 보이지만 발생하는 지점이 다르기 때문에 구분해야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;7717&quot; data-start=&quot;7704&quot; data-section-id=&quot;1gawg5i&quot; data-ke-size=&quot;size26&quot;&gt;포맷 스트링 취약점&lt;/h2&gt;
&lt;p data-end=&quot;7740&quot; data-start=&quot;7719&quot; data-ke-size=&quot;size16&quot;&gt;출력 함수도 입력 검증의 대상이 된다.&lt;/p&gt;
&lt;p data-end=&quot;7788&quot; data-start=&quot;7742&quot; data-ke-size=&quot;size16&quot;&gt;다음 코드에서는 사용자 입력을 그대로 printf()의 포맷 문자열로 사용한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;void bad(char *user)
{
    printf(user);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7927&quot; data-start=&quot;7843&quot; data-ke-size=&quot;size16&quot;&gt;사용자 입력에 %x, %s, %n 같은 형식 지정자가 들어 있으면 printf()는 이를 단순한 문자로 출력하지 않고 명령처럼 해석한다.&lt;/p&gt;
&lt;p data-end=&quot;7976&quot; data-start=&quot;7929&quot; data-ke-size=&quot;size16&quot;&gt;그 결과 메모리 내용이 출력되거나, 특정 조건에서는 메모리에 값이 기록될 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;8003&quot; data-start=&quot;7978&quot; data-ke-size=&quot;size16&quot;&gt;다음처럼 포맷 문자열을 상수로 고정해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;void better(char *user)
{
    printf(&quot;%s&quot;, user);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8100&quot; data-start=&quot;8067&quot; data-ke-size=&quot;size16&quot;&gt;이 부분의 핵심은 &lt;b&gt;데이터와 명령을 분리하는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;printf(user)
사용자 데이터가 명령으로 해석됨

printf(&quot;%s&quot;, user)
포맷은 개발자가 고정하고 사용자 입력은 값으로만 처리&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;8217&quot; data-start=&quot;8196&quot; data-section-id=&quot;1cvo1n4&quot; data-ke-size=&quot;size26&quot;&gt;MISRA 규칙을 코드에 연결하기&lt;/h2&gt;
&lt;p data-end=&quot;8269&quot; data-start=&quot;8219&quot; data-ke-size=&quot;size16&quot;&gt;MISRA 규칙을 모두 외우는 것보다, 규칙이 어떤 위험을 막는지 이해하는 것이 중요했다.&lt;/p&gt;
&lt;p data-end=&quot;8296&quot; data-start=&quot;8271&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 다음 규칙들이 대표적으로 소개됐다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Rule 1.3
정의되지 않은 동작에 의존하지 않는다.

Rule 10.3
더 좁은 타입에 값을 그대로 대입하지 않는다.

Rule 17.7
void가 아닌 함수의 반환값을 무시하지 않는다.

Rule 18.1
포인터 산술은 같은 배열 범위 안에서만 수행한다.

Rule 21.3
malloc/free 계열의 동적 메모리 할당을 사용하지 않는다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8558&quot; data-start=&quot;8505&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 CAN 메시지 길이를 32비트 변수에서 8비트 변수로 옮기는 상황을 생각할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;uint32_t len = get_frame_len();
uint8_t dlc = len;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8696&quot; data-start=&quot;8621&quot; data-ke-size=&quot;size16&quot;&gt;len이 255보다 크면 값이 잘릴 수 있다. 단순히 명시적 형변환을 붙이는 것만으로는 부족하고, 먼저 허용 범위를 검사해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;if (len &amp;gt; 8u) {
    return ERR_BAD_LEN;
}

uint8_t dlc = (uint8_t)len;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8829&quot; data-start=&quot;8779&quot; data-ke-size=&quot;size16&quot;&gt;자동차 코드에서는 CAN의 데이터 길이처럼 프로토콜이 허용하는 범위와 함께 검증해야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;8853&quot; data-start=&quot;8831&quot; data-section-id=&quot;168fv2a&quot; data-ke-size=&quot;size26&quot;&gt;CERT C 규칙과 취약 코드 연결&lt;/h2&gt;
&lt;p data-end=&quot;8891&quot; data-start=&quot;8855&quot; data-ke-size=&quot;size16&quot;&gt;CERT C는 취약 코드와 규칙을 직접 연결해서 설명하기 좋았다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;취약 패턴CERT C 규칙
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;9065&quot; data-start=&quot;8893&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;9065&quot; data-start=&quot;8925&quot;&gt;
&lt;tr data-end=&quot;8950&quot; data-start=&quot;8925&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;8939&quot; data-start=&quot;8925&quot;&gt;스택 버퍼 오버플로우&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;8950&quot; data-start=&quot;8939&quot;&gt;STR31-C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;8972&quot; data-start=&quot;8951&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;8961&quot; data-start=&quot;8951&quot;&gt;해제 후 사용&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;8972&quot; data-start=&quot;8961&quot;&gt;MEM30-C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;8996&quot; data-start=&quot;8973&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;8985&quot; data-start=&quot;8973&quot;&gt;널 포인터 역참조&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;8996&quot; data-start=&quot;8985&quot;&gt;EXP34-C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;9019&quot; data-start=&quot;8997&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;9008&quot; data-start=&quot;8997&quot;&gt;정수 연산 래핑&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;9019&quot; data-start=&quot;9008&quot;&gt;INT30-C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;9044&quot; data-start=&quot;9020&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;9033&quot; data-start=&quot;9020&quot;&gt;정수 변환 값 손실&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;9044&quot; data-start=&quot;9033&quot;&gt;INT31-C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;9065&quot; data-start=&quot;9045&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;9054&quot; data-start=&quot;9045&quot;&gt;포맷 스트링&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;9065&quot; data-start=&quot;9054&quot;&gt;FIO30-C&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9121&quot; data-start=&quot;9067&quot; data-ke-size=&quot;size16&quot;&gt;보고서나 코드 리뷰에서는 &amp;ldquo;위험해 보인다&amp;rdquo;라고만 적는 것보다 다음과 같이 작성하는 편이 정확하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;외부 입력의 길이를 확인하지 않고 고정 배열에 복사하여
버퍼 경계를 초과할 수 있다.

CERT C STR31-C 위반에 해당하며,
대상 배열의 널 종료 공간까지 포함한 최대 길이를 보장해야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9323&quot; data-start=&quot;9247&quot; data-ke-size=&quot;size16&quot;&gt;규칙 번호는 단순히 외우기 위한 번호가 아니라, 개발자들이 같은 문제를 짧고 정확하게 이야기하기 위한 공통 언어라는 점을 알 수 있었다.&lt;/p&gt;
&lt;h2 data-end=&quot;9344&quot; data-start=&quot;9325&quot; data-section-id=&quot;qs63qv&quot; data-ke-size=&quot;size26&quot;&gt;현대&amp;middot;기아차의 자체 코딩 표준&lt;/h2&gt;
&lt;p data-end=&quot;9411&quot; data-start=&quot;9346&quot; data-ke-size=&quot;size16&quot;&gt;국제 표준을 실제 자동차 기업에서 그대로 사용하기도 하지만, 기업의 개발 환경에 맞게 자체 표준으로 정리하기도 한다.&lt;/p&gt;
&lt;p data-end=&quot;9467&quot; data-start=&quot;9413&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 현대&amp;middot;기아차의 HKMC Secure C/C++ Coding Standard도 소개됐다.&lt;/p&gt;
&lt;p data-end=&quot;9510&quot; data-start=&quot;9469&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 앞에서 본 취약점들은 다음과 같이 HKMC 규칙으로도 연결된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;버퍼 오버플로우
C-ARR-001

Use-After-Free
C-MEM-001

널 포인터 역참조
C-EXP-009

정수 오버플로우
C-INT-002 / C-INT-005

포맷 스트링
C-FIO-001&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9695&quot; data-start=&quot;9641&quot; data-ke-size=&quot;size16&quot;&gt;기업이 별도의 규칙 번호를 사용하더라도 기본적인 구조는 CERT C와 MISRA의 영향을 받는다.&lt;/p&gt;
&lt;p data-end=&quot;9763&quot; data-start=&quot;9697&quot; data-ke-size=&quot;size16&quot;&gt;결국 중요한 것은 규칙 이름보다도 입력 경계, 메모리 수명, 정수 범위, 오류 처리를 일관된 방식으로 관리하는 것이다.&lt;/p&gt;
&lt;h2 data-end=&quot;9787&quot; data-start=&quot;9765&quot; data-section-id=&quot;xqrwdb&quot; data-ke-size=&quot;size26&quot;&gt;AUTOSAR C++14와 RAII&lt;/h2&gt;
&lt;p data-end=&quot;9848&quot; data-start=&quot;9789&quot; data-ke-size=&quot;size16&quot;&gt;C++에서는 메모리를 직접 할당하고 해제하기보다 객체의 수명에 자원 관리를 묶는 RAII 방식이 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;9923&quot; data-start=&quot;9850&quot; data-ke-size=&quot;size16&quot;&gt;다음처럼 직접 malloc()과 free()를 사용하면 중간에 예외나 조기 반환이 발생했을 때 메모리 해제를 놓칠 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;int *p = static_cast&amp;lt;int *&amp;gt;(std::malloc(sizeof(int)));
std::free(p);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10055&quot; data-start=&quot;10006&quot; data-ke-size=&quot;size16&quot;&gt;AUTOSAR C++14에서는 스마트 포인터와 표준 컨테이너를 사용하는 방향을 권장한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;auto value = std::make_unique&amp;lt;int&amp;gt;(42);
std::vector&amp;lt;int&amp;gt; values{1, 2, 3};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10213&quot; data-start=&quot;10143&quot; data-ke-size=&quot;size16&quot;&gt;객체가 범위를 벗어나면 메모리가 자동으로 해제되므로 사람이 모든 실행 경로에서 직접 delete를 호출할 필요가 줄어든다.&lt;/p&gt;
&lt;p data-end=&quot;10241&quot; data-start=&quot;10215&quot; data-ke-size=&quot;size16&quot;&gt;배열 할당과 해제 방식도 반드시 일치해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;int *a = new int[10];
delete a;        // 잘못된 방식

int *b = new int[10];
delete[] b;      // 형태는 맞음&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10436&quot; data-start=&quot;10354&quot; data-ke-size=&quot;size16&quot;&gt;다만 더 안전한 방향은 직접 new[]와 delete[]를 관리하기보다 std::array나 std::vector를 사용하는 것이다.&lt;/p&gt;
&lt;h2 data-end=&quot;10455&quot; data-start=&quot;10438&quot; data-section-id=&quot;1pmh4bo&quot; data-ke-size=&quot;size26&quot;&gt;실패 경로도 코드의 일부다&lt;/h2&gt;
&lt;p data-end=&quot;10509&quot; data-start=&quot;10457&quot; data-ke-size=&quot;size16&quot;&gt;함수가 실패할 수 있는데 반환값을 무시하면, 실패한 데이터를 정상 데이터처럼 사용할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;can_read(&amp;amp;msg);
use(&amp;amp;msg);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10595&quot; data-start=&quot;10550&quot; data-ke-size=&quot;size16&quot;&gt;can_read()가 실패했다면 msg는 사용할 수 없는 상태일 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;if (can_read(&amp;amp;msg) != CAN_OK) {
    return;
}

use(&amp;amp;msg);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10711&quot; data-start=&quot;10667&quot; data-ke-size=&quot;size16&quot;&gt;C++의 std::optional을 사용할 때도 값이 있는지 확인해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;std::optional&amp;lt;Frame&amp;gt; frame = rx.read();

if (!frame) {
    return Error::NoFrame;
}

process(frame-&amp;gt;id);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10875&quot; data-start=&quot;10830&quot; data-ke-size=&quot;size16&quot;&gt;오류 처리는 정상 흐름을 방해하는 부가적인 코드가 아니라 프로그램 설계의 일부다.&lt;/p&gt;
&lt;p data-end=&quot;10962&quot; data-start=&quot;10877&quot; data-ke-size=&quot;size16&quot;&gt;소멸자처럼 객체를 정리하는 과정에서는 예외가 밖으로 빠져나가지 않도록 해야 한다. 정리 중 또 다른 예외가 발생하면 프로그램이 종료될 수 있기 때문이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;~Logger() noexcept
{
    try {
        flush();
    } catch (...) {
        // 소멸자 밖으로 예외를 내보내지 않음
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11101&quot; data-start=&quot;11083&quot; data-ke-size=&quot;size16&quot;&gt;결국 중요한 질문은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이 오류를 누가 복구할 수 있는가?
복구할 수 없다면 안전하게 중단할 수 있는가?
실패 경로가 테스트되어 있는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;11212&quot; data-start=&quot;11180&quot; data-section-id=&quot;18bb5f2&quot; data-ke-size=&quot;size26&quot;&gt;Required, Advisory와 Deviation&lt;/h2&gt;
&lt;p data-end=&quot;11235&quot; data-start=&quot;11214&quot; data-ke-size=&quot;size16&quot;&gt;코딩 표준에는 규칙의 강도도 존재한다.&lt;/p&gt;
&lt;p data-end=&quot;11328&quot; data-start=&quot;11237&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Required&lt;/b&gt;나 &lt;b&gt;Mandatory&lt;/b&gt; 규칙은 원칙적으로 반드시 지켜야 한다.&lt;br /&gt;&lt;b&gt;Advisory&lt;/b&gt;는 품질과 안전을 위해 강하게 권고되는 규칙이다.&lt;/p&gt;
&lt;p data-end=&quot;11400&quot; data-start=&quot;11330&quot; data-ke-size=&quot;size16&quot;&gt;하지만 실제 산업 코드에서는 모든 규칙을 예외 없이 적용하기 어려운 경우도 있다. 이때 사용하는 개념이 Deviation이다.&lt;/p&gt;
&lt;p data-end=&quot;11432&quot; data-start=&quot;11402&quot; data-ke-size=&quot;size16&quot;&gt;Deviation은 규칙을 그냥 무시하는 것이 아니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;왜 규칙을 지키지 못하는가?
어떤 위험이 남는가?
대체 방어 방법은 무엇인가?
누가 이를 검토하고 승인했는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11527&quot; data-start=&quot;11509&quot; data-ke-size=&quot;size16&quot;&gt;이 내용을 문서로 남기는 절차다.&lt;/p&gt;
&lt;p data-end=&quot;11603&quot; data-start=&quot;11529&quot; data-ke-size=&quot;size16&quot;&gt;표준 준수의 목표는 무조건 위반 개수를 0으로 만드는 것만이 아니라, 남아 있는 위험을 알고 통제하고 있다는 사실을 증명하는 것이다.&lt;/p&gt;
&lt;h2 data-end=&quot;11620&quot; data-start=&quot;11605&quot; data-section-id=&quot;19wzxud&quot; data-ke-size=&quot;size26&quot;&gt;정적 분석과 동적 분석&lt;/h2&gt;
&lt;p data-end=&quot;11665&quot; data-start=&quot;11622&quot; data-ke-size=&quot;size16&quot;&gt;사람이 모든 코드 경로를 직접 확인하기는 어렵기 때문에 도구를 함께 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;11696&quot; data-start=&quot;11667&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 정적 분석과 동적 분석의 차이를 설명했다.&lt;/p&gt;
&lt;h3 data-end=&quot;11707&quot; data-start=&quot;11698&quot; data-section-id=&quot;hgt66j&quot; data-ke-size=&quot;size23&quot;&gt;정적 분석&lt;/h3&gt;
&lt;p data-end=&quot;11741&quot; data-start=&quot;11709&quot; data-ke-size=&quot;size16&quot;&gt;정적 분석은 프로그램을 실행하지 않고 소스코드를 분석한다.&lt;/p&gt;
&lt;p data-end=&quot;11794&quot; data-start=&quot;11743&quot; data-ke-size=&quot;size16&quot;&gt;도구는 함수 이름, AST, 데이터 흐름, 제어 흐름 등을 살펴보며 잠재적인 문제를 찾는다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;irpf90&quot;&gt;&lt;code&gt;찾을 수 있는 예
경계 밖 접근 가능성
널 포인터 역참조 가능성
미초기화 값
Use-After-Free
반환값 무시
MISRA/CERT 규칙 위반&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11962&quot; data-start=&quot;11891&quot; data-ke-size=&quot;size16&quot;&gt;장점은 프로그램을 실행하지 않아도 다양한 경로를 검사할 수 있다는 것이다. CI에 넣어 코드가 머지될 때마다 실행할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;12034&quot; data-start=&quot;11964&quot; data-ke-size=&quot;size16&quot;&gt;단점은 실제 실행값을 모르기 때문에 오탐이 발생할 수 있다는 점이다. 도구가 위험하다고 판단했지만 실제로는 안전할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;12082&quot; data-start=&quot;12036&quot; data-ke-size=&quot;size16&quot;&gt;하지만 오탐이라고 해서 그냥 무시해서는 안 된다. 왜 안전한지 근거를 남겨야 한다.&lt;/p&gt;
&lt;p data-end=&quot;12110&quot; data-start=&quot;12084&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 사용한 대표적인 도구는 다음과 같았다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;cppcheck
C/C++ 정적 분석

clang-tidy
LLVM 기반 린터와 정적 검사

flawfinder
strcpy, printf 같은 위험 함수 탐지

gcc -fanalyzer
GCC의 코드 흐름 분석&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;12254&quot; data-start=&quot;12245&quot; data-section-id=&quot;ezr7t3&quot; data-ke-size=&quot;size23&quot;&gt;동적 분석&lt;/h3&gt;
&lt;p data-end=&quot;12288&quot; data-start=&quot;12256&quot; data-ke-size=&quot;size16&quot;&gt;동적 분석은 프로그램을 실제로 실행하면서 오류를 감시한다.&lt;/p&gt;
&lt;p data-end=&quot;12345&quot; data-start=&quot;12290&quot; data-ke-size=&quot;size16&quot;&gt;대표적인 도구가 AddressSanitizer와 UndefinedBehaviorSanitizer다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;irpf90&quot;&gt;&lt;code&gt;ASan
버퍼 오버플로우
Use-After-Free
잘못된 메모리 접근

UBSan
정수 오버플로우
0으로 나누기
널 포인터 접근
잘못된 형변환&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;12499&quot; data-start=&quot;12441&quot; data-ke-size=&quot;size16&quot;&gt;동적 분석의 장점은 실제로 오류가 발생한 줄과 원인을 정확하게 보여 준다는 것이다. 오탐도 비교적 적다.&lt;/p&gt;
&lt;p data-end=&quot;12560&quot; data-start=&quot;12501&quot; data-ke-size=&quot;size16&quot;&gt;단점은 실행한 경로만 검사한다는 점이다. 테스트에서 실행되지 않은 코드 경로의 문제는 찾지 못할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;12597&quot; data-start=&quot;12562&quot; data-ke-size=&quot;size16&quot;&gt;따라서 둘 중 하나만 사용하는 것이 아니라 함께 사용해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;정적 분석
실행하지 않고 넓게 검사

동적 분석
실제로 실행된 경로를 정확하게 검사

사람 리뷰
도구가 이해하지 못하는 설계와 의도를 판단&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;12716&quot; data-start=&quot;12690&quot; data-section-id=&quot;1o1q431&quot; data-ke-size=&quot;size26&quot;&gt;하나의 도구로 모든 문제를 찾을 수는 없다&lt;/h2&gt;
&lt;p data-end=&quot;12749&quot; data-start=&quot;12718&quot; data-ke-size=&quot;size16&quot;&gt;강의 실습에서는 같은 취약 코드에 여러 도구를 실행했다.&lt;/p&gt;
&lt;p data-end=&quot;12870&quot; data-start=&quot;12751&quot; data-ke-size=&quot;size16&quot;&gt;위험 함수 이름을 찾는 flawfinder는 strcpy()나 위험한 printf() 사용은 잘 찾지만, 포인터의 수명을 추적해야 하는 Use-After-Free나 널 포인터 문제는 잡지 못할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;12947&quot; data-start=&quot;12872&quot; data-ke-size=&quot;size16&quot;&gt;cppcheck와 clang-tidy는 코드 흐름을 더 깊게 분석할 수 있지만, 모든 정수 오버플로우를 완벽하게 찾지는 못한다.&lt;/p&gt;
&lt;p data-end=&quot;12969&quot; data-start=&quot;12949&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다음과 같은 흐름을 사용한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;컴파일러 경고
&amp;rarr; 정적 분석
&amp;rarr; Sanitizer
&amp;rarr; 단위 테스트
&amp;rarr; 사람 코드 리뷰
&amp;rarr; 수정 후 재검사&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;13084&quot; data-start=&quot;13043&quot; data-ke-size=&quot;size16&quot;&gt;도구별로 잡는 결함이 다르기 때문에 여러 단계를 통과시키는 것이 중요하다.&lt;/p&gt;
&lt;h2 data-end=&quot;13101&quot; data-start=&quot;13086&quot; data-section-id=&quot;ejvbg5&quot; data-ke-size=&quot;size26&quot;&gt;수정했다는 증거 남기기&lt;/h2&gt;
&lt;p data-end=&quot;13141&quot; data-start=&quot;13103&quot; data-ke-size=&quot;size16&quot;&gt;취약점을 발견하고 코드를 수정했다고 말하는 것만으로는 충분하지 않다.&lt;/p&gt;
&lt;p data-end=&quot;13212&quot; data-start=&quot;13143&quot; data-ke-size=&quot;size16&quot;&gt;수정 전 코드에서 도구가 문제를 탐지하고, 수정 후 같은 도구를 실행했을 때 더 이상 문제가 나오지 않는지를 확인해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;13239&quot; data-start=&quot;13214&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 실습 과정을 다음과 같이 정리했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;취약 코드 확인
&amp;rarr; 정적 분석 실행
&amp;rarr; Sanitizer로 실제 오류 관찰
&amp;rarr; 표준 규칙에 매핑
&amp;rarr; 코드 수정
&amp;rarr; 같은 테스트와 분석을 다시 실행&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;13360&quot; data-start=&quot;13336&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 변경을 할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;취약 코드보완 방향
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;13605&quot; data-start=&quot;13362&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;13605&quot; data-start=&quot;13390&quot;&gt;
&lt;tr data-end=&quot;13426&quot; data-start=&quot;13390&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13412&quot; data-start=&quot;13390&quot;&gt;strcpy(id, input)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13426&quot; data-start=&quot;13412&quot;&gt;크기를 제한한 복사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;13482&quot; data-start=&quot;13427&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13451&quot; data-start=&quot;13427&quot;&gt;free(token) 후 다시 사용&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13482&quot; data-start=&quot;13451&quot;&gt;해제 후 포인터를 NULL로 변경하고 재사용 금지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;13517&quot; data-start=&quot;13483&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13501&quot; data-start=&quot;13483&quot;&gt;NULL 포인터 바로 역참조&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13517&quot; data-start=&quot;13501&quot;&gt;사용 전 NULL 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;13555&quot; data-start=&quot;13518&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13534&quot; data-start=&quot;13518&quot;&gt;작은 타입에서 정수 계산&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13555&quot; data-start=&quot;13534&quot;&gt;더 넓은 타입과 범위 검사 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;13605&quot; data-start=&quot;13556&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13577&quot; data-start=&quot;13556&quot;&gt;printf(user_msg)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;13605&quot; data-start=&quot;13577&quot;&gt;printf(&quot;%s&quot;, user_msg)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;13693&quot; data-start=&quot;13607&quot; data-ke-size=&quot;size16&quot;&gt;그리고 한 번 고친 문제는 재발 방지 테스트로 남겨야 한다. 이후 코드가 변경되더라도 같은 취약점이 다시 생기지 않는지 자동으로 확인할 수 있기 때문이다.&lt;/p&gt;
&lt;h2 data-end=&quot;13713&quot; data-start=&quot;13695&quot; data-section-id=&quot;1waov4d&quot; data-ke-size=&quot;size26&quot;&gt;코드 리뷰 보고서 작성 방식&lt;/h2&gt;
&lt;p data-end=&quot;13765&quot; data-start=&quot;13715&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의를 통해 취약 코드를 분석할 때 다음 구조로 작성하면 된다는 것을 알 수 있었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. 취약 코드
어떤 코드에서 문제가 발생하는지 제시

2. 위험
버퍼 경계 초과, 크래시, 정보 유출 등 영향 설명

3. 원인
길이 검사 누락, 포인터 수명 오류, 정수 범위 오류 등

4. 표준 매핑
MISRA, AUTOSAR, CERT C, HKMC 규칙 연결

5. 수정 방향
안전한 코드와 설계 방식 제시

6. 검증 증거
정적 분석, Sanitizer, 단위 테스트 결과 기록&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;14030&quot; data-start=&quot;13998&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 버퍼 오버플로우는 다음과 같이 정리할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;원인:
외부 입력 길이를 검사하지 않고 고정 길이 배열에 복사함.

위험:
배열 밖의 메모리를 덮어써 인접 변수 또는 반환 주소가 손상될 수 있음.

표준:
CERT C STR31-C, MISRA Rule 18.1 등과 연결됨.

수정:
입력 길이를 검사하고 대상 버퍼 크기를 기준으로 제한하여 복사함.

검증:
경계값 테스트와 ASan을 실행하고 수정 전후 결과를 비교함.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;14304&quot; data-start=&quot;14255&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 작성하면 단순한 코드 설명이 아니라, 실제 산업 코드 리뷰와 비슷한 형태가 된다.&lt;/p&gt;
&lt;h2 data-end=&quot;14323&quot; data-start=&quot;14306&quot; data-section-id=&quot;1r4fs84&quot; data-ke-size=&quot;size26&quot;&gt;이번 강의에서 기억할 핵심&lt;/h2&gt;
&lt;p data-end=&quot;14353&quot; data-start=&quot;14325&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의의 내용은 다음과 같이 정리할 수 있었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;시큐어 코딩은 위험한 코드를 공통 규칙으로 설명하는 과정이다.

많은 취약점은 입력 경계와 메모리 수명에서 시작한다.

MISRA와 AUTOSAR는 안전한 작성 방법을 정하고,
CERT C는 취약 코드 패턴을 설명한다.

ISO 26262와 ISO/SAE 21434는
위험 관리와 검증 근거를 요구한다.

정적 분석, 동적 분석, 테스트와 사람 리뷰를 함께 사용해야 한다.

취약점 수정은 코드 변경에서 끝나는 것이 아니라,
수정 근거와 재검사 결과까지 남겨야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;14636&quot; data-start=&quot;14630&quot; data-section-id=&quot;1h9nj85&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-end=&quot;14694&quot; data-start=&quot;14638&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의를 듣기 전에는 코딩 표준을 단순히 회사에서 정해 놓은 까다로운 문법 규칙 정도로 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;14840&quot; data-start=&quot;14696&quot; data-ke-size=&quot;size16&quot;&gt;하지만 자동차나 임베디드 환경에서는 작은 포인터 실수나 정수 변환 하나가 ECU 중단이나 차량 기능 오작동으로 이어질 수 있다. 이런 환경에서 코딩 표준은 개발자를 불편하게 만들기 위한 문서가 아니라, 과거에 반복됐던 사고를 줄이기 위한 공통 약속에 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;14864&quot; data-start=&quot;14842&quot; data-ke-size=&quot;size16&quot;&gt;특히 기억에 남은 것은 다음 문장이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;시큐어 코딩의 목표는
취약한 코드를 보고 &amp;ldquo;위험하다&amp;rdquo;고 말하는 데서 끝나지 않는다.

왜 위험한지 설명하고,
어떤 규칙을 위반했는지 연결하고,
수정한 뒤 안전해졌다는 증거를 남기는 것까지가 한 과정이다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;15110&quot; data-start=&quot;14993&quot; data-ke-size=&quot;size16&quot;&gt;결국 안전한 코드는 특별한 기술 하나로 만들어지는 것이 아니라, 입력 크기를 확인하고, 포인터 수명을 관리하고, 반환값을 검사하고, 위험한 함수 사용을 제한하는 기본적인 습관에서 시작된다는 점을 알 수 있었다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>하계 보안 세미나</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/7</guid>
      <comments>https://song-song.tistory.com/7#entry7comment</comments>
      <pubDate>Fri, 10 Jul 2026 15:36:09 +0900</pubDate>
    </item>
    <item>
      <title>하계 보안 세미나 4일차 - 자동차 보안 이해</title>
      <link>https://song-song.tistory.com/6</link>
      <description>&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-6a3a1513-0ef8-83e8-a772-7f568a0759a7-2&quot;&gt;
&lt;div data-conversation-screenshot-content=&quot;&quot;&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-5-thinking&quot; data-turn-start-message=&quot;true&quot; data-message-id=&quot;636434d4-69c5-472b-be1b-0f69a8282924&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;p data-end=&quot;403&quot; data-start=&quot;256&quot; data-ke-size=&quot;size16&quot;&gt;1~3일차에서는 암호나 PQC처럼 비교적 수학적인 내용이 많았다면, 이번 강의는 실제 자동차 안에 들어가는 ECU, CAN, 인포테인먼트, 키 포브, 충전기, 모바일 API 같은 현실적인 공격면을 중심으로 진행됐다.&lt;/p&gt;
&lt;p data-end=&quot;531&quot; data-start=&quot;405&quot; data-ke-size=&quot;size16&quot;&gt;강의를 듣고 보니 자동차는 그냥 이동수단이 아니라 &lt;b&gt;수많은 컴퓨터와 네트워크가 붙어 있는 하나의 거대한 임베디드 시스템&lt;/b&gt;에 가까웠다.&lt;/p&gt;
&lt;p data-end=&quot;698&quot; data-start=&quot;533&quot; data-ke-size=&quot;size16&quot;&gt;자동차 안에는 여러 ECU가 있고, ECU끼리는 CAN, LIN, Ethernet 같은 내부 네트워크로 연결된다. 여기에 인포테인먼트, 블루투스, 모바일 앱, 텔레매틱스, EV 충전기까지 연결되면서 공격면이 점점 넓어지고 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;717&quot; data-start=&quot;700&quot; data-section-id=&quot;fz45wd&quot; data-ke-size=&quot;size26&quot;&gt;자동차 보안에서 중요한 점&lt;/h2&gt;
&lt;p data-end=&quot;781&quot; data-start=&quot;719&quot; data-ke-size=&quot;size16&quot;&gt;자동차 보안이 일반 IT 보안과 다른 점은, 공격 결과가 단순한 데이터 유출에서 끝나지 않을 수 있다는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;887&quot; data-start=&quot;783&quot; data-ke-size=&quot;size16&quot;&gt;웹 서비스가 뚫리면 계정 정보나 데이터가 유출될 수 있다. 물론 이것도 심각하지만, 자동차에서는 공격이 차량 제어, 운전자 혼란, 안전 기능 오작동 같은 물리적인 문제로 이어질 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1179&quot; data-start=&quot;889&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 인포테인먼트 시스템이 공격당하면 단순히 음악이 꺼지는 정도가 아니라, 차량 내부 네트워크로 연결된 CAN 메시지를 조작하거나 운전자에게 잘못된 정보를 보여줄 수도 있다. 강의에서도 기아 Gen5 Head Unit 취약점 사례를 통해, 공격자가 M-CAN 버스로 전송되는 CAN 프레임을 생성하는 명령을 삽입할 수 있고, 이로 인해 잘못된 속도나 경고 메시지 표시, 멀티미디어 기능 조작, 시스템 재부팅 같은 문제가 생길 수 있다고 설명했다.&lt;/p&gt;
&lt;p data-end=&quot;1214&quot; data-start=&quot;1181&quot; data-ke-size=&quot;size16&quot;&gt;즉 자동차 보안은 정보 보안이면서 동시에 안전과도 연결된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;일반 IT 보안:
정보 유출, 계정 탈취, 서비스 중단

자동차 보안:
정보 유출 + 차량 기능 조작 + 운전자 안전 문제&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;1326&quot; data-start=&quot;1298&quot; data-section-id=&quot;1bmpllk&quot; data-ke-size=&quot;size26&quot;&gt;Tesla VCSEC 취약점: 정수 오버플로우&lt;/h2&gt;
&lt;p data-end=&quot;1388&quot; data-start=&quot;1328&quot; data-ke-size=&quot;size16&quot;&gt;강의 초반에는 Tesla Model 3의 VCSEC 모듈에서 발견된 CVE-2025-2082 사례가 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;1605&quot; data-start=&quot;1390&quot; data-ke-size=&quot;size16&quot;&gt;이 취약점은 &lt;b&gt;정수 오버플로우(Integer Overflow)&lt;/b&gt;와 관련되어 있었다. 정수 오버플로우는 컴퓨터가 처리할 수 있는 정수 범위를 넘어서는 값을 계산하거나 저장하려고 할 때 생기는 문제다. 단순한 계산 오류처럼 보이지만, 실제로는 잘못된 메모리 주소 계산이나 잘못된 버퍼 크기 할당으로 이어질 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1737&quot; data-start=&quot;1607&quot; data-ke-size=&quot;size16&quot;&gt;이 사례에서는 TPMS, 즉 타이어 공기압 모니터링 시스템에서 전송되는 인증서 응답을 조작하여 특정 조건에서 정수 오버플로우를 유발할 수 있었다고 한다. 성공하면 원격 코드 실행까지 가능할 수 있었기 때문에 위험도가 높게 평가되었다.&lt;/p&gt;
&lt;p data-end=&quot;1856&quot; data-start=&quot;1739&quot; data-ke-size=&quot;size16&quot;&gt;다만 이 공격은 아무 곳에서나 인터넷으로 바로 되는 형태가 아니라, 공격자가 차량 근처의 무선 통신 범위 같은 인접 네트워크 환경에 있어야 하는 것으로 설명됐다. 그래서 위험하지만 공격 조건도 같이 봐야 한다.&lt;/p&gt;
&lt;p data-end=&quot;1917&quot; data-start=&quot;1858&quot; data-ke-size=&quot;size16&quot;&gt;이 사례를 보면서 느낀 점은, 차량 보안 취약점도 결국 기본적인 소프트웨어 취약점과 이어져 있다는 것이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;정수 오버플로우
&amp;rarr; 잘못된 크기 계산
&amp;rarr; 메모리 처리 오류
&amp;rarr; 코드 실행 가능성&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2033&quot; data-start=&quot;1977&quot; data-ke-size=&quot;size16&quot;&gt;자동차라고 해서 완전히 다른 보안 세계가 아니라, 메모리 취약점과 입력 검증 문제가 그대로 등장한다.&lt;/p&gt;
&lt;h2 data-end=&quot;2058&quot; data-start=&quot;2035&quot; data-section-id=&quot;1n4s2ek&quot; data-ke-size=&quot;size26&quot;&gt;EV 충전기 취약점: 버퍼 오버플로우&lt;/h2&gt;
&lt;p data-end=&quot;2138&quot; data-start=&quot;2060&quot; data-ke-size=&quot;size16&quot;&gt;다음으로는 Autel MaxiCharger AC Elite Business C50 충전소 취약점인 CVE-2024-23957 사례가 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;2319&quot; data-start=&quot;2140&quot; data-ke-size=&quot;size16&quot;&gt;이 취약점은 DLB, 즉 Dynamic Load Balancing 프로토콜 구현에서 발생했다. 강의에서는 AES 키를 파싱하는 과정에서 사용자 입력 데이터의 길이를 제대로 검증하지 않고 고정 길이의 스택 기반 버퍼에 복사하면서 문제가 생겼다고 설명했다.&lt;/p&gt;
&lt;p data-end=&quot;2387&quot; data-start=&quot;2321&quot; data-ke-size=&quot;size16&quot;&gt;이런 경우 공격자는 버퍼 경계를 넘어 데이터를 덮어쓸 수 있고, 성공하면 충전소 장치에서 임의 코드를 실행할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2514&quot; data-start=&quot;2389&quot; data-ke-size=&quot;size16&quot;&gt;여기서 중요한 점은 공격 대상이 차량 자체가 아니라 &lt;b&gt;EV 충전기&lt;/b&gt;라는 것이다. 자동차 보안이라고 하면 차량 내부만 생각하기 쉽지만, 전기차 환경에서는 충전기, 충전 네트워크, 차량과 충전기 사이의 통신도 공격면이 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;차량 보안 공격면:
차량 내부 ECU
인포테인먼트
모바일 앱
블루투스
키 포브
OBD 포트
EV 충전기
텔레매틱스&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2767&quot; data-start=&quot;2593&quot; data-ke-size=&quot;size16&quot;&gt;강의 후반의 최신 취약점 동향에서도 Pwn2Own Automotive의 주요 타깃이 EV 충전기와 IVI, 즉 인포테인먼트 쪽으로 확장되고 있다고 설명했다. 최근 자동차 공격면은 차량 내부 ECU만이 아니라 차량 주변 생태계까지 넓어지고 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;2786&quot; data-start=&quot;2769&quot; data-section-id=&quot;qwltlz&quot; data-ke-size=&quot;size26&quot;&gt;Kia 인포테인먼트 취약점&lt;/h2&gt;
&lt;p data-end=&quot;2831&quot; data-start=&quot;2788&quot; data-ke-size=&quot;size16&quot;&gt;기아 Gen5 Head Unit 관련 CVE-2020-8539 사례도 다뤘다.&lt;/p&gt;
&lt;p data-end=&quot;2976&quot; data-start=&quot;2833&quot; data-ke-size=&quot;size16&quot;&gt;Head Unit은 쉽게 말하면 차량 안의 인포테인먼트 시스템이다. 내비게이션, 오디오, 화면 표시, 스마트폰 연결 같은 기능을 담당한다. 겉으로는 편의 기능처럼 보이지만, 차량 내부 네트워크와 이어질 수 있기 때문에 보안 관점에서는 중요한 공격면이 된다.&lt;/p&gt;
&lt;p data-end=&quot;3137&quot; data-start=&quot;2978&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 공격자가 micomd 실행 데몬을 통해 허가되지 않은 명령 삽입과 기능 작동을 허용할 수 있었다고 설명했다. micomd는 마이크로컨트롤러 관련 장치를 관리하고 제어하는 백그라운드 프로세스라고 볼 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;3293&quot; data-start=&quot;3139&quot; data-ke-size=&quot;size16&quot;&gt;이 사례에서 중요한 점은 인포테인먼트가 단순한 화면 장치가 아니라, 내부 CAN 버스와 연결될 수 있다는 점이다. 공격자가 M-CAN 버스로 CAN 프레임을 생성하는 명령을 삽입할 수 있다면, 해당 버스에 연결된 장치들이 오작동하거나 운전자에게 잘못된 정보를 표시할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;3390&quot; data-start=&quot;3295&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 &amp;ldquo;인포테인먼트가 해킹되어도 음악이나 내비만 문제 생기는 거 아닌가?&amp;rdquo;라고 생각할 수 있는데, 차량 내부 네트워크와 연결되어 있으면 영향 범위가 더 커질 수 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;3412&quot; data-start=&quot;3392&quot; data-section-id=&quot;q7t90w&quot; data-ke-size=&quot;size26&quot;&gt;Kia 딜러/포털 API 취약점&lt;/h2&gt;
&lt;p data-end=&quot;3471&quot; data-start=&quot;3414&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의에서 가장 현실적으로 무섭게 느껴졌던 부분은 Kia 딜러/포털 및 모바일 API 취약점이었다.&lt;/p&gt;
&lt;p data-end=&quot;3675&quot; data-start=&quot;3473&quot; data-ke-size=&quot;size16&quot;&gt;이 취약점은 차량 내부 펌웨어나 CAN 메시지를 직접 건드리는 것이 아니라, &lt;b&gt;딜러/관리 포털 API의 인증 및 권한 논리 결함&lt;/b&gt;과 관련된 사례였다. 공격자는 차량 번호판 같은 단순 식별자를 이용해 VIN을 확보하고, 딜러 권한을 악용해 차량 제어 권한을 탈취할 수 있었던 것으로 설명됐다.&lt;/p&gt;
&lt;p data-end=&quot;3704&quot; data-start=&quot;3677&quot; data-ke-size=&quot;size16&quot;&gt;기술적 원인은 크게 네 가지로 정리할 수 있었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;과도한 딜러 권한
권한 경계 오류
취약한 식별자 사용
약한 계정 생성 절차&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3881&quot; data-start=&quot;3761&quot; data-ke-size=&quot;size16&quot;&gt;여기서 핵심은 &amp;ldquo;딜러 계정인지 아닌지만 보고, 그 딜러가 실제로 해당 차량을 관리할 권한이 있는지 엄격하게 확인하지 않았다&amp;rdquo;는 점이었다. 즉, 인증은 된 것처럼 보여도 권한 검사가 제대로 되지 않으면 문제가 생긴다.&lt;/p&gt;
&lt;p data-end=&quot;3983&quot; data-start=&quot;3883&quot; data-ke-size=&quot;size16&quot;&gt;이건 웹 보안에서 자주 나오는 IDOR나 권한 검증 오류와도 비슷하게 느껴졌다. 차량 보안이라고 해도 결국 서버 API와 권한 모델이 약하면 차량 원격 기능까지 위험해질 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;차량 번호판
&amp;rarr; VIN 등 차량 식별 정보
&amp;rarr; 딜러 권한 악용
&amp;rarr; 소유자 연결 조작
&amp;rarr; 원격 제어 기능 악용 가능&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4135&quot; data-start=&quot;4062&quot; data-ke-size=&quot;size16&quot;&gt;이 사례를 보면서 자동차 보안은 차량 내부만 보는 것이 아니라, 모바일 앱과 클라우드 API까지 같이 봐야 한다는 점이 확실해졌다.&lt;/p&gt;
&lt;h2 data-end=&quot;4151&quot; data-start=&quot;4137&quot; data-section-id=&quot;1v6ver0&quot; data-ke-size=&quot;size26&quot;&gt;키 포브와 롤링 코드&lt;/h2&gt;
&lt;p data-end=&quot;4293&quot; data-start=&quot;4153&quot; data-ke-size=&quot;size16&quot;&gt;키 포브(Key Fob)는 차량 문을 잠그거나 열고, 시동을 걸거나 트렁크를 여는 데 사용하는 무선 리모컨이다. 버튼을 누르면 RF 신호를 차량의 RKE 수신 장치로 보내는 방식이다.&lt;/p&gt;
&lt;p data-end=&quot;4417&quot; data-start=&quot;4295&quot; data-ke-size=&quot;size16&quot;&gt;만약 키 포브가 항상 같은 코드를 보낸다면, 공격자는 그 신호를 한 번 가로챈 뒤 나중에 그대로 재전송해서 차량 문을 열 수 있다. 이런 공격을 막기 위해 사용하는 방식이 &lt;b&gt;롤링 코드(Rolling Code)&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;4510&quot; data-start=&quot;4419&quot; data-ke-size=&quot;size16&quot;&gt;롤링 코드는 매번 다른 코드를 사용한다. 키 포브와 차량은 같은 알고리즘과 카운터를 가지고 있고, 버튼을 누를 때마다 카운터가 증가하면서 새로운 코드가 만들어진다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;고정 코드:
항상 같은 코드 전송
&amp;rarr; 한 번 가로채면 재사용 가능

롤링 코드:
매번 다른 코드 전송
&amp;rarr; 이전 코드는 다시 보내도 무시됨&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4832&quot; data-start=&quot;4602&quot; data-ke-size=&quot;size16&quot;&gt;그런데 CVE-2022-37418과 관련된 롤백 공격은 이 롤링 코드의 재동기화 메커니즘을 악용한다. 공격자는 차량 소유자가 키 포브를 누르는 순간 신호를 가로채고 동시에 방해해서, 소유자가 다시 버튼을 누르게 만든다. 이 과정에서 연속된 유효 신호를 확보하고, 재동기화 로직을 악용해 차량의 카운터를 과거 값으로 되돌릴 수 있다는 흐름이었다.&lt;/p&gt;
&lt;p data-end=&quot;4922&quot; data-start=&quot;4834&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 롤링 코드가 있으면 재사용 공격이 불가능하다고 생각했는데, 구현된 재동기화 규칙에 논리적 결함이 있으면 다시 문제가 생길 수 있다는 점이 흥미로웠다.&lt;/p&gt;
&lt;h2 data-end=&quot;4936&quot; data-start=&quot;4924&quot; data-section-id=&quot;1n2h90d&quot; data-ke-size=&quot;size26&quot;&gt;ECU란 무엇인가&lt;/h2&gt;
&lt;p data-end=&quot;4968&quot; data-start=&quot;4938&quot; data-ke-size=&quot;size16&quot;&gt;자동차 내부 구조를 이해하려면 ECU부터 잡아야 한다.&lt;/p&gt;
&lt;p data-end=&quot;5165&quot; data-start=&quot;4970&quot; data-ke-size=&quot;size16&quot;&gt;ECU는 Electronic Control Unit, 전자제어장치다. 자동차 안에서 조향, 제동, 엔진, 좌석, 창문, 정보 표시 등 특정 기능을 제어하는 작은 컴퓨터라고 보면 된다. 차량에는 기능별로 여러 ECU가 들어가고, 이 ECU들이 내부 네트워크를 통해 서로 통신한다.&lt;/p&gt;
&lt;p data-end=&quot;5245&quot; data-start=&quot;5167&quot; data-ke-size=&quot;size16&quot;&gt;보안 관점에서 ECU는 중요한 자산이다. 전원 입력, 네트워크 버스 라인, 센서 입력, 액추에이터 출력 등이 모두 공격 표면이 될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;5340&quot; data-start=&quot;5247&quot; data-ke-size=&quot;size16&quot;&gt;ECU 내부에는 PCB, 저항, 커패시터, 다이오드, 릴레이, 솔레노이드, 전원 관리 칩, 네트워크 트랜시버, 메모리 칩, MCU나 SoC 같은 제어 장치가 들어간다.&lt;/p&gt;
&lt;p data-end=&quot;5518&quot; data-start=&quot;5342&quot; data-ke-size=&quot;size16&quot;&gt;특히 MCU 기반 ECU에서는 메모리와 디버그 인터페이스가 중요하다. ECU 제어 소프트웨어와 캘리브레이션 데이터가 MCU 메모리에 들어 있고, 공격자는 온칩 디버그 기능이나 시리얼 플래시 프로그래밍 인터페이스를 악용해 접근을 시도할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;ECU = 차량 안의 작은 제어 컴퓨터
MCU = ECU 안에서 실제 제어를 담당하는 핵심 칩
CAN/LIN/Ethernet = ECU들이 서로 말하는 통신망&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;5640&quot; data-start=&quot;5622&quot; data-section-id=&quot;1fe0yrk&quot; data-ke-size=&quot;size26&quot;&gt;차량 내부 네트워크와 CAN&lt;/h2&gt;
&lt;p data-end=&quot;5713&quot; data-start=&quot;5642&quot; data-ke-size=&quot;size16&quot;&gt;차량 안의 ECU들은 혼자 동작하지 않는다. 서로 데이터를 주고받아야 한다. 이때 사용하는 대표적인 내부 네트워크가 CAN이다.&lt;/p&gt;
&lt;p data-end=&quot;5877&quot; data-start=&quot;5715&quot; data-ke-size=&quot;size16&quot;&gt;CAN 메시지는 대략 CAN ID, DLC, Data Field, CRC 같은 요소로 구성된다. CAN ID는 메시지 식별자이고, DLC는 데이터 길이, Data Field는 실제 데이터, CRC는 오류 탐지용 값이다.&lt;/p&gt;
&lt;p data-end=&quot;6034&quot; data-start=&quot;5879&quot; data-ke-size=&quot;size16&quot;&gt;CAN은 차량 제어에 오래 사용된 중요한 프로토콜이지만, 보안 관점에서는 약점도 있다. 내부 네트워크에 일단 접근하면 정상 ECU처럼 메시지를 보내는 공격이 가능할 수 있기 때문이다. 특히 OBD 포트나 취약한 게이트웨이를 통해 내부 네트워크로 들어갈 수 있다면 문제가 커진다.&lt;/p&gt;
&lt;p data-end=&quot;6065&quot; data-start=&quot;6036&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 여러 차량 통신 프로토콜도 함께 비교했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;CAN:
엔진, 변속기, 섀시 제어, 진단에 사용

LIN:
좌석, 창문 같은 저가 센서/액추에이터에 사용

FlexRay:
ABS, ESC, ADAS 등 안전 핵심 기능 일부에 사용

Automotive Ethernet:
ADAS, 인포테인먼트, 고속 센서 데이터에 사용

UART/I&amp;sup2;C:
디버그나 칩 내부/근거리 센서 통신에 사용

GMSL:
카메라, 디스플레이, 오디오 같은 대용량 멀티미디어 전송에 사용&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6511&quot; data-start=&quot;6311&quot; data-ke-size=&quot;size16&quot;&gt;각 프로토콜마다 속도와 용도가 다르기 때문에, 공격면도 다르게 봐야 한다. 예를 들어 CAN은 OBD 악용이나 DoS 공격, Automotive Ethernet은 외부 공격 경유지와 실시간성 붕괴, GMSL은 카메라나 영상 신호 변조로 인한 ADAS 오작동이 보안 포인트가 될 수 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;6545&quot; data-start=&quot;6513&quot; data-section-id=&quot;jem9yp&quot; data-ke-size=&quot;size26&quot;&gt;OBD 포트는 정비용이지만 공격 진입점도 될 수 있다&lt;/h2&gt;
&lt;p data-end=&quot;6622&quot; data-start=&quot;6547&quot; data-ke-size=&quot;size16&quot;&gt;OBD 포트는 원래 차량 진단과 정비를 위해 만들어진 표준 기능이다. 정비소에서 차량 상태를 확인하거나 오류 코드를 읽을 때 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;6825&quot; data-start=&quot;6624&quot; data-ke-size=&quot;size16&quot;&gt;하지만 보안 관점에서는 내부 네트워크에 접근할 수 있는 물리적 진입점이 될 수 있다. 강의에서는 OBD 포트를 통해 공격자가 차량 내부 네트워크에 무단 접근하고, 게이트웨이에 보안 필터가 부족하거나 네트워크 세분화가 약하면 안전하지 않은 메시지를 내부 ECU에 전달할 수 있다고 설명했다.&lt;/p&gt;
&lt;p data-end=&quot;6907&quot; data-start=&quot;6827&quot; data-ke-size=&quot;size16&quot;&gt;즉 OBD 포트 자체가 나쁜 것은 아니다. 문제는 OBD 포트로 들어온 메시지를 어디까지 허용할 것인지, 게이트웨이가 얼마나 잘 필터링하는지다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;OBD 포트의 원래 목적:
진단, 정비, 배출가스 관련 상태 확인

보안상 위험:
내부 네트워크 접근 경로
진단 명령 악용
게이트웨이 필터 부족 시 제어 메시지 전달 가능&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;7036&quot; data-start=&quot;7018&quot; data-section-id=&quot;1lrxzv6&quot; data-ke-size=&quot;size26&quot;&gt;차량 E/E 아키텍처의 변화&lt;/h2&gt;
&lt;p data-end=&quot;7151&quot; data-start=&quot;7038&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 차량 E/E 아키텍처의 변화도 다뤘다. 예전에는 기능별로 ECU가 많이 흩어져 있는 분산 구조가 일반적이었다. 그런데 차량 기능이 복잡해지면서 ECU 수가 많아지고, 배선과 관리가 어려워졌다.&lt;/p&gt;
&lt;p data-end=&quot;7188&quot; data-start=&quot;7153&quot; data-ke-size=&quot;size16&quot;&gt;그래서 점점 도메인 집중형 구조와 존 아키텍처로 발전하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;7363&quot; data-start=&quot;7190&quot; data-ke-size=&quot;size16&quot;&gt;도메인 집중형 구조는 기능별 ECU들을 도메인 전용 ECU로 통합하는 방식이다. 예를 들어 파워트레인 도메인, 섀시 도메인처럼 기능별로 묶는다. 관리 효율이 좋아지고 비용을 줄일 수 있지만, 도메인 ECU가 공격당하면 영향 범위도 커진다.&lt;/p&gt;
&lt;p data-end=&quot;7574&quot; data-start=&quot;7365&quot; data-ke-size=&quot;size16&quot;&gt;존 아키텍처는 차량을 물리적인 구역, 즉 zone 단위로 나누고 각 Zone ECU가 주변 센서와 액추에이터를 모아 상위 Vehicle Computer와 연결하는 방식이다. 배선을 단순화하고 고성능 컴퓨팅을 집중시킬 수 있지만, Zone ECU와 Vehicle Computer가 핵심 공격 표면이 된다.&lt;/p&gt;
&lt;p data-end=&quot;7770&quot; data-start=&quot;7576&quot; data-ke-size=&quot;size16&quot;&gt;또 DCU, 즉 Domain Control Unit도 나왔다. DCU는 여러 소규모 ECU를 통합한 고성능 ECU로, SDV의 핵심 구성요소다. 하나의 플랫폼에서 여러 애플리케이션이 함께 실행될 수 있으므로 메모리와 자원 분리, 스케줄링 간섭 방지 같은 보안 설계가 중요하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;분산형 ECU:
기능별 ECU가 많음

도메인 집중형:
기능별 도메인 ECU로 통합

존 아키텍처:
차량을 물리적 구역으로 나누어 Zone ECU가 담당

SDV / DCU:
소프트웨어 업데이트로 기능을 활성화하거나 변경&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7987&quot; data-start=&quot;7909&quot; data-ke-size=&quot;size16&quot;&gt;자동차가 점점 소프트웨어 정의 차량으로 바뀌면서, 보안도 단순한 ECU 보호에서 플랫폼 보안과 네트워크 보안으로 확장되고 있다는 느낌이었다.&lt;/p&gt;
&lt;h2 data-end=&quot;8007&quot; data-start=&quot;7989&quot; data-section-id=&quot;ctz6ch&quot; data-ke-size=&quot;size26&quot;&gt;블루투스와 외부 연결 공격면&lt;/h2&gt;
&lt;p data-end=&quot;8121&quot; data-start=&quot;8009&quot; data-ke-size=&quot;size16&quot;&gt;요즘 차량은 스마트폰과 연결되는 기능이 많다. 핸즈프리 통화, 음악 재생, 앱 연동, 차량 초기 설정 등에서 블루투스가 사용된다. 일부 사용자는 OBD-II와 연결되는 블루투스 동글을 사용하기도 한다.&lt;/p&gt;
&lt;p data-end=&quot;8295&quot; data-start=&quot;8123&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 차량 환경에서 볼 수 있는 블루투스 위협도 정리했다. Car Whisperer, Bluesnarfing, Bluebugging, Bluejacking, BlueBorne, KNOB, BlueFrag 같은 공격 기법이 소개됐다.&lt;/p&gt;
&lt;p data-end=&quot;8322&quot; data-start=&quot;8297&quot; data-ke-size=&quot;size16&quot;&gt;이름은 많지만 핵심은 하나로 정리할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;무선 연결은 편리하지만,
차량 바깥에서 접근 가능한 공격면이 된다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8495&quot; data-start=&quot;8375&quot; data-ke-size=&quot;size16&quot;&gt;특히 블루투스는 사용자가 가까운 거리에서 편하게 연결하기 위해 만든 기능이다. 그런데 보안이 약하면 공격자도 가까운 거리에서 접근할 수 있다. 자동차 보안에서는 이런 외부 연결 지점을 하나하나 공격면으로 봐야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;8513&quot; data-start=&quot;8497&quot; data-section-id=&quot;bp3m3l&quot; data-ke-size=&quot;size26&quot;&gt;최신 자동차 취약점 동향&lt;/h2&gt;
&lt;p data-end=&quot;8542&quot; data-start=&quot;8515&quot; data-ke-size=&quot;size16&quot;&gt;강의 후반에는 최근 자동차 취약점 동향도 다뤘다.&lt;/p&gt;
&lt;p data-end=&quot;8774&quot; data-start=&quot;8544&quot; data-ke-size=&quot;size16&quot;&gt;특히 Pwn2Own Automotive에서는 EV 충전기와 IVI, 즉 인포테인먼트 헤드유닛, 텔레매틱스 모뎀이 주요 타깃으로 등장했다. 2024년에는 EV 충전기 카테고리가 처음 등장했고, 2025년에는 Tesla Wall Connector가 하루에 두 번 침해되는 사례도 있었다. 2026년에는 급속충전기 쪽 공개 익스플로잇도 언급됐다.&lt;/p&gt;
&lt;p data-end=&quot;8819&quot; data-start=&quot;8776&quot; data-ke-size=&quot;size16&quot;&gt;이 흐름을 보면 자동차 보안의 중심이 점점 넓어지고 있다는 것을 알 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;8876&quot; data-start=&quot;8821&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 차량 내부 CAN이나 ECU가 중심이었다면, 지금은 다음과 같은 영역까지 같이 봐야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;EV 충전기
인포테인먼트
텔레매틱스 모뎀
모바일 앱
클라우드 API
OBD 동글
블루투스&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9031&quot; data-start=&quot;8941&quot; data-ke-size=&quot;size16&quot;&gt;자동차가 네트워크와 연결될수록 공격자는 꼭 차량 내부에 직접 접근하지 않아도 된다. 차량 주변 장치, 앱, 서버, 충전 인프라를 통해 우회적으로 접근할 수 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;9054&quot; data-start=&quot;9033&quot; data-section-id=&quot;1yerjn&quot; data-ke-size=&quot;size26&quot;&gt;자동차 보안 규정: UN R155&lt;/h2&gt;
&lt;p data-end=&quot;9089&quot; data-start=&quot;9056&quot; data-ke-size=&quot;size16&quot;&gt;자동차 보안은 기술 문제이면서 동시에 규제 문제이기도 하다.&lt;/p&gt;
&lt;p data-end=&quot;9273&quot; data-start=&quot;9091&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 UN R155도 소개됐다. UN R155는 차량 사이버보안과 관련된 중요한 규정으로, 사이버보안 관리 시스템인 CSMS 구축과 차량 사이버보안 위험 관리 요구사항을 다룬다. 공급망 전반의 위험 관리와 차량 설계 단계에서의 보안 조치도 요구한다.&lt;/p&gt;
&lt;p data-end=&quot;9354&quot; data-start=&quot;9275&quot; data-ke-size=&quot;size16&quot;&gt;중요한 점은 자동차 보안이 이제 선택 사항이 아니라는 것이다. 차량을 만들 때부터 보안 위험을 식별하고, 관리하고, 대응하는 체계가 필요하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;자동차 보안은 패치만의 문제가 아니라,
설계 단계부터 운영과 공급망까지 이어지는 관리 문제다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;9439&quot; data-start=&quot;9422&quot; data-section-id=&quot;1r4fs84&quot; data-ke-size=&quot;size26&quot;&gt;핵심&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;자동차는 여러 ECU와 네트워크가 연결된 컴퓨터 시스템이다.
차량 보안 취약점은 메모리 오류, 권한 검증 실패, API 논리 오류, 무선 통신 문제 등에서 발생한다.
공격면은 차량 내부뿐 아니라 모바일 앱, 클라우드, 충전기, 블루투스, OBD 포트까지 확장된다.
차량 구조가 SDV와 존 아키텍처로 바뀌면서 보안 설계도 더 중요해진다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9849&quot; data-start=&quot;9707&quot; data-ke-size=&quot;size16&quot;&gt;특히 기억에 남은 건 자동차 보안이 단순히 차 문을 여는 해킹이 아니라는 점이었다.&lt;br /&gt;정수 오버플로우, 버퍼 오버플로우, 명령 삽입, 권한 검증 오류, 롤링 코드 재동기화 문제처럼 우리가 일반 보안에서 배우는 개념들이 자동차 환경에 그대로 적용된다.&lt;/p&gt;
&lt;p data-end=&quot;9896&quot; data-start=&quot;9851&quot; data-ke-size=&quot;size16&quot;&gt;다만 자동차에서는 그 결과가 물리적인 안전 문제로 이어질 수 있다는 점이 다르다.&lt;/p&gt;
&lt;p data-end=&quot;9896&quot; data-start=&quot;9851&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;9904&quot; data-start=&quot;9898&quot; data-section-id=&quot;1h9nj85&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-end=&quot;9949&quot; data-start=&quot;9906&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의를 통해 자동차 보안은 생각보다 훨씬 넓은 분야라는 걸 알게 되었다.&lt;/p&gt;
&lt;p data-end=&quot;10066&quot; data-start=&quot;9951&quot; data-ke-size=&quot;size16&quot;&gt;ECU와 CAN 같은 차량 내부 구조도 알아야 하고, 모바일 API와 클라우드 권한 모델도 봐야 한다. 블루투스나 키 포브 같은 무선 통신도 중요하고, 전기차 시대에는 충전기와 충전 인프라도 공격면이 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;자동차 보안은 차량 하나만 지키는 것이 아니라,
차량과 연결된 모든 컴퓨터, 네트워크, API, 무선 장치를 함께 지키는 일이다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;10359&quot; data-start=&quot;10192&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 자동차 보안이 낯설었지만, 결국 기본은 입력 검증, 권한 검증, 메모리 안전, 네트워크 분리, 안전한 업데이트, 공격면 관리라는 점에서 기존 보안과 이어져 있었다. 다만 자동차라는 특성상 보안 실패가 실제 안전 문제로 이어질 수 있기 때문에 더 조심스럽고 체계적인 접근이 필요하다고 느꼈다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>하계 보안 세미나</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/6</guid>
      <comments>https://song-song.tistory.com/6#entry6comment</comments>
      <pubDate>Mon, 6 Jul 2026 10:32:46 +0900</pubDate>
    </item>
    <item>
      <title>하계 보안 세미나 3일차 - ML-KEM&amp;middot;ML-DSA(Module-LWE에서 크기&amp;middot;속도&amp;middot;하이브리드 PQC까지)</title>
      <link>https://song-song.tistory.com/5</link>
      <description>&lt;div&gt;
&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-6a3a1513-0ef8-83e8-a772-7f568a0759a7-1&quot;&gt;
&lt;div&gt;
&lt;div data-conversation-screenshot-content=&quot;&quot;&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-5-thinking&quot; data-turn-start-message=&quot;true&quot; data-message-id=&quot;010f2893-078d-4174-8590-139becb3ebd5&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;blockquote data-end=&quot;365&quot; data-start=&quot;187&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;PQC 전환은 단순히 알고리즘 하나 바꾸는 일이 아니다&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-end=&quot;365&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;365&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;365&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;365&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;이번 3일차에서는 2일차에서 배웠던 격자 기반 암호가 실제 표준 알고리즘인 &lt;b&gt;ML-KEM&lt;/b&gt;과 &lt;b&gt;ML-DSA&lt;/b&gt;로 어떻게 이어지는지 배웠다.&lt;br /&gt;2일차가 SIS, LWE, Module-LWE 같은 수학적인 배경을 잡는 시간이었다면, 3일차는 그 개념이 실제 통신, 코드, 패킷 안에서 어떻게 보이는지를 확인하는 느낌이었다.&lt;/p&gt;
&lt;p data-end=&quot;464&quot; data-start=&quot;367&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 ML-KEM, ML-DSA, HKDF, AES-GCM, Wireshark 같은 단어가 한꺼번에 나와서 헷갈렸는데, 전체 흐름을 잡아보니 결국 중요한 질문은 하나였다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;패킷에 보여도 되는 값은 무엇이고,
절대 보이면 안 되는 값은 무엇인가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;579&quot; data-start=&quot;520&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의에서는 이 기준을 중심으로 PQC가 실제 통신에 들어갈 때 어떤 역할을 하는지 정리할 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;579&quot; data-start=&quot;520&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;609&quot; data-start=&quot;581&quot; data-section-id=&quot;1eyo9pk&quot; data-ke-size=&quot;size26&quot;&gt;안전한 통신에는 비밀과 신원이 둘 다 필요하다&lt;/h2&gt;
&lt;p data-end=&quot;705&quot; data-start=&quot;611&quot; data-ke-size=&quot;size16&quot;&gt;보안통신에서 중요한 것은 단순히 내용을 못 보게 하는 것만이 아니다.&lt;br /&gt;도청을 막는 것도 중요하지만, 내가 통신하고 있는 상대가 진짜 서버인지 확인하는 것도 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;742&quot; data-start=&quot;707&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 이걸 &lt;b&gt;비밀&lt;/b&gt;과 &lt;b&gt;신원&lt;/b&gt;으로 나누어 설명했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;fix&quot;&gt;&lt;code&gt;키 교환 = 비밀을 만드는 역할
서명 = 상대의 신원을 증명하는 역할&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;887&quot; data-start=&quot;796&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 클라이언트와 서버가 같은 대칭키를 만들어야 통신 내용을 암호화할 수 있다. 이 역할을 하는 것이 KEM이고, PQC에서는 ML-KEM이 여기에 해당한다.&lt;/p&gt;
&lt;p data-end=&quot;992&quot; data-start=&quot;889&quot; data-ke-size=&quot;size16&quot;&gt;반대로 &amp;ldquo;이 서버가 진짜 서버인지&amp;rdquo;를 확인하려면 전자서명이 필요하다. 인증서에 들어 있는 공개키가 정말 해당 서버의 것인지 확인해야 하기 때문이다. 이 역할을 하는 것이 ML-DSA다.&lt;/p&gt;
&lt;p data-end=&quot;1049&quot; data-start=&quot;994&quot; data-ke-size=&quot;size16&quot;&gt;즉, 양자내성암호로 넘어갈 때는 키 교환만 바꾸면 끝나는 것이 아니라, 서명 쪽도 같이 봐야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;키 교환 &amp;rarr; ML-KEM
서명 / 인증서 &amp;rarr; ML-DSA&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;1120&quot; data-start=&quot;1096&quot; data-section-id=&quot;198sfy&quot; data-ke-size=&quot;size26&quot;&gt;공개키만으로는 진짜 주인을 알 수 없다&lt;/h2&gt;
&lt;p data-end=&quot;1210&quot; data-start=&quot;1122&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 인증서 이야기도 나왔다. 처음에는 공개키만 있으면 되는 것 아닌가 싶었는데, 공개키 자체에는 &amp;ldquo;이 키가 누구 것인지&amp;rdquo;라는 정보가 보장되어 있지 않다.&lt;/p&gt;
&lt;p data-end=&quot;1325&quot; data-start=&quot;1212&quot; data-ke-size=&quot;size16&quot;&gt;누군가가 &amp;ldquo;이게 내 공개키야&amp;rdquo;라고 말한다고 해서, 그 사람이 진짜 서버인지 알 수는 없다. 공격자가 중간에서 자기 공개키를 보내도 사용자는 겉으로 보기에는 구분하기 어렵다. 이것이 중간자 공격 상황이다.&lt;/p&gt;
&lt;p data-end=&quot;1341&quot; data-start=&quot;1327&quot; data-ke-size=&quot;size16&quot;&gt;그래서 인증서가 필요하다.&lt;/p&gt;
&lt;p data-end=&quot;1440&quot; data-start=&quot;1343&quot; data-ke-size=&quot;size16&quot;&gt;인증서는 쉽게 말하면 &lt;b&gt;공개키에 신원을 묶어 놓은 디지털 신분증&lt;/b&gt;이다.&lt;br /&gt;인증서에는 서버의 도메인, 서버 공개키, 발급자, 유효기간, 그리고 CA의 전자서명이 들어간다.&lt;/p&gt;
&lt;p data-end=&quot;1526&quot; data-start=&quot;1442&quot; data-ke-size=&quot;size16&quot;&gt;중요한 점은 개인키는 인증서에 들어가지 않는다는 것이다.&lt;br /&gt;인증서에 들어가는 것은 공개키와 신원정보이고, 개인키는 서버가 따로 비밀로 보관해야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;인증서에 들어가는 것:
서버 신원
서버 공개키
CA의 서명

인증서에 들어가면 안 되는 것:
서버 개인키&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1655&quot; data-start=&quot;1600&quot; data-ke-size=&quot;size16&quot;&gt;결국 인증서는 &amp;ldquo;이 공개키가 진짜 이 서버의 공개키다&amp;rdquo;라는 사실을 CA의 서명으로 보장하는 구조다.&lt;/p&gt;
&lt;h2 data-end=&quot;1681&quot; data-start=&quot;1657&quot; data-section-id=&quot;1dxzlyg&quot; data-ke-size=&quot;size26&quot;&gt;암호화, KEM, DSA는 서로 다르다&lt;/h2&gt;
&lt;p data-end=&quot;1752&quot; data-start=&quot;1683&quot; data-ke-size=&quot;size16&quot;&gt;강의에서 헷갈리기 쉬운 개념으로 공개키 암호화, KEM, DSA가 나왔다. 셋 다 공개키와 비밀키가 나오지만 목표가 다르다.&lt;/p&gt;
&lt;p data-end=&quot;1826&quot; data-start=&quot;1754&quot; data-ke-size=&quot;size16&quot;&gt;공개키 암호화는 메시지 자체를 보호하는 방식이다.&lt;br /&gt;상대방의 공개키로 메시지를 암호화하고, 상대방은 자신의 비밀키로 복호화한다.&lt;/p&gt;
&lt;p data-end=&quot;1937&quot; data-start=&quot;1828&quot; data-ke-size=&quot;size16&quot;&gt;KEM은 메시지를 직접 암호화하는 것이 아니라, 양쪽이 같은 &lt;b&gt;shared secret&lt;/b&gt;을 만들기 위한 방식이다. 여기서 만들어진 shared secret은 이후 대칭키를 만드는 재료가 된다.&lt;/p&gt;
&lt;p data-end=&quot;2045&quot; data-start=&quot;1939&quot; data-ke-size=&quot;size16&quot;&gt;DSA는 암호화가 아니라 서명이다.&lt;br /&gt;비밀키로 메시지에 서명하고, 검증자는 공개키로 그 서명이 맞는지 확인한다. 그래서 DSA의 목표는 내용 숨기기가 아니라 &lt;b&gt;출처와 무결성 확인&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2063&quot; data-start=&quot;2047&quot; data-ke-size=&quot;size16&quot;&gt;정리하면 이렇게 볼 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;공개키 암호화 = 메시지를 잠근다
KEM = shared secret을 합의한다
DSA = 누가 보냈는지 증명한다&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2182&quot; data-start=&quot;2142&quot; data-ke-size=&quot;size16&quot;&gt;이 구분이 잡히니까 ML-KEM과 ML-DSA의 역할도 훨씬 명확해졌다.&lt;/p&gt;
&lt;h2 data-end=&quot;2218&quot; data-start=&quot;2184&quot; data-section-id=&quot;1dyh6kx&quot; data-ke-size=&quot;size26&quot;&gt;ML-KEM은 shared secret을 만드는 방식이다&lt;/h2&gt;
&lt;p data-end=&quot;2334&quot; data-start=&quot;2220&quot; data-ke-size=&quot;size16&quot;&gt;ML-KEM은 Key Encapsulation Mechanism이다.&lt;br /&gt;긴 데이터를 직접 암호화하는 알고리즘이 아니라, 클라이언트와 서버가 같은 shared secret을 만들도록 도와주는 알고리즘이다.&lt;/p&gt;
&lt;p data-end=&quot;2388&quot; data-start=&quot;2336&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 ML-KEM의 흐름을 KeyGen, Encaps, Decaps 세 단계로 설명했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;KeyGen  &amp;rarr; 공개키 pk와 비밀키 sk 생성
Encaps  &amp;rarr; pk로 ciphertext ct와 shared secret 생성
Decaps  &amp;rarr; sk와 ct로 같은 shared secret 복원&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2591&quot; data-start=&quot;2515&quot; data-ke-size=&quot;size16&quot;&gt;여기서 패킷에 보여도 되는 값은 pk와 ct다.&lt;br /&gt;반대로 sk와 shared secret은 절대 네트워크에 나오면 안 된다.&lt;/p&gt;
&lt;p data-end=&quot;2607&quot; data-start=&quot;2593&quot; data-ke-size=&quot;size16&quot;&gt;이 부분이 가장 중요했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;보여도 되는 값:
public key(pk)
ciphertext(ct)

숨겨야 하는 값:
secret key(sk)
shared secret(ss)
AES-GCM key&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2800&quot; data-start=&quot;2718&quot; data-ke-size=&quot;size16&quot;&gt;ML-KEM에서 ciphertext는 일반적인 의미의 &amp;ldquo;암호화된 메시지&amp;rdquo;라기보다는, shared secret을 복원하기 위한 &lt;b&gt;캡슐&lt;/b&gt;에 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;2959&quot; data-start=&quot;2802&quot; data-ke-size=&quot;size16&quot;&gt;강의에서도 ct는 shared secret을 담은 상자가 아니라, 비밀키를 가진 쪽이 임시 비밀값을 복원할 수 있게 해주는 재료라고 설명했다. 이 임시 비밀값에서 다시 shared secret을 만들고, 그 shared secret을 HKDF에 넣어 AES-GCM 키를 만든다.&lt;/p&gt;
&lt;p data-end=&quot;2987&quot; data-start=&quot;2961&quot; data-ke-size=&quot;size16&quot;&gt;즉 실제 데이터 암호화 흐름은 이렇게 이어진다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;ML-KEM으로 shared secret 생성
&amp;rarr; HKDF로 AES-GCM 키 파생
&amp;rarr; AES-GCM으로 실제 데이터 암호화&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;3099&quot; data-start=&quot;3072&quot; data-section-id=&quot;1ntfoc8&quot; data-ke-size=&quot;size26&quot;&gt;shared secret은 바로 쓰지 않는다&lt;/h2&gt;
&lt;p data-end=&quot;3201&quot; data-start=&quot;3101&quot; data-ke-size=&quot;size16&quot;&gt;ML-KEM으로 얻은 shared secret은 32바이트 값이다.&lt;br /&gt;그런데 이 값을 그대로 데이터 암호화 키로 쓰는 것이 아니라, HKDF 같은 KDF를 거쳐 세션키를 만든다.&lt;/p&gt;
&lt;p data-end=&quot;3314&quot; data-start=&quot;3203&quot; data-ke-size=&quot;size16&quot;&gt;여기서 HKDF는 shared secret을 실제 암호화에 쓰기 좋은 키로 다듬어 주는 역할을 한다. 그리고 transcript 같은 통신 문맥 정보를 salt나 info로 같이 넣어 키를 파생한다.&lt;/p&gt;
&lt;p data-end=&quot;3348&quot; data-start=&quot;3316&quot; data-ke-size=&quot;size16&quot;&gt;최종적으로 실제 데이터를 보호하는 것은 AES-GCM이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;shared secret
&amp;rarr; HKDF
&amp;rarr; AES-GCM key
&amp;rarr; nonce + ciphertext + tag&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3540&quot; data-start=&quot;3425&quot; data-ke-size=&quot;size16&quot;&gt;여기서도 역할 구분이 중요하다.&lt;br /&gt;PQC가 실제 데이터를 직접 암호화하는 것이 아니라, 안전한 대칭키를 만들기 위한 앞단 역할을 한다. 실제 본문 암호화는 여전히 AES-GCM 같은 대칭키 암호가 맡는다.&lt;/p&gt;
&lt;h2 data-end=&quot;3566&quot; data-start=&quot;3542&quot; data-section-id=&quot;1omrg2y&quot; data-ke-size=&quot;size26&quot;&gt;ML-DSA는 암호화가 아니라 서명이다&lt;/h2&gt;
&lt;p data-end=&quot;3674&quot; data-start=&quot;3568&quot; data-ke-size=&quot;size16&quot;&gt;ML-DSA는 디지털 서명 알고리즘이다.&lt;br /&gt;ML-KEM이 shared secret을 만드는 역할이라면, ML-DSA는 &amp;ldquo;누가 보냈는지&amp;rdquo;와 &amp;ldquo;중간에 바뀌지 않았는지&amp;rdquo;를 확인하는 역할을 한다.&lt;/p&gt;
&lt;p data-end=&quot;3751&quot; data-start=&quot;3676&quot; data-ke-size=&quot;size16&quot;&gt;서버는 secret key로 메시지나 transcript에 서명한다.&lt;br /&gt;클라이언트는 public key로 그 서명이 맞는지 검증한다.&lt;/p&gt;
&lt;p data-end=&quot;3825&quot; data-start=&quot;3753&quot; data-ke-size=&quot;size16&quot;&gt;여기서 신기했던 점은 검증자는 비밀키를 몰라도 된다는 것이다.&lt;br /&gt;비밀키는 서명을 만들 때만 필요하고, 검증은 공개키로 가능하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Sign:
secret key로 signature 생성

Verify:
public key로 message와 signature 확인&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3973&quot; data-start=&quot;3914&quot; data-ke-size=&quot;size16&quot;&gt;메시지가 1바이트라도 바뀌면 검증이 실패한다.&lt;br /&gt;그래서 서명은 출처 증명과 무결성 확인을 동시에 해준다.&lt;/p&gt;
&lt;h2 data-end=&quot;3988&quot; data-start=&quot;3975&quot; data-section-id=&quot;elqsyx&quot; data-ke-size=&quot;size26&quot;&gt;NIST 표준 기준&lt;/h2&gt;
&lt;p data-end=&quot;4024&quot; data-start=&quot;3990&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의에서는 FIPS 203, 204, 205도 정리했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;FIPS 203 &amp;rarr; ML-KEM
FIPS 204 &amp;rarr; ML-DSA
FIPS 205 &amp;rarr; SLH-DSA&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4192&quot; data-start=&quot;4094&quot; data-ke-size=&quot;size16&quot;&gt;ML-KEM은 키 합의와 shared secret 생성 쪽 표준이고, ML-DSA는 전자서명 표준이다. SLH-DSA는 해시 기반 전자서명으로, 보수적인 백업 선택지에 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;4275&quot; data-start=&quot;4194&quot; data-ke-size=&quot;size16&quot;&gt;SLH-DSA는 해시 기반이라 신뢰는 크지만, 서명 크기가 크고 느리다는 단점이 있다. 그래서 오늘 강의의 중심은 ML-KEM과 ML-DSA였다.&lt;/p&gt;
&lt;h2 data-end=&quot;4303&quot; data-start=&quot;4277&quot; data-section-id=&quot;7jhjs0&quot; data-ke-size=&quot;size26&quot;&gt;ML-KEM과 ML-DSA는 크기가 커진다&lt;/h2&gt;
&lt;p data-end=&quot;4371&quot; data-start=&quot;4305&quot; data-ke-size=&quot;size16&quot;&gt;PQC로 전환하면 보안성만 좋아지는 것이 아니라, 운영 비용도 같이 봐야 한다. 특히 패킷 크기와 서명 크기가 커진다.&lt;/p&gt;
&lt;p data-end=&quot;4462&quot; data-start=&quot;4373&quot; data-ke-size=&quot;size16&quot;&gt;ML-KEM-768 기준으로 보면 공개키는 1184B, ciphertext는 1088B 정도다. shared secret은 세 파라미터 모두 32B로 동일하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;ML-KEM-768
public key: 1184B
ciphertext: 1088B
shared secret: 32B&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4630&quot; data-start=&quot;4543&quot; data-ke-size=&quot;size16&quot;&gt;ML-DSA도 마찬가지로 서명 크기가 커진다.&lt;br /&gt;ECDSA-P256 서명은 약 72B 정도인데, ML-DSA-65의 signature는 3309B 정도다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;ECDSA-P256 signature: 약 72B
ML-DSA-65 signature: 약 3309B&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4802&quot; data-start=&quot;4702&quot; data-ke-size=&quot;size16&quot;&gt;이 부분에서 PQC 전환은 단순히 &amp;ldquo;더 안전한 알고리즘으로 교체&amp;rdquo;가 아니라는 생각이 들었다.&lt;br /&gt;인증서 체인, 펌웨어, 코드서명, 저장공간, 네트워크 지연까지 같이 고려해야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;4834&quot; data-start=&quot;4804&quot; data-section-id=&quot;12alcn4&quot; data-ke-size=&quot;size26&quot;&gt;TLS 핸드셰이크에서 KEM과 서명이 만나는 위치&lt;/h2&gt;
&lt;p data-end=&quot;4888&quot; data-start=&quot;4836&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 TLS 핸드셰이크 안에서 ML-KEM과 ML-DSA가 어디에 들어가는지도 설명했다.&lt;/p&gt;
&lt;p data-end=&quot;4901&quot; data-start=&quot;4890&quot; data-ke-size=&quot;size16&quot;&gt;흐름은 대략 이렇다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;ClientHello
&amp;rarr; ML-KEM public key 전송

ServerHello
&amp;rarr; ML-KEM ciphertext 회신

Certificate / CertificateVerify
&amp;rarr; ML-DSA 서명으로 서버 신원 증명

Application Data
&amp;rarr; shared secret에서 파생한 AES-GCM 키로 본문 암호화&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5167&quot; data-start=&quot;5101&quot; data-ke-size=&quot;size16&quot;&gt;즉 KEM은 세션키 합의를 담당하고, 서명은 서버 신원을 증명한다.&lt;br /&gt;둘은 비슷해 보이지만 완전히 다른 역할을 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;KEM = 세션키 합의
서명 = 서버 신원 증명&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;5239&quot; data-start=&quot;5209&quot; data-section-id=&quot;9g8tll&quot; data-ke-size=&quot;size26&quot;&gt;실습에서는 무엇이 보이고 무엇이 숨는지를 확인한다&lt;/h2&gt;
&lt;p data-end=&quot;5269&quot; data-start=&quot;5241&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의의 실습은 크게 세 단계로 볼 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;5429&quot; data-start=&quot;5271&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째는 로컬에서 ML-KEM, ML-DSA, AES-GCM 출력이 정상인지 확인하는 것이다.&lt;br /&gt;예를 들어 ML-KEM에서는 shared secret이 양쪽에서 같은지 확인하고, ML-DSA에서는 원본 메시지 검증은 True, 변조된 메시지 검증은 False가 나오는지 확인한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;shared secret equal: True
verify original: True
verify tampered: False&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5636&quot; data-start=&quot;5515&quot; data-ke-size=&quot;size16&quot;&gt;두 번째는 서버와 클라이언트를 나눠 실행하는 것이다.&lt;br /&gt;작은 TLS처럼 client_hello, server_hello, encrypted_request, encrypted_response 흐름을 직접 만들어 본다.&lt;/p&gt;
&lt;p data-end=&quot;5721&quot; data-start=&quot;5638&quot; data-ke-size=&quot;size16&quot;&gt;세 번째는 Wireshark로 패킷을 보는 것이다.&lt;br /&gt;여기서 가장 중요한 건 &amp;ldquo;패킷에 보여도 되는 값&amp;rdquo;과 &amp;ldquo;보이면 안 되는 값&amp;rdquo;을 구분하는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;5741&quot; data-start=&quot;5723&quot; data-ke-size=&quot;size16&quot;&gt;패킷에 보이는 값은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;kem_public_key_b64
kem_ciphertext_b64
signature_b64
nonce_b64
ciphertext_tag_b64&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5860&quot; data-start=&quot;5837&quot; data-ke-size=&quot;size16&quot;&gt;반대로 보이면 안 되는 값은 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;shared secret
AES-GCM key
plaintext response body&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5964&quot; data-start=&quot;5925&quot; data-ke-size=&quot;size16&quot;&gt;이 구분이 실제 보안통신을 이해하는 데 가장 중요한 부분이라고 느꼈다.&lt;/p&gt;
&lt;h2 data-end=&quot;5977&quot; data-start=&quot;5966&quot; data-section-id=&quot;8idh55&quot; data-ke-size=&quot;size26&quot;&gt;하이브리드 전환&lt;/h2&gt;
&lt;p data-end=&quot;6058&quot; data-start=&quot;5979&quot; data-ke-size=&quot;size16&quot;&gt;전환기에는 기존 ECDH를 바로 버리고 ML-KEM만 쓰는 것이 아니라, X25519와 ML-KEM을 함께 사용하는 하이브리드 방식도 나온다.&lt;/p&gt;
&lt;p data-end=&quot;6178&quot; data-start=&quot;6060&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 X25519MLKEM768은 기존 X25519와 ML-KEM-768을 함께 사용하는 형태다.&lt;br /&gt;이 방식은 기존 방식의 안정성과 PQC의 양자내성 보안을 같이 가져가려는 전환기 전략이라고 볼 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;6265&quot; data-start=&quot;6180&quot; data-ke-size=&quot;size16&quot;&gt;다만 하이브리드 방식은 key_share 크기가 커진다.&lt;br /&gt;ClientHello가 커지면 MTU, 지연, 중간장비 호환성 같은 문제도 같이 봐야 한다.&lt;/p&gt;
&lt;p data-end=&quot;6369&quot; data-start=&quot;6267&quot; data-ke-size=&quot;size16&quot;&gt;그래서 PQC 전환은 &amp;ldquo;지원한다 / 지원하지 않는다&amp;rdquo;만 보면 안 된다.&lt;br /&gt;실제로 어떤 그룹이 협상되었는지, 패킷 크기가 얼마나 커졌는지, 중간장비가 막지는 않는지까지 확인해야 한다.&lt;/p&gt;
&lt;h2 data-end=&quot;6396&quot; data-start=&quot;6371&quot; data-section-id=&quot;o1vgii&quot; data-ke-size=&quot;size26&quot;&gt;구현이 새면 수학이 맞아도 깨질 수 있다&lt;/h2&gt;
&lt;p data-end=&quot;6421&quot; data-start=&quot;6398&quot; data-ke-size=&quot;size16&quot;&gt;마지막으로 구현 취약점 이야기도 중요했다.&lt;/p&gt;
&lt;p data-end=&quot;6533&quot; data-start=&quot;6423&quot; data-ke-size=&quot;size16&quot;&gt;수학적으로 안전한 알고리즘이라도 구현에서 정보가 새면 공격이 가능해질 수 있다.&lt;br /&gt;특히 PQC 구현에서는 디캡슐화 실패 처리, 상수시간 구현, 랜덤 품질, 패킹/역패킹 버그 같은 부분이 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;6643&quot; data-start=&quot;6535&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 실패 여부가 시간 차이나 오류 메시지로 드러나면 공격자가 그 차이를 이용할 수 있다.&lt;br /&gt;또 비밀값에 따라 분기나 배열 접근, 루프 횟수가 달라지면 타이밍 정보가 새어 나갈 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;6800&quot; data-start=&quot;6645&quot; data-ke-size=&quot;size16&quot;&gt;강의에서는 KyberSlash 사례도 언급했다. ML-KEM/Kyber 구현에서 비밀 의존 나눗셈 타이밍 때문에 키 복원 가능성이 제기되었고, 여러 구현이 패치되었다. 이걸 보면서 &amp;ldquo;표준 알고리즘을 쓴다&amp;rdquo;는 것만으로는 부족하고, 구현 방식까지 안전해야 한다는 점을 다시 느꼈다.&lt;/p&gt;
&lt;h2 data-end=&quot;6808&quot; data-start=&quot;6802&quot; data-section-id=&quot;1h9nj85&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-end=&quot;6866&quot; data-start=&quot;6810&quot; data-ke-size=&quot;size16&quot;&gt;이번 3강은 2강에서 배운 Module-LWE 개념이 실제 표준과 통신 흐름으로 이어지는 내용이었다.&lt;/p&gt;
&lt;p data-end=&quot;6884&quot; data-start=&quot;6868&quot; data-ke-size=&quot;size16&quot;&gt;정리하면 이렇게 볼 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;vbnet&quot;&gt;&lt;code&gt;ML-KEM은 shared secret을 만드는 역할
ML-DSA는 서버 신원과 메시지 무결성을 증명하는 역할
shared secret은 HKDF를 거쳐 AES-GCM 키가 됨
실제 데이터 보호는 AES-GCM이 담당
패킷에는 pk, ct, signature는 보일 수 있음
shared secret, AES key, plaintext는 보이면 안 됨&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7209&quot; data-start=&quot;7096&quot; data-ke-size=&quot;size16&quot;&gt;가장 기억에 남은 점은 PQC 전환이 단순히 알고리즘 하나 바꾸는 일이 아니라는 것이었다.&lt;br /&gt;키 교환, 서명, 인증서, 패킷 크기, 중간장비, 구현 취약점까지 같이 봐야 실제로 안전한 전환이 가능하다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;7326&quot; data-start=&quot;7211&quot; data-ke-size=&quot;size16&quot;&gt;이번 강의를 듣고 나니 ML-KEM과 ML-DSA가 그냥 어려운 이름의 알고리즘이 아니라, TLS 같은 실제 보안통신 안에서 각각 &amp;ldquo;비밀 만들기&amp;rdquo;와 &amp;ldquo;신원 증명&amp;rdquo;을 맡는 부품이라는 점이 조금 더 명확해졌다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>하계 보안 세미나</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/5</guid>
      <comments>https://song-song.tistory.com/5#entry5comment</comments>
      <pubDate>Mon, 6 Jul 2026 10:27:14 +0900</pubDate>
    </item>
    <item>
      <title>하계 보안 세미나 2일차 - 격자 기반 암호 (SIS &amp;middot; LWE부터 Kyber와 ML-KEM)</title>
      <link>https://song-song.tistory.com/4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;PQC가 AES를 없애는 것이 아니라 공개키 암호 쪽을 바꾸는 것&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 강의에서는 &lt;b&gt;양자컴퓨터 시대의 공개키 암호&lt;/b&gt;를 주제로, 격자 기반 암호가 왜 중요한지 배웠다.&lt;br /&gt;제목만 봤을 때는 SIS, LWE, Kyber, ML-KEM 같은 용어가 한 번에 나와서 꽤 어렵게 느껴졌는데, 전체 흐름을 잡아보면 핵심은 생각보다 단순했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 공개키 암호인 RSA와 ECC는 지금까지 많이 사용되어 왔지만, 양자컴퓨터가 충분히 발전하면 위험해질 수 있다. 특히 Shor 알고리즘은 소인수분해와 이산로그 문제를 빠르게 풀 수 있기 때문에 RSA와 ECC의 기반을 흔들 수 있다. 그래서 양자컴퓨터 이후에도 버틸 수 있는 암호, 즉 &lt;b&gt;PQC(Post-Quantum Cryptography, 양자내성암호)&lt;/b&gt;가 필요해졌다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;PQC는 AES를 대체하는 것이 아니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 헷갈렸던 부분은 &amp;ldquo;PQC가 나오면 AES도 사라지는 건가?&amp;rdquo;였다.&lt;br /&gt;그런데 강의에서는 역할이 다르다고 설명했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AES 같은 대칭키 암호는 실제 데이터를 빠르게 암호화하는 역할을 한다. 반면 PQC는 RSA나 ECC처럼 &lt;b&gt;키 교환이나 서명&lt;/b&gt; 쪽 공개키 암호를 대체하는 쪽에 가깝다. 즉, PQC가 세션키를 안전하게 만들고, 그 세션키로 AES-GCM 같은 대칭키 암호가 실제 데이터를 보호하는 구조다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안통신 흐름을 간단히 보면 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;x86asm&quot;&gt;&lt;code&gt;인증서 확인
&amp;rarr; KEM 또는 ECDH로 공유 비밀 생성
&amp;rarr; HKDF로 세션키 파생
&amp;rarr; AES-GCM으로 실제 데이터 암호화
&amp;rarr; 키 관리
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 PQC 전환은 단순히 알고리즘 이름 하나 바꾸는 일이 아니라, 통신 프로토콜과 키 관리까지 같이 봐야 하는 문제였다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;격자란 무엇인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 강의의 중심은 &lt;b&gt;격자 기반 암호&lt;/b&gt;였다.&lt;br /&gt;격자는 쉽게 말하면, 일정한 규칙으로 찍힌 점들의 집합이라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPT에서는 격자를 &amp;ldquo;기저 벡터들의 모든 정수 결합&amp;rdquo;이라고 설명했다. 말이 조금 어려운데, 풀어보면 어떤 방향 벡터들이 있고, 그 벡터들을 정수 배만큼 더해서 만들 수 있는 점들이 격자점이 된다. 예를 들어 v = 2b₁ + b₂처럼 기저 벡터를 정수만큼 조합하면 격자 위의 한 점이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 점은 &lt;b&gt;같은 격자라도 어떤 기저로 보느냐에 따라 문제의 난이도가 달라질 수 있다&lt;/b&gt;는 것이다. 짧고 서로 직교에 가까운 좋은 기저를 알면 문제가 쉽게 풀리지만, 길고 거의 평행한 나쁜 기저만 알고 있으면 같은 문제도 매우 어려워진다. 강의에서는 이 차이를 &amp;ldquo;좋은 기저는 비밀키, 나쁜 기저는 공개키&amp;rdquo;처럼 설명했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;SIS: 짧은 해를 찾는 문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SIS는 &lt;b&gt;Short Integer Solution&lt;/b&gt;의 약자로, 짧은 정수해 문제라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;형태는 대략 이렇게 생겼다.&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;A &amp;middot; z &amp;equiv; 0 (mod q)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 공개된 행렬 A가 있고, 이 식을 만족하는 작은 벡터 z를 찾아야 한다.&lt;br /&gt;그냥 아무 해나 찾는 것은 비교적 쉽지만, 성분이 -1, 0, 1처럼 작은 해를 찾는 것이 어렵다. 강의에서는 이 &amp;ldquo;짧다&amp;rdquo;는 조건이 SIS의 어려움을 만든다고 설명했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 SIS는 한마디로 정리하면 이렇게 볼 수 있다.&lt;/p&gt;
&lt;pre class=&quot;dns&quot;&gt;&lt;code&gt;공개된 A가 있을 때,
A&amp;middot;z가 0이 되도록 만드는 작은 z를 찾아라.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SIS는 해시, 서명, 커밋먼트 같은 쪽과 연결된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;LWE: 노이즈가 섞인 식에서 비밀을 찾는 문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LWE는 &lt;b&gt;Learning With Errors&lt;/b&gt;의 약자다.&lt;br /&gt;이름 그대로, 오류가 섞인 상태에서 뭔가를 알아내야 하는 문제다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 형태는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;b = A &amp;middot; s + e
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 A와 b는 공개될 수 있고, s는 비밀값, e는 작은 오류다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류가 없다면 공격자는 그냥 연립방정식을 풀어서 s를 구할 수 있다. 그런데 중간에 작은 오류 e가 섞이면 상황이 달라진다. 겉보기에는 값이 조금만 흔들린 것 같지만, 실제로 식을 풀면 완전히 다른 답이 나올 수 있다. PPT에서도 노이즈가 없을 때는 비밀값이 깔끔하게 복원되지만, +1, -1 정도의 작은 노이즈만 들어가도 가우스 소거 결과가 틀어지는 예시가 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 이해한 LWE의 핵심은 이거였다.&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;정답 근처에 일부러 안개를 끼워서,
겉으로는 보이지만 정확히 되돌리기는 어렵게 만든다.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;SIS와 LWE 차이 정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의 중간정리에서는 SIS와 LWE를 이렇게 구분했다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;SIS = 짧은 우연을 찾는 문제
LWE = 오류가 섞인 직선을 복원하는 문제
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SIS는 A&amp;middot;z &amp;equiv; 0을 만족하는 작은 z를 찾는 문제이고, LWE는 b = A&amp;middot;s + e에서 오류 e 때문에 숨겨진 s를 찾기 어렵게 만드는 문제다. 둘 다 결국 &amp;ldquo;작은 것&amp;rdquo;이 핵심이다. SIS는 작은 해, LWE는 작은 오류가 난이도를 만든다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ML-KEM은 무엇인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ML-KEM은 &lt;b&gt;Module-Lattice Key Encapsulation Mechanism&lt;/b&gt;의 약자다.&lt;br /&gt;쉽게 말하면, 격자 기반 수학을 이용해서 두 사람이 같은 공유 비밀을 만들 수 있게 해주는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 건 ML-KEM이 긴 데이터를 직접 암호화하는 것이 아니라는 점이다. ML-KEM은 이후 대칭키를 만들기 위한 &lt;b&gt;shared secret&lt;/b&gt;을 안전하게 합의하는 역할을 한다. 그 shared secret은 그대로 쓰이지 않고, KDF를 거쳐 AES-GCM 같은 AEAD 암호의 키로 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흐름은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;KeyGen   &amp;rarr; 공개키 pk, 개인키 sk 생성
Encaps   &amp;rarr; pk로 캡슐화해서 ct와 shared secret 생성
Decaps   &amp;rarr; sk와 ct로 같은 shared secret 복원
그 다음 &amp;rarr; KDF를 거쳐 실제 대칭키로 사용
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개키 pk와 암호문 ct는 네트워크로 오가도 되지만, 개인키 sk와 shared secret은 절대 새면 안 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 Module-LWE가 나오는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 LWE는 이론적으로는 좋지만, 그대로 쓰기에는 공개키가 너무 커질 수 있다. 그래서 실용화를 위해 Ring-LWE, Module-LWE 같은 구조가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의에서는 Module-LWE를 &amp;ldquo;숫자 행렬의 각 칸이 작은 다항식으로 바뀐 버전&amp;rdquo;처럼 설명했다. 숫자 하나하나를 전부 들고 다니는 대신, 다항식 구조를 이용해 더 작고 빠르게 만드는 것이다. Kyber, 즉 ML-KEM은 이런 Module-LWE 구조를 이용해 실용적인 키 교환 방식으로 만든 표준이라고 볼 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;NTT는 보안이 아니라 속도를 위한 장치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의 후반부에서 NTT도 나왔다. 처음에는 이게 또 새로운 보안 가정인가 싶었는데, 그건 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NTT는 &lt;b&gt;Number Theoretic Transform&lt;/b&gt;의 약자로, 다항식 곱셈을 빠르게 하기 위한 계산 방식이다. ML-KEM 내부에서는 다항식 곱셈이 많이 필요한데, 그냥 모든 항을 하나씩 곱하면 느리다. NTT는 다항식을 곱하기 쉬운 좌표계로 바꾼 뒤, 각 자리끼리 곱하고 다시 원래 형태로 되돌리는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 문장으로 정리하면:&lt;/p&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;Module-LWE는 보안의 근거,
NTT는 그 계산을 빠르게 돌리는 엔진.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 둘을 구분하는 게 중요했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;구현 보안도 중요하다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수학적으로 안전한 알고리즘이라고 해서 실제 구현까지 자동으로 안전한 것은 아니다. 강의에서는 KyberSlash 같은 사례도 언급하면서, 비밀값에 따라 실행 시간이 달라지면 타이밍이나 캐시를 통해 정보가 샐 수 있다고 설명했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현에서 중요한 요소는 다음과 같았다.&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;상수시간 구현
정확한 mod q 감산
올바른 샘플링과 분포
재암호화 검사
실패 처리 숨기기
검증 벡터 확인
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 Decaps 과정에서 실패 여부가 밖으로 드러나면 공격자가 반복 질의를 통해 정보를 모을 수 있기 때문에, 실패 처리도 조용하고 일정하게 해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;TLS에서는 어떻게 쓰이나&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 X25519 같은 ECDH 방식으로 공유 비밀을 만들었다면, 양자컴퓨터 위협 이후에는 ML-KEM 같은 PQC 기반 KEM이 그 자리를 대체하거나 함께 사용될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의에서는 전환기에는 X25519와 ML-KEM을 함께 쓰는 하이브리드 방식도 설명했다. 중요한 점은 이것도 실제 데이터를 암호화하는 부분이 아니라, &lt;b&gt;세션키를 만드는 앞단&lt;/b&gt;이라는 것이다. 실제 데이터 보호는 여전히 AES-GCM 같은 AEAD가 담당한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 강의는 수식이 많아서 따라가기 쉽지는 않았지만, 큰 흐름은 이렇게 정리할 수 있었다.&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;양자컴퓨터가 RSA/ECC를 위협한다.
그래서 PQC가 필요하다.
그중 격자 기반 암호가 유력하다.
격자 기반 암호의 핵심 문제로 SIS와 LWE가 있다.
ML-KEM은 LWE 계열을 실용화한 키 캡슐화 표준이다.
실제 데이터 암호화는 여전히 AES-GCM 같은 대칭키 암호가 맡는다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기억에 남은 부분은 &lt;b&gt;PQC가 AES를 없애는 것이 아니라 공개키 암호 쪽을 바꾸는 것&lt;/b&gt;이라는 점이었다. 그리고 수학적으로 안전한 구조를 만드는 것도 중요하지만, 실제 구현에서 시간 차이나 실패 처리 같은 작은 정보가 새지 않게 하는 것도 그만큼 중요하다는 걸 알 수 있었다.&lt;/p&gt;</description>
      <category>하계 보안 세미나</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/4</guid>
      <comments>https://song-song.tistory.com/4#entry4comment</comments>
      <pubDate>Mon, 6 Jul 2026 10:20:45 +0900</pubDate>
    </item>
    <item>
      <title>하계 보안 세미나 1회차 - 깨지는 암호의 해부학</title>
      <link>https://song-song.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;암호 알고리즘 자체가 약해서 깨지는게 아니라 쓰는 방식이 잘못되면 깨진다&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대칭키: 같은 키 하나로 암호화와 복호화 (빠른 본문 암호화)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AES, ChaCha20&lt;/li&gt;
&lt;li&gt;빠르지만, 그 키를 어떻게 안전하게 나눠갖느냐가 문제&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비대칭키: 공개키와 개인키가 따로 (키 교환/ 서명)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RSA, ECC, ECDSA&lt;/li&gt;
&lt;li&gt;느리지만, 서로 미리 키를 공유하지 않아도 통신을 시작할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시: 키가 없고, 데이터를 고정된 길이의 값으로 바꿈 (무결성 확인)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SHA-256&lt;/li&gt;
&lt;li&gt;무결성 확인에는 쓰지만, 인증은 아님&lt;/li&gt;
&lt;li&gt;내용이 바뀌었나? 는 볼 수 있지만, 누가 보냈는지는 모름&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TLS는 이 세 개가 같이 쓰임 (ex: HTTPS)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;처음 연결할 때 비대칭키로 세션키를 안전하게 합의&lt;/li&gt;
&lt;li&gt;실제 데이터 전송은 빠른 대칭키&lt;/li&gt;
&lt;li&gt;중간에 변조됐는지는 해시 / MAC / AEAD 태그로 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AES는 블록하나를 암호화하는 기계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 데이터는 길다. 여러 블록을 어떻게 이어서 암호화할지 정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 운영모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECB (평문 블록)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;항상 같은 암호문 블록&lt;/li&gt;
&lt;li&gt;이미지를 암호화해도 윤곽이 남아 실무x&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CBC&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전 암호문 블록과 XOR해서 다음 블록을 암호화&lt;/li&gt;
&lt;li&gt;패턴은 잘 숨기지만, 패딩 검사를 잘못하면 패딩 오라클 공격 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CTR&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카운터 값을 암호화해서 키스트림을 만들고, 평문과 XOR&lt;/li&gt;
&lt;li&gt;빠르고 편하지만, nonce를 재사용하면 큰일남&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GCM&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CTR 방식에 인증 태그까지 붙인 방식&lt;/li&gt;
&lt;li&gt;요즘 많이 쓰지만, nonce 재사용에 매우 취약&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nonce 재사용이 왜 위험하냐?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CTR/GCM에서는 이런 식&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호문 C = 평문 P &amp;oplus; 키스트림 KS&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 nonce를 재사용하면 같은 키스트림 KS가 또 나옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C1 = P1 &amp;oplus; KS&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C2 = P2 &amp;oplus; KS&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘을 XOR하면&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C1 &amp;oplus; C2 = P1 &amp;oplus; P2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐하면 KS가 두 번 XOR돼서 사라짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 키를 몰라도 두 평문의 관계가 드러남 그래서 사용금지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오라클은 서버가 실수로 알려주는 작은 힌트 (1비트 응답)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 서버가 암호문을 복호화했을 때&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;패딩 맞음&amp;rdquo;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;패딩 틀림&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 다르게 반응하면, 공격자는 그 차이를 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 겨우 1비트 정보 같지만, 이걸 수백 번, 수천 번 반복하면 평문이나 키를 알아낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오라클 = 서버가 흘리는 yes/no 힌트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 1비트가 반복되면 비밀이 풀린다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패딩 오라클&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CBC 복호화 공식이 핵심&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pᵢ = Dₖ(Cᵢ) &amp;oplus; Cᵢ₋₁&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pᵢ = 알고 싶은 평문 블록&lt;/li&gt;
&lt;li&gt;Cᵢ = 현재 암호문 블록&lt;/li&gt;
&lt;li&gt;Dₖ(Cᵢ) = AES 복호화 결과, 공격자는 모름&lt;/li&gt;
&lt;li&gt;Cᵢ₋₁ = 직전 암호문 블록, 공격자가 조작 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 건&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자는 AES 키를 모른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 직전 암호문 블록 Cᵢ₋₁은 바꿀 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 서버가 패딩 맞는지 틀리는지 알려준다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 공격자가 Cᵢ₋₁을 한 바이트씩 바꿔가며 서버에 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버가 &amp;ldquo;패딩 OK&amp;rdquo;라고 하는 순간, 공격자는 그 바이트에 대한 정보를 얻음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 평문을 한 바이트씩 복원 가능&lt;/p&gt;</description>
      <category>하계 보안 세미나</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/3</guid>
      <comments>https://song-song.tistory.com/3#entry3comment</comments>
      <pubDate>Mon, 6 Jul 2026 10:11:41 +0900</pubDate>
    </item>
    <item>
      <title>[git 배우기] - 다음 단계로</title>
      <link>https://song-song.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;다시 열심히 공부해 봅시다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞 내용 벌써 까먹진 않았겠죠??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 내용도 총 4개인데요&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;HEAD 분리하기&lt;/li&gt;
&lt;li&gt;상대 참조 (^) (Relative Refs)&lt;/li&gt;
&lt;li&gt;상대 참조 #2 (~)&lt;/li&gt;
&lt;li&gt;Git에서 작업 되돌리기&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HEAD분리부터 시작할게요 이름이 되게 폭력적이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거는 현재 체크아웃된 커밋(현재 작업중인 커밋)을 가리키는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 브랜치의 이름을 가리키고 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuXcpS/dJMb99TU4CW/psfKdZCQN68IXmz8UEKOy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuXcpS/dJMb99TU4CW/psfKdZCQN68IXmz8UEKOy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuXcpS/dJMb99TU4CW/psfKdZCQN68IXmz8UEKOy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuXcpS%2FdJMb99TU4CW%2FpsfKdZCQN68IXmz8UEKOy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;310&quot; height=&quot;390&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에&lt;/p&gt;
&lt;pre id=&quot;code_1778782331820&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout C1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ck7Bvs/dJMcaf0SHHn/5CQv1uho2FkcvqN7HuKImk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ck7Bvs/dJMcaf0SHHn/5CQv1uho2FkcvqN7HuKImk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ck7Bvs/dJMcaf0SHHn/5CQv1uho2FkcvqN7HuKImk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fck7Bvs%2FdJMcaf0SHHn%2F5CQv1uho2FkcvqN7HuKImk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;454&quot; height=&quot;440&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 HEAD가 분리가 되네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 상대 참조 입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋들을 해시로 구분하는 것은 귀찮기 때문에 사용합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상대 커밋은 두가지 간단한 방법이 있는데요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한번에 한 커밋 위로 움직이는 ^&lt;/li&gt;
&lt;li&gt;한번에 여러 커밋 위로 올라가는 ~&amp;lt;num&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 캐럿 (^) 연산자 입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조 이름에 하나씩 추가할 때마다, 명시한 커밋의 부모를 찾게 됩니다&lt;/p&gt;
&lt;pre id=&quot;code_1778782895437&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;main^    //main의 부모
main^^   //main의 조부모&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;304&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpY58c/dJMcabK1LI6/dCdt3BpcYA5yKp7pKyD1Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpY58c/dJMcabK1LI6/dCdt3BpcYA5yKp7pKyD1Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpY58c/dJMcabK1LI6/dCdt3BpcYA5yKp7pKyD1Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpY58c%2FdJMcabK1LI6%2FdCdt3BpcYA5yKp7pKyD1Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;304&quot; height=&quot;644&quot; data-origin-width=&quot;304&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778782934715&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout main^&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 해주면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;650&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SasZ9/dJMb997sEsA/8Qw18eH89CQ9EZPNtKJhek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SasZ9/dJMb997sEsA/8Qw18eH89CQ9EZPNtKJhek/img.png&quot; data-alt=&quot;HEAD가 부모로 감&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SasZ9/dJMb997sEsA/8Qw18eH89CQ9EZPNtKJhek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSasZ9%2FdJMb997sEsA%2F8Qw18eH89CQ9EZPNtKJhek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;650&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;650&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HEAD가 부모로 감&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 참조인 HEAD도 상대참조를 위해 사용할 수 있어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LVjFF/dJMcabc6i4L/jx3vZm1zopOeXeMM2Tdwnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LVjFF/dJMcabc6i4L/jx3vZm1zopOeXeMM2Tdwnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LVjFF/dJMcabc6i4L/jx3vZm1zopOeXeMM2Tdwnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLVjFF%2FdJMcabc6i4L%2Fjx3vZm1zopOeXeMM2Tdwnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;302&quot; height=&quot;670&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778783072252&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 해주면 C3에서 HEAD가 분리되어, 하나씩하나씩 올라갑니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애니메이션이 너무 슉 지나가버려서 캡쳐를 못하겠어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과만 볼까요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8gVZk/dJMcabc6i6v/mIaKevL0x4Wwk4wMG8SgK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8gVZk/dJMcabc6i6v/mIaKevL0x4Wwk4wMG8SgK0/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8gVZk/dJMcabc6i6v/mIaKevL0x4Wwk4wMG8SgK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8gVZk%2FdJMcabc6i6v%2FmIaKevL0x4Wwk4wMG8SgK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;676&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 다음 &quot;~&quot; (틸드) 연산자 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;^는 올라가는데에 너무 오래걸리잖아요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거는 올라가고 싶은 부모의 갯수가 뒤에 숫자로 옵니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDmRHl/dJMcad22y1F/HE2BRI8444s0mFW7jROnG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDmRHl/dJMcad22y1F/HE2BRI8444s0mFW7jROnG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDmRHl/dJMcad22y1F/HE2BRI8444s0mFW7jROnG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDmRHl%2FdJMcad22y1F%2FHE2BRI8444s0mFW7jROnG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;330&quot; height=&quot;656&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778783472602&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout HEAD~4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vCYOR/dJMcafGDcjX/KE2bPBL44GrA1yrKu8pQGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vCYOR/dJMcafGDcjX/KE2bPBL44GrA1yrKu8pQGK/img.png&quot; data-alt=&quot;쉽네요 ㅋㅑㅋㅑ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vCYOR/dJMcafGDcjX/KE2bPBL44GrA1yrKu8pQGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvCYOR%2FdJMcafGDcjX%2FKE2bPBL44GrA1yrKu8pQGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;626&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쉽네요 ㅋㅑㅋㅑ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치 강제로 옮기기도 해봅시다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-f 옵션을 이용해요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;650&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caXMnV/dJMcacJU5ct/gwFLaD7jZXK9eR5laWiBp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caXMnV/dJMcacJU5ct/gwFLaD7jZXK9eR5laWiBp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caXMnV/dJMcacJU5ct/gwFLaD7jZXK9eR5laWiBp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaXMnV%2FdJMcacJU5ct%2FgwFLaD7jZXK9eR5laWiBp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;332&quot; height=&quot;650&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;650&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778783566554&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -f main HEAD~3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdIof5/dJMcaii1rqz/E7mTRNmjsK4keCswdgRw40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdIof5/dJMcaii1rqz/E7mTRNmjsK4keCswdgRw40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdIof5/dJMcaii1rqz/E7mTRNmjsK4keCswdgRw40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdIof5%2FdJMcaii1rqz%2FE7mTRNmjsK4keCswdgRw40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;384&quot; height=&quot;652&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치를 저 위로 빠르게 옮길 수 있게 되었습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;1104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5nnTk/dJMb997sEYo/kXWZ3kdAAQzUlEt54D9vu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5nnTk/dJMb997sEYo/kXWZ3kdAAQzUlEt54D9vu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5nnTk/dJMb997sEYo/kXWZ3kdAAQzUlEt54D9vu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5nnTk%2FdJMb997sEYo%2FkXWZ3kdAAQzUlEt54D9vu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1460&quot; height=&quot;1104&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;1104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 하나 풀어보겠습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간화면처럼 만들어야하는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3개의 명령어로 간단하게 풀 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 6개나 써서 풀었지만요..;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778785483930&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -f bugFix C0
git branch -f main C6
git checkout C1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하면 다음으로 넘어갈 수 있어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드디어 마지막&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Git에서 작업 되돌리기입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;낮은 수준의 일(개별 파일이나 묶음을 스테이징)과 높은 수준의 일(실제 변경이 복구)이 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후자에 집중할게요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Git에서 변경한 내용을 되돌리는 방법은 크게 두가지가 있습니다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git reset&lt;/li&gt;
&lt;li&gt;git revert&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 git reset은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마치 애초에 커밋하지 않은 것처럼 예전 커밋으로 브랜치를 옮기는 것입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치가 예전의 커밋을 가리키도록 이동시켜요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zC3K8/dJMcaja4DZK/f9Qhd4KO2bB5Ks1KRAmmoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zC3K8/dJMcaja4DZK/f9Qhd4KO2bB5Ks1KRAmmoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zC3K8/dJMcaja4DZK/f9Qhd4KO2bB5Ks1KRAmmoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzC3K8%2FdJMcaja4DZK%2Ff9Qhd4KO2bB5Ks1KRAmmoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;370&quot; height=&quot;658&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1778785724754&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git reset HEAD~1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWXvhp/dJMcaa6otgb/pNMHe43VKjaR31TcoEvOYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWXvhp/dJMcaa6otgb/pNMHe43VKjaR31TcoEvOYK/img.png&quot; data-alt=&quot;불투명해지네요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWXvhp/dJMcaa6otgb/pNMHe43VKjaR31TcoEvOYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWXvhp%2FdJMcaa6otgb%2FpNMHe43VKjaR31TcoEvOYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;282&quot; height=&quot;666&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;불투명해지네요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 Git 리버트(revert)입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각자의 컴퓨터에서 작업하는 로컬 브랜치의 경우 리셋(reset)을 잘 쓰겠지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람이작업하는 리모트 브랜치에는 쓸 수 없습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때 변경분을 되돌리고, 이 내용을 다른 사람들과 공유하기 위해서는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git revert를 써야합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;308&quot; data-origin-height=&quot;654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVvE5I/dJMcabqHfFW/qdYkS8Y30ZfOhUBNc3JKR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVvE5I/dJMcabqHfFW/qdYkS8Y30ZfOhUBNc3JKR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVvE5I/dJMcabqHfFW/qdYkS8Y30ZfOhUBNc3JKR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVvE5I%2FdJMcabqHfFW%2FqdYkS8Y30ZfOhUBNc3JKR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;308&quot; height=&quot;654&quot; data-origin-width=&quot;308&quot; data-origin-height=&quot;654&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778785869211&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git revert HEAD&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUAS3c/dJMcaaZAOIs/AUCgaylZLU8tD9kb4pjI7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUAS3c/dJMcaaZAOIs/AUCgaylZLU8tD9kb4pjI7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUAS3c/dJMcaaZAOIs/AUCgaylZLU8tD9kb4pjI7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUAS3c%2FdJMcaaZAOIs%2FAUCgaylZLU8tD9kb4pjI7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;334&quot; height=&quot;664&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 풀어볼게요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;local(로컬 브랜치)과 pushed(리모트 브랜치)에 있는 최근 두 번의 커밋을 되돌려야해요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에는 reset, 리모트는 revert쓰면 되겠네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;1102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6FL3W/dJMcafUab44/QT0emGkPO5DQKsF1T2ykC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6FL3W/dJMcafUab44/QT0emGkPO5DQKsF1T2ykC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6FL3W/dJMcafUab44/QT0emGkPO5DQKsF1T2ykC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6FL3W%2FdJMcafUab44%2FQT0emGkPO5DQKsF1T2ykC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1522&quot; height=&quot;1102&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;1102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1778786155561&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git reset main
git checkout pushed
git revert pushed&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Git 재밌네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 어려워요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공부하는 모든 분들 대단해요~&lt;/p&gt;</description>
      <category>Git공부</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/2</guid>
      <comments>https://song-song.tistory.com/2#entry2comment</comments>
      <pubDate>Fri, 15 May 2026 04:18:07 +0900</pubDate>
    </item>
    <item>
      <title>[git 배우기] - git 기본</title>
      <link>https://song-song.tistory.com/1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git을 배워보겠습니다....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Learn Git Branching 사이트를 사용했구요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인은 총 4갠데 그 중 첫 번째 git 기본 입니다&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Git 커밋 소개&lt;/li&gt;
&lt;li&gt;Git에서 브랜치 쓰기&lt;/li&gt;
&lt;li&gt;Git에서 브랜치 합치기(Merge)&lt;/li&gt;
&lt;li&gt;리베이스(rebase)의 기본&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋은 Git 저장소에 디렉토리에 있는 모든 파일에 대한 스냅샷을 기록하는건데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉토리 전체를 복붙하는거랑 비슷한데 훨씬 유용한 방법입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐면 Git은 가능한 한 커밋을 가볍게 유지하고자 해서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋할 때마다 디렉토리 전체를 복사하지는 않거든요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 커밋은 저장소의 이전 버전과 다음 버전의 변경내역(&quot;delta&quot;)를 저장해요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 대부분 커밋이 그 커밋 위에있는 부모 커밋을 가리킵니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장소를 복제(clone)하려면 모든 변경분(delta)를 풀어내야 하는데, 이 때문에 명령행 결과로&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778776041746&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resolving deltas&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거를 볼 수 있다네욥..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 뭔소린진 잘 모르겠지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단은&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;커밋은 프로젝트의 스냅샷이다&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 것만 알고있을게욥&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋은 매우 가볍고 커밋 사이의 전환도 엄청 빠르대요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFLpNg/dJMcagyJe7c/rzkqm3TkSK3j0yUTHJKrJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFLpNg/dJMcagyJe7c/rzkqm3TkSK3j0yUTHJKrJ1/img.png&quot; data-alt=&quot;두 번 커밋한 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFLpNg/dJMcagyJe7c/rzkqm3TkSK3j0yUTHJKrJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFLpNg%2FdJMcagyJe7c%2Frzkqm3TkSK3j0yUTHJKrJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;444&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;두 번 커밋한 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778777202833&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git commit&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;을 하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAbk0p/dJMcaaZAMIB/IhBMztKH9ou1yzWbzcc26k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAbk0p/dJMcaaZAMIB/IhBMztKH9ou1yzWbzcc26k/img.png&quot; data-alt=&quot;부모는 C1, 어떤 커밋을 기반으로 변경된 것인지를 가리킴&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAbk0p/dJMcaaZAMIB/IhBMztKH9ou1yzWbzcc26k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAbk0p%2FdJMcaaZAMIB%2FIhBMztKH9ou1yzWbzcc26k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;396&quot; height=&quot;668&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;부모는 C1, 어떤 커밋을 기반으로 변경된 것인지를 가리킴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽네요 아직까지는!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋 두 번 더 하니까 다음 단계로 와졌어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 Git 브랜치입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치는 특정 커밋에 대한 참조(reference)입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많이 만들어도 부담이 없어서, 작은 단위로 잘게 나누는 것이 좋습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많이 만들면 좋나봐요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치는 단순히&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;하나의 커밋과 그 부모 커밋들을 포함하는 작업 내역&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 기억합시다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9mNg1/dJMcai4k3Zf/QYwKtpyyr8DzYYaMBRaosK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9mNg1/dJMcai4k3Zf/QYwKtpyyr8DzYYaMBRaosK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9mNg1/dJMcai4k3Zf/QYwKtpyyr8DzYYaMBRaosK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9mNg1%2FdJMcai4k3Zf%2FQYwKtpyyr8DzYYaMBRaosK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;346&quot; height=&quot;398&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 여기서&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778777239562&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch newImage&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해주면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6Mjc7/dJMcabxp39z/Bo5XMWgJhQL259D2t0u09K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6Mjc7/dJMcabxp39z/Bo5XMWgJhQL259D2t0u09K/img.png&quot; data-alt=&quot;브랜치 newImage가 커밋 C1을 가리킴&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6Mjc7/dJMcabxp39z/Bo5XMWgJhQL259D2t0u09K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6Mjc7%2FdJMcabxp39z%2FBo5XMWgJhQL259D2t0u09K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;362&quot; height=&quot;402&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브랜치 newImage가 커밋 C1을 가리킴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 밑에 뭔가 생겼습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 커밋을 하면 어떻게 될까요?!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시&lt;/p&gt;
&lt;pre id=&quot;code_1778777328592&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git commit&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;708&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rX6RT/dJMb99M7EiJ/BbskCk2TRuG5JHpRDEB0a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rX6RT/dJMb99M7EiJ/BbskCk2TRuG5JHpRDEB0a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rX6RT/dJMb99M7EiJ/BbskCk2TRuG5JHpRDEB0a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrX6RT%2FdJMb99M7EiJ%2FBbskCk2TRuG5JHpRDEB0a1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;708&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;708&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main(별 붙은 애) 만 움직이고 아까 만든 newImage는 가만히 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(*)별표 가 붙은 애가 이동하는거래요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 저는 newImage를 이동시키고 싶은데요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면&lt;/p&gt;
&lt;pre id=&quot;code_1778777463687&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout newImage&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해주면 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋까지 같이 해줄게요&lt;/p&gt;
&lt;pre id=&quot;code_1778777501121&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout newImage; git commit&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6Mjc7/dJMcabxp39z/Bo5XMWgJhQL259D2t0u09K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6Mjc7/dJMcabxp39z/Bo5XMWgJhQL259D2t0u09K/img.png&quot; data-alt=&quot;브랜치 newImage가 커밋 C1을 가리킴&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6Mjc7/dJMcabxp39z/Bo5XMWgJhQL259D2t0u09K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6Mjc7%2FdJMcabxp39z%2FBo5XMWgJhQL259D2t0u09K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;362&quot; height=&quot;402&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브랜치 newImage가 커밋 C1을 가리킴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NcgEq/dJMcacpA4Na/ldG5zBdnNT39vnruMi2rxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NcgEq/dJMcacpA4Na/ldG5zBdnNT39vnruMi2rxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NcgEq/dJMcacpA4Na/ldG5zBdnNT39vnruMi2rxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNcgEq%2FdJMcacpA4Na%2FldG5zBdnNT39vnruMi2rxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;336&quot; height=&quot;698&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저런식으로 하니까 넘어가지네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 세 번째예요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치와 합치기(Merge)인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두개의 부모(parent)를 가리키는 특별한 커밋을 만들어냅니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 한 부모의 모든 작업내역과 나머지 부모의 모든 작업, 그리고 그 두 부모의 모든 부모들의 작업내역을 포함한다는 말&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음 잘 모르겠으니 그림을 볼까요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDKFXe/dJMcaiXAc2m/brPhSmEzTCmMERnJsdG7k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDKFXe/dJMcaiXAc2m/brPhSmEzTCmMERnJsdG7k0/img.png&quot; data-alt=&quot;브랜치 두개와 독립되 커밋이 하나씩&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDKFXe/dJMcaiXAc2m/brPhSmEzTCmMERnJsdG7k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDKFXe%2FdJMcaiXAc2m%2FbrPhSmEzTCmMERnJsdG7k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;766&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브랜치 두개와 독립되 커밋이 하나씩&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장소에 지금까지 작업한 내역이 나뉘어서 담겨 있네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bugFix브랜치를 main브랜치에 합쳐봅시다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778778053081&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git merge bugFix&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;392&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNzZZS/dJMb990Jlub/PZMXAWTiKTyoZ4T8A1rOk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNzZZS/dJMb990Jlub/PZMXAWTiKTyoZ4T8A1rOk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNzZZS/dJMb990Jlub/PZMXAWTiKTyoZ4T8A1rOk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNzZZS%2FdJMb990Jlub%2FPZMXAWTiKTyoZ4T8A1rOk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;392&quot; height=&quot;720&quot; data-origin-width=&quot;392&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main이 두 부모가 있는 커밋을 가리키고 있어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 색도 바뀌었는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;합쳐지면 두 색이 섞여요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해하기 더 쉬워졌구만&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bugFix브랜치 쪽을 제외한 나머지 커밋이 지금 main브랜치 색이네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 다 합쳐야하니까 main브랜치에 bugFix를 합쳐볼게요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778778250852&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout bugFix; git merge main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;756&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x25nb/dJMcabK1KG1/tWdKOEAgHaq3NnEiKng7X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x25nb/dJMcabK1KG1/tWdKOEAgHaq3NnEiKng7X1/img.png&quot; data-alt=&quot;이제 색이 다 똑같아졌어요!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x25nb/dJMcabK1KG1/tWdKOEAgHaq3NnEiKng7X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx25nb%2FdJMcabK1KG1%2FtWdKOEAgHaq3NnEiKng7X1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;756&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;756&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이제 색이 다 똑같아졌어요!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bugFix가 main 부모쪽에 있었어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 bugFix를 main이 붙어 있는 커밋으로 이동시키기만 하면 되네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 비슷하게 했더니 넘어가졌어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 대망의 마지막&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Git 리베이스(Rebase) 입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치끼리의 작업을 접목하는건데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리베이스는 기본적으로 커밋들을 모아서 복사한 뒤, 다른 곳에 떨궈 놓는거래요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리베이스를 쓰면 저장소의 커밋 로그랑 이력이 깨끗하고 보기좋아져요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XUbRl/dJMcabEcYGz/F0oIl2ggp34Vhfi0SEWAX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XUbRl/dJMcabEcYGz/F0oIl2ggp34Vhfi0SEWAX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XUbRl/dJMcabEcYGz/F0oIl2ggp34Vhfi0SEWAX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXUbRl%2FdJMcabEcYGz%2FF0oIl2ggp34Vhfi0SEWAX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;732&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bugFix 브랜치에서의 작업을 main 브랜치 위로 직접 옮겨 놓으려고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 순서대로 개발한 것처럼 보이게 돼요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1778778702393&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git rebase main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/49Wzo/dJMcaakY4pA/8MCkqxVgJPkD2byxEEpGKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/49Wzo/dJMcaakY4pA/8MCkqxVgJPkD2byxEEpGKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/49Wzo/dJMcaakY4pA/8MCkqxVgJPkD2byxEEpGKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F49Wzo%2FdJMcaakY4pA%2F8MCkqxVgJPkD2byxEEpGKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;666&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오호&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDGr3N/dJMb99M7EzZ/LUQzl8NqLkmt3PNHkNory0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDGr3N/dJMb99M7EzZ/LUQzl8NqLkmt3PNHkNory0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDGr3N/dJMb99M7EzZ/LUQzl8NqLkmt3PNHkNory0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDGr3N%2FdJMb99M7EzZ%2FLUQzl8NqLkmt3PNHkNory0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;656&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거는 main을 선택한 상태인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이거를 bugFix로 리베이스 해볼게요&lt;/p&gt;
&lt;pre id=&quot;code_1778778832711&quot; class=&quot;ebnf&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git rebase main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;386&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/44HFf/dJMcafNqd9B/Faz6st6zhW6GM7gHjwFq2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/44HFf/dJMcafNqd9B/Faz6st6zhW6GM7gHjwFq2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/44HFf/dJMcafNqd9B/Faz6st6zhW6GM7gHjwFq2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F44HFf%2FdJMcafNqd9B%2FFaz6st6zhW6GM7gHjwFq2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;386&quot; height=&quot;674&quot; data-origin-width=&quot;386&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main이 bugFix의 부모쪽에 있어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 그 브랜치를 더 앞쪽의 커밋을 가리키게 이동하는게 전부입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우와...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;commit, branch, merge, rebase를 배워봤습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복습을 잘 해야겠어요 헷갈리네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 merge랑 rebase의 차이점을 잘 모르겠어서 찾아봤는데요&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;구분&lt;/td&gt;
&lt;td&gt;merge&lt;/td&gt;
&lt;td&gt;rebase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;핵심 이미지&lt;/td&gt;
&lt;td&gt;갈라진 길을 다시 합류시킴&lt;/td&gt;
&lt;td&gt;내 작업을 최신 길 뒤에 다시 붙임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;한 줄 뜻&lt;/td&gt;
&lt;td&gt;두 브랜치를 &lt;b&gt;합친다&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;내 커밋을 다른 브랜치 뒤로 &lt;b&gt;옮겨 붙인다&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;새 커밋&lt;/td&gt;
&lt;td&gt;보통 &lt;b&gt;merge commit&lt;/b&gt;이 생김&lt;/td&gt;
&lt;td&gt;기존 커밋이 복사되어 C2'처럼 새 커밋이 생김&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;기록&lt;/td&gt;
&lt;td&gt;&amp;ldquo;여기서 브랜치를 합쳤다&amp;rdquo;는 기록이 남음&lt;/td&gt;
&lt;td&gt;갈라졌던 흔적이 줄어들고 깔끔해 보임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;커밋 이름 변화&lt;/td&gt;
&lt;td&gt;기존 커밋 이름이 거의 그대로 유지됨&lt;/td&gt;
&lt;td&gt;커밋이 새로 만들어져서 이름이 바뀜&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사이트에서 구분법&lt;/td&gt;
&lt;td&gt;선이 갈라졌다가 다시 합쳐지면 merge&lt;/td&gt;
&lt;td&gt;C2', C3'처럼 작은따옴표가 있으면 rebase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;명령어 예시&lt;/td&gt;
&lt;td&gt;git merge bugFix&lt;/td&gt;
&lt;td&gt;git rebase main&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;명령어 뜻&lt;/td&gt;
&lt;td&gt;현재 브랜치에 bugFix를 합침&lt;/td&gt;
&lt;td&gt;현재 브랜치를 main 뒤로 옮겨 붙임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;주의점&lt;/td&gt;
&lt;td&gt;현재 내가 있는 브랜치에 합쳐짐&lt;/td&gt;
&lt;td&gt;현재 내가 있는 브랜치가 이동됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;언제 사용?&lt;/td&gt;
&lt;td&gt;합친 기록을 남기고 싶을 때&lt;/td&gt;
&lt;td&gt;커밋 기록을 일자로 정리하고 싶을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;초보자 기억법&lt;/td&gt;
&lt;td&gt;&amp;ldquo;두 갈래를 합쳐서 새 합류점 만들기&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;내 작업을 최신 main 뒤에 다시 줄 세우기&amp;rdquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에 또 올게요.......&lt;/p&gt;</description>
      <category>Git공부</category>
      <author>song.3_3</author>
      <guid isPermaLink="true">https://song-song.tistory.com/1</guid>
      <comments>https://song-song.tistory.com/1#entry1comment</comments>
      <pubDate>Fri, 15 May 2026 02:19:45 +0900</pubDate>
    </item>
  </channel>
</rss>