<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>꿀봉자바 [Developer]</title>
    <link>https://developer87.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 24 Jul 2026 01:11:31 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>예은파파</managingEditor>
    <image>
      <title>꿀봉자바 [Developer]</title>
      <url>https://tistory1.daumcdn.net/tistory/4013720/attach/5f74ea06d0254cce837a2e69b723589f</url>
      <link>https://developer87.tistory.com</link>
    </image>
    <item>
      <title>[Linux] JVM 상태 모니터링 및 GC 정보 확인 ( jstat 명령어 )</title>
      <link>https://developer87.tistory.com/40</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;JDK 1.6부터 함께 제공되기 시작한 모니터링 및 분석 툴.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 JVM 튜닝을 하기 위하여 JVM 상태를 모니터링하고 GC(Garbage Collection) 정보를 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;jstat에서 사용할 수 있는 옵션&lt;/li&gt;
&lt;/ul&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;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%; text-align: center;&quot;&gt;&lt;b&gt;Option&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%; text-align: center;&quot;&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-class&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;클래스 로더의 동작에 대한 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-compiler&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;HotSpot의 JIT 컴파일러에 대한 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gc&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;GC된 heap의 동작에 대한 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gccapacity&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;세대마다의 용량과 대응하는 영역 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gccause&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;GC 통계 데이터(-gcutil 옵션)와 직전 및 현재의 GC 이벤트의 원인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gcnew&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;New 세대 동작에 대한 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gcnewcapacity&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;New 세대의 사이즈와 대응하는 영역에 대한 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gcold&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;Old 세대 및 Permanent 세대의 동작에 관한 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gcoldcapacity&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;Old 세대의 사이즈에 관한 통계&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gcpermcapacity&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;Permanent 세대의 사이즈에 대한 통계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-gcutil&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;GC 통계 데이터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;-printcompilation&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;HotSpot 컴파일러의 통계 데이터&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;jstat -gcutil -t {pid} {&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;interval} {repeat count}&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1181&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nHc9s/btsDZmXPD2o/6iUXSSs2uWT3n3U5xUE7j1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nHc9s/btsDZmXPD2o/6iUXSSs2uWT3n3U5xUE7j1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nHc9s/btsDZmXPD2o/6iUXSSs2uWT3n3U5xUE7j1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnHc9s%2FbtsDZmXPD2o%2F6iUXSSs2uWT3n3U5xUE7j1%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;1181&quot; height=&quot;271&quot; data-origin-width=&quot;1181&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;S0 : Survivor 영역 0의 사용율&lt;/li&gt;
&lt;li&gt;S1 : Survivor 영역 1의 사용율&lt;/li&gt;
&lt;li&gt;E : Eden 영역의 사용율&lt;/li&gt;
&lt;li&gt;O : Old 영역의 사용율&lt;/li&gt;
&lt;li&gt;P : Permanent 영역의 사용율&lt;/li&gt;
&lt;li&gt;YGC : Young 세대의 GC 이벤트 수&lt;/li&gt;
&lt;li&gt;YGCT : Young 세대의 GC 시간&lt;/li&gt;
&lt;li&gt;FGC : Full GC 이벤트 수&lt;/li&gt;
&lt;li&gt;FGCT : Full GC 시간&lt;/li&gt;
&lt;li&gt;GCT : GC 총 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. jstat -gccapacity -t {pid} {&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;interval} {repeat count}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2181&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KuGqq/btsDZJ6kisd/lAzLON5n6aKfM42H4u46vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KuGqq/btsDZJ6kisd/lAzLON5n6aKfM42H4u46vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KuGqq/btsDZJ6kisd/lAzLON5n6aKfM42H4u46vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKuGqq%2FbtsDZJ6kisd%2FlAzLON5n6aKfM42H4u46vk%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;2181&quot; height=&quot;272&quot; data-origin-width=&quot;2181&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;NGCMN : New 세대의 최소 크기 (KB)&lt;/li&gt;
&lt;li&gt;NGCMX : New 세대의 최대 크기 (KB)&lt;/li&gt;
&lt;li&gt;S0C : Survivor 영역 0의 크기&lt;/li&gt;
&lt;li&gt;S1C : Survivor 영역 1의 크기&lt;/li&gt;
&lt;li&gt;EC : Eden 영역의 크기&amp;nbsp;&lt;/li&gt;
&lt;li&gt;OGCMN : Old 세대의 최소 크기&lt;/li&gt;
&lt;li&gt;OGCMX : Old 세대의 최대 크기&amp;nbsp;&lt;/li&gt;
&lt;li&gt;OGC : Old 세대의 현재 크기&lt;/li&gt;
&lt;li&gt;OC : Old 영역의 현재 크기&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;3. 구동중인 JAVA application Heap momory 사용량 확인&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;watch -n 2 'jstat -gc 20206 | awk '\''NR&amp;gt;1 { print &quot;Used Heap: &quot; ($6+$8+$4)/1024 &quot; MB&quot; }'\'''&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Linux</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/40</guid>
      <comments>https://developer87.tistory.com/40#entry40comment</comments>
      <pubDate>Thu, 25 Jan 2024 17:03:27 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] Socket 상태 조회 ( Socket Statistics  )</title>
      <link>https://developer87.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스에서 네트워크 상태를 확인하기 위해 흔히 사용하는 명령어로 netstat 명령어가 존재하나&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 리눅스 배포판은 netstat 보다 새로운 명령어인 ss 사용을 권장하고 있음.&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;ss는 옵션 없이 사용하면 listening socket을 제외하고 현재 연결되어 있는 모든 소켓(TCP/UDP/Unix)을 표시.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3510&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBEwz8/btsDUiBB936/k3QFcQJ9LbIMRwVmeEm9g0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBEwz8/btsDUiBB936/k3QFcQJ9LbIMRwVmeEm9g0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBEwz8/btsDUiBB936/k3QFcQJ9LbIMRwVmeEm9g0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBEwz8%2FbtsDUiBB936%2Fk3QFcQJ9LbIMRwVmeEm9g0%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;3510&quot; height=&quot;664&quot; data-origin-width=&quot;3510&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;ss는 다양한 옵션을 제공한다. 자주 사용되는 옵션은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1706082865711&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ss [options] [ filters ]&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;border-collapse: collapse; width: 71.7442%; height: 275px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 16px; text-align: center;&quot;&gt;&lt;b&gt;Option&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 16px; text-align: center;&quot;&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 10px;&quot;&gt;&lt;b&gt;a&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 10px;&quot;&gt;전체 포트 보기 ( listening socket 포함 )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 16px;&quot;&gt;&lt;b&gt;t&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 16px;&quot;&gt;TCP 포트 보기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 16px;&quot;&gt;&lt;b&gt;u&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 16px;&quot;&gt;UDP 포트 보기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 16px;&quot;&gt;&lt;b&gt;x&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 16px;&quot;&gt;유닉스 포트 보기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 16px;&quot;&gt;&lt;b&gt;l&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 16px;&quot;&gt;Listening 상태의 포트 보기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 10px;&quot;&gt;&lt;b&gt;p&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 10px;&quot;&gt;프로세스명 표시하기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 19.8839%; height: 16px;&quot;&gt;&lt;b&gt;n&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.1161%; height: 16px;&quot;&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;table style=&quot;border-collapse: collapse; width: 71.6279%; height: 90px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.9675%; text-align: center;&quot;&gt;&lt;b&gt;Filter&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.0325%; text-align: center;&quot;&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.9675%;&quot;&gt;&lt;b&gt;sport&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.0325%;&quot;&gt;송신 포트 번호 또는 프로토콜 명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.9675%;&quot;&gt;&lt;b&gt;dport&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.0325%;&quot;&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;ss 명령어의 출력은 다양한 열과 행으로 구성되어 있다.&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;State&quot; (상태), &quot;Recv-Q&quot; (수신 큐), &quot;Send-Q&quot; (송신 큐), &quot;Local Address&quot; (로컬 주소), &quot;Foreign Address&quot; (원격 주소), &quot;PID/Program name&quot; (프로세스 ID/프로그램 이름) 등이 포함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;State : 소켓의 현재 상태. 여기에는 &quot;ESTAB&quot; (연결), &quot;TIME-WAIT&quot;(연결 종료 후 대기) 등이 있음.&lt;/li&gt;
&lt;li&gt;Recv-Q : 수신 대기 큐의 크기, 이 값이 0이면 현재 데이터를 받고 있지 않음을 의미.수신 대기 큐에 있는 패킷들은 아직 응용프로그램에 의해 처리되지 않고 대기 중인 상태&lt;/li&gt;
&lt;li&gt;Send-Q : 송신 대기 큐의 크기, 이 값이 0이면 현재 데이터를 보내고 있지 않음을 의미. 데이터를 네트워크로 보내기 위해 대기하는 데이터의 양&lt;/li&gt;
&lt;li&gt;Local Address : 로컬 주소와 포트 번호&lt;/li&gt;
&lt;li&gt;Peer Address : 원격 주소와 포트 번호&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Recv-Q, Send-Q의 값이 점차 증가 한다면 해당 소켓에 대한 처리가 따라오지 못하거나 병목현상이 발생되고 있을 수 있고 이는 네트워크 대역폭의 이유 또는 응용프로그램 수신 부문에서 병목이 발생하고 있음을 뜻함.&lt;/b&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;nstat&amp;nbsp;-az&amp;nbsp;TcpExtTCPRcvCollapsed&amp;nbsp;TcpExtRcvPruned&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- nstat 유틸리티를 이용하여 TcpExtTCPRcvCollapsed 및 TcpExtRcvPruned 카운트를 조회&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;위 명령어들을 통해 socket buffer&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;span&gt;nohup bash -c 'while true; do echo -e &quot;$(date)\n$(ss -ntl | grep -e &quot;12000&quot; -e &quot;Send-Q&quot;)\n&quot; &amp;gt;&amp;gt; output.log; sleep 10; done' &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Linux</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/39</guid>
      <comments>https://developer87.tistory.com/39#entry39comment</comments>
      <pubDate>Wed, 24 Jan 2024 17:19:07 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Time Orderd UUID</title>
      <link>https://developer87.tistory.com/38</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;UUID를 Primary Key로 썼을 경우&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MariaDB InnoDB 테이블의 Primary Key는 Clustered 인덱스로 물리적으로 순서대로 유지가 가능&lt;/li&gt;
&lt;li&gt;UUID의 값은 unique하긴 하나 랜덤하게 발생되는 값으로, Primary Key 컬럼일 경우 Clustered Index로 재배열하게 되어, InnoDB 스트로지 엔진의 부하가 발생.&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;h2 data-ke-size=&quot;size26&quot;&gt;해결방안&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UUID를 랜덤하게 생성하되 이 값을 sequencial 하게 생성하여, DB 입장에서 새로운 데이터가 들어오더라도 indexing으로 인해 드는 리소스가 랜덤값보다 현저히 감소.&lt;/li&gt;
&lt;li&gt;Java UUID Generator (JUG) Library 사용 ( 아래 dependecy 추가 )&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1645599365162&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
	&amp;lt;groupId&amp;gt;com.fasterxml.uuid&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;java-uuid-generator&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;4.0.1&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1645599399712&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TimeBasedGenerator gen = Generators.timeBasedGenerator(EthernetAddress.fromInterface());
UUID uuid = gen.generate();
UUID anotherUuid = gen.generate();
		
System.out.println( uuid );
System.out.println( anotherUuid );

----------------------------------------------------------------------------------------------
결과 
d8a551a6-9475-11ec-8083-00d86126fd1a
d8a551a7-9475-11ec-8083-00d86126fd1a&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java-uuid-generator</category>
      <category>jug</category>
      <category>Time based UUID</category>
      <category>UUID</category>
      <category>UUID ORDERED</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/38</guid>
      <comments>https://developer87.tistory.com/38#entry38comment</comments>
      <pubDate>Wed, 23 Feb 2022 15:59:14 +0900</pubDate>
    </item>
    <item>
      <title>/dev/null 2&amp;gt;&amp;amp;1 와 nohup, &amp;amp; 의미</title>
      <link>https://developer87.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;shell(#mode)에서 간단하게 명령어를 통해 테스트를 진행하면서 &quot;/dev/null 2&amp;gt;&amp;amp;1&quot;의 의미를 알아봅니다.&lt;/span&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;span&gt;아래 명령어는 표준 출력을 /dev/null로 redirection 하라는 의미로 표준출력을 버리라는 의미입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1629867314469&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ rm test &amp;gt; /dev/null&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;span style=&quot;color: #666666;&quot;&gt;하지만, test라는 file이 존재하지 않는 경우 아래와 같은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;표준에러&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;가 출력됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629867415281&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ rm test &amp;gt; /dev/null
rm: cannot remove 'test': No such file or directory&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;span&gt;방금 언급했지만, 이것은 &quot;표준출력&quot;이 아닌 &quot;표준에러&quot;이기 때문에 화면에 출력이 된것입니다.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;다시 강조하면 위에 예제는 /dev/null 로 redirection 을 통해 화면 출력을 하지 않는것은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;표준출력&lt;/span&gt;에 한해서 해당됩니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;br /&gt;자 그렇다면, 표준에러를 버리고 싶다면 아래와 같이 사용하도록 합시다,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629867431395&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ rm test &amp;gt; /dev/null 2&amp;gt;&amp;amp;1&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;span style=&quot;color: #666666;&quot;&gt;2&amp;gt;&amp;amp;1 는 표준에러를 표준출력으로 redirection 하라는 의미입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0 : 표준입력&lt;/li&gt;
&lt;li&gt;1 :&amp;nbsp;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot;&gt;표준출력&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;2 : &lt;span style=&quot;color: #ee2323;&quot;&gt;표준에러&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정리하면 &quot;rm test&quot;의 표준출력을 /dev/null로 버리는데, 표준에러는 표준출력으로 redirection 합니다.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;결국 결과는 표준출력이 되기 때문에 /dev/null로 버려지고, 화면에 결과가 뿌려지지 않게 되는 것입니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;br /&gt;/dev/null과 2&amp;gt;&amp;amp;1를 같이 사용하지 않는 경우 위의 예제는 결국 표준출력되기 때문에 화면에 에러 내용이 출력됩니다.&lt;/span&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;pre id=&quot;code_1629867654405&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ foo.sh 1&amp;gt;output.log 2&amp;gt;error.log&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;nohup이란? 리눅스, 유닉스에서 쉘스크립트 파일( *.sh)을 데몬 형태로 실행시키는 프로그램&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;amp; 이란? 프로세스를 실행할 때 백그라운드에서 동작하도록 만드는 명령어&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;nohup으로 실행할 쉘 스크립트파일(*.sh)은 현재 퍼미션이 755 이상 상태여야 가능. ( e.g. chmod 755 shell.sh )&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_1629867869483&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ nohup shell.sh &amp;amp;
$ nohup -- ./shell.sh &amp;amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종료 방법&lt;/p&gt;
&lt;pre id=&quot;code_1629867911146&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;ps -ef | grep #{shell스크립트 파일명}&quot;
kill -9 #{shell pid}&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;a href=&quot;https://jybaek.tistory.com/115&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jybaek.tistory.com/115, &lt;/a&gt;&lt;a href=&quot;https://brownbears.tistory.com/164&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://brownbears.tistory.com/164&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Linux</category>
      <category>/dev/null</category>
      <category>Linux</category>
      <category>nohup</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/37</guid>
      <comments>https://developer87.tistory.com/37#entry37comment</comments>
      <pubDate>Wed, 25 Aug 2021 14:05:41 +0900</pubDate>
    </item>
    <item>
      <title>[Java] JMX를 통한 자원 모니터링</title>
      <link>https://developer87.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;JMX 확장 라이브러리를 이용한 Jconsole, Jvisualvm 기반으로 서버 실시간 자원 모니터링.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( Thread dump도 지원한다. )&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;Java 실행하는 쉘 스크립트를 이용하여 JMX port 오픈하는 방법&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;DEBUG_OPT=&quot;-Dcom.sun.management.jmxremote&amp;nbsp;-Dco&lt;a href=&quot;http://m.sun.management.jmxremote.port=80&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.sun.management.jmxremote.port= &lt;/a&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: start;&quot; href=&quot;http://m.sun.management.jmxremote.port=8080&quot;&gt;#{JMX PORT}&lt;/a&gt; &amp;nbsp;-Dco&lt;a href=&quot;http://m.sun.management.jmxremote.rmi.port=80&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.sun.management.jmxremote.rmi.port= &lt;/a&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: start;&quot; href=&quot;http://m.sun.management.jmxremote.port=8080&quot;&gt;#{JMX PORT}&lt;/a&gt; &amp;nbsp;-Dco&lt;a href=&quot;http://m.sun.management.jmxremote.local.only=false&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.sun.management.jmxremote.local.only=false&lt;/a&gt;&amp;nbsp;-Dcom.sun.management.jmxremote.authenticate=false&amp;nbsp;-Dco&lt;a href=&quot;http://m.sun.management.jmxremote.ssl=false&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.sun.management.jmxremote.ssl=false&lt;/a&gt; -Djava.rmi.server.hostname=#{SERVER IP}&quot;&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;C:\Program Files\Java\jdk1.8.0_201\bin\Jvisualvm.exe 실행&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;2712&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VK0hG/btq616UabAq/eZKkJxFc2DFJ8YhWXoHuq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VK0hG/btq616UabAq/eZKkJxFc2DFJ8YhWXoHuq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VK0hG/btq616UabAq/eZKkJxFc2DFJ8YhWXoHuq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVK0hG%2Fbtq616UabAq%2FeZKkJxFc2DFJ8YhWXoHuq1%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;2712&quot; height=&quot;358&quot; data-origin-width=&quot;2712&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Java</category>
      <category>java</category>
      <category>JMX PORT</category>
      <category>Thread</category>
      <category>서버 모니터링</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/36</guid>
      <comments>https://developer87.tistory.com/36#entry36comment</comments>
      <pubDate>Fri, 11 Jun 2021 14:12:41 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] TCPDUMP 사용법</title>
      <link>https://developer87.tistory.com/35</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;i&gt;LINUX TCPDUMP 사용법&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCPDUMP는 주어진 조건식을 만족하는 네트워크 인터페이스를 거치는 패킷들의 헤더를 출력해 주는 유틸&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( 설치되어 있지 않을 경우, &lt;b&gt;yum install tcpdump&lt;/b&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;명령어 : tcpdump [option] [expression] [host]&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;( tcpdump -i any -w test.pcap -C 16 -s 1500 -z root port 11200&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Option&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;-i device : 어느 인터페이스를 경유하는 패킷들을 잡을지 지정한다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 지정되지 않으면 시스템의 인터페이스 리스트를 확인하여 가장 낮은 번호를 가진 인터페이스를 선택&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ( loopback은 제외 )&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;-w : capture packet을 분석하여 출력하는 대신에 파일로 저장한다.&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;-c number : 입력한 수의 패킷을 받은 후 종료한다. ( capture할 갯 수 )&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;-s length : 패킷들로부터 추출하는 샘플을 default 값인 68 byte외의 값으로 설정할 때 사용.&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://dany-it.tistory.com/100&quot;&gt;https://dany-it.tistory.com/100&lt;/a&gt;&lt;/p&gt;</description>
      <category>Linux</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/35</guid>
      <comments>https://developer87.tistory.com/35#entry35comment</comments>
      <pubDate>Sat, 6 Feb 2021 22:35:39 +0900</pubDate>
    </item>
    <item>
      <title>[Network] WireShark 필터 명령어 방법</title>
      <link>https://developer87.tistory.com/34</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;i&gt;WireShark 필터 주요 기능&lt;/i&gt;&lt;/h3&gt;
&lt;p&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;1. MAC ID 필터링&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Source &amp;amp; &lt;span style=&quot;color: #333333;&quot;&gt;Destination&lt;/span&gt;둘다 : eth.addr = 00:12:34:56:78:9A&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Source : eth.src == &lt;span style=&quot;color: #333333;&quot;&gt;00:12:34:56:78:9A&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #333333;&quot;&gt;Destination&lt;/span&gt;: eth.dst == &lt;span style=&quot;color: #333333;&quot;&gt;00:12:34:56:78:9A&lt;/span&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;2. IP 필터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Source &amp;amp; Destination 둘다 : ip.addr == 13.107.4.50&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Source : ip.src == 13.107.4.50&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #333333;&quot;&gt;Destination &lt;/span&gt;: ip.dst == &lt;span style=&quot;color: #333333;&quot;&gt;13.107.4.50&lt;/span&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;span style=&quot;color: #333333;&quot;&gt;3. PORT 필터링 (TCP,UDP 동일)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- Source &amp;amp; &lt;span style=&quot;color: #333333;&quot;&gt;Destination 둘다 : tcp.port == 8443&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- Source : tcp.srcport == 8443&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- &lt;span style=&quot;color: #333333;&quot;&gt;Destination : tcp.dstport == 8443&lt;/span&gt;&lt;/span&gt;&lt;/span&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;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;4. 명령어 혼합 사용&lt;/span&gt;&lt;/span&gt;&lt;/span&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;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;ex) IP가 13.107.4.50 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이며&lt;/b&gt; &lt;/span&gt;PORT가 8443인 경우&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- ip.addr == 13.107.4.50 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;and&lt;/b&gt; &lt;/span&gt;tcp.port == 8443&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ip.addr == 192.168.2.100 and not tcp.port in {11200 8443}&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;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;ex) IP가 13.107.4.50 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이거나&lt;/span&gt;&lt;/b&gt;, PORT가 8443인 경우&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- ip.addr == 13.107.4.50 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;or&lt;/b&gt; &lt;/span&gt;tcp.port == 8443&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Network</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/34</guid>
      <comments>https://developer87.tistory.com/34#entry34comment</comments>
      <pubDate>Sat, 6 Feb 2021 21:40:01 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 공개키(Public Key) 와 개인키(Priviate Key)</title>
      <link>https://developer87.tistory.com/32</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대칭키와 비대칭키란?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;대칭키는 암호화 / 복호화 시에 사용하는 키가 동일한 방식으로 1개의 키만 사용한다.&lt;br /&gt;전자문서(비밀편지)가 대칭키(열쇠)로 암호화 되면 똑같은 대칭키를 가지고 있는 상대방만이 이 전자문서를 복호화 할 수 있으며, 누군가가 암호화된 전자문서를 입수 하여도 이를 복호화하지 못하기 때문에 입수한 사람에게는 아무 의미가 없는 문서이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;대칭키.png&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;267&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kF9Gj/btqPRAqktXH/v4iPYHm2w7rJAWKk5C4j2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kF9Gj/btqPRAqktXH/v4iPYHm2w7rJAWKk5C4j2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kF9Gj/btqPRAqktXH/v4iPYHm2w7rJAWKk5C4j2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkF9Gj%2FbtqPRAqktXH%2Fv4iPYHm2w7rJAWKk5C4j2K%2Fimg.png&quot; data-filename=&quot;대칭키.png&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;267&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;비대칭키는 사용하는 키와 복호화 할 때 사용하는 키가 다른 경우를 말한다. 타인에게 절대 노출되어서는 안되는 비밀키(개인키), 비밀키를 토대로 만든 공개키가 쌍을 이룬 형태이다. 2개의 키를 사용한다.&lt;/li&gt;
&lt;li&gt;공개키 - 사람들에게 공개된 키이며 정보를 암호화 할 수 있다.&lt;/li&gt;
&lt;li&gt;비밀키 - 사용자만 알고 있는 암호를 풀 수 있는 키&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;비대칭키.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;570&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZIFki/btqPTDf2fG0/yMfzHwUjWxL4UP9uj6kaI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZIFki/btqPTDf2fG0/yMfzHwUjWxL4UP9uj6kaI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZIFki/btqPTDf2fG0/yMfzHwUjWxL4UP9uj6kaI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZIFki%2FbtqPTDf2fG0%2FyMfzHwUjWxL4UP9uj6kaI0%2Fimg.png&quot; data-filename=&quot;비대칭키.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;570&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Java RSA 암호화/복호화 Util 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1607607453949&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class RSAUtil {

    /**
     * 1024비트 RSA 키쌍을 생성
     */
    public static KeyPair genRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance(&quot;RSA&quot;);
        gen.initialize(1024, new SecureRandom());
        return gen.genKeyPair();
    }

    /**
     * Public Key로 RSA 암호화를 수행
     */
    public static String encryptRSA(String plainText, PublicKey publicKey)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
            BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(&quot;RSA&quot;);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        byte[] bytePlain = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(bytePlain);
    }

    /**
     * Private Key로 RSA 복호화를 수행
     */
    public static String decryptRSA(String encrypted, PrivateKey privateKey)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
            BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Cipher cipher = Cipher.getInstance(&quot;RSA&quot;);
        byte[] byteEncrypted = Base64.getDecoder().decode(encrypted.getBytes());

        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] bytePlain = cipher.doFinal(byteEncrypted);
        return new String(bytePlain, &quot;utf-8&quot;);
    }

    public static PublicKey getPublicKeyFromBase64Encrypted(String base64PublicKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] decodedBase64PubKey = Base64.getDecoder().decode(base64PublicKey);

        return KeyFactory.getInstance(&quot;RSA&quot;)
                .generatePublic(new X509EncodedKeySpec(decodedBase64PubKey));
    }

    public static PrivateKey getPrivateKeyFromBase64Encrypted(String base64PrivateKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] decodedBase64PrivateKey = Base64.getDecoder().decode(base64PrivateKey);

        return KeyFactory.getInstance(&quot;RSA&quot;)
                .generatePrivate(new PKCS8EncodedKeySpec(decodedBase64PrivateKey));
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Java RSA Util을 이용한 Test Client&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1607607721333&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class RSAUtilTest {

    public static void main(String[] args) throws Exception {
		
        // RSA 키쌍을 생성
        KeyPair keyPair = RSAUtil.genRSAKeyPair();

        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String plainText = &quot;RSA Encryption test&quot;;

        // Base64 인코딩된 암호화 문자열
        String encrypted = RSAUtil.encryptRSA(plainText, publicKey);

        // 복호화
        String decrypted = RSAUtil.decryptRSA(encrypted, privateKey);

        // 공개키를 Base64 인코딩한 문자일을 만듦
        byte[] bytePublicKey = publicKey.getEncoded();
        String base64PublicKey = Base64.getEncoder().encodeToString(bytePublicKey);

        // 개인키를 Base64 인코딩한 문자열을 만듦
        byte[] bytePrivateKey = privateKey.getEncoded();
        String base64PrivateKey = Base64.getEncoder().encodeToString(bytePrivateKey);

        // base64 암호화한 String 에서 Public Key 를 다시생성한후 암호화 테스트를 진행
        PublicKey rePublicKey = RSAUtil.getPublicKeyFromBase64Encrypted(base64PublicKey);
        String encryptedRe = RSAUtil.encryptRSA(plainText, rePublicKey);
        String decryptedRe = RSAUtil.decryptRSA(encryptedRe, privateKey);

        // base64 암호화한 String 에서 Private Key 를 다시생성한후 복호화 테스트를 진행
        PrivateKey privateKeyRe = RSAUtil.getPrivateKeyFromBase64Encrypted(base64PrivateKey);
        String decryptedReRe = RSAUtil.decryptRSA(encryptedRe, privateKeyRe);
	        
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q2RHH/btqPPDVsAU3/yeC2fm5aXKNITN56euSteK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q2RHH/btqPPDVsAU3/yeC2fm5aXKNITN56euSteK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q2RHH/btqPPDVsAU3/yeC2fm5aXKNITN56euSteK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq2RHH%2FbtqPPDVsAU3%2FyeC2fm5aXKNITN56euSteK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>JAVA RSA</category>
      <category>RSA</category>
      <category>공개키 개인키</category>
      <category>대칭키</category>
      <category>비대칭키</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/32</guid>
      <comments>https://developer87.tistory.com/32#entry32comment</comments>
      <pubDate>Thu, 10 Dec 2020 22:45:02 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 암호 알고리즘 / 운용 모드 / Padding</title>
      <link>https://developer87.tistory.com/31</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;암호 알고리즘&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;자바에서는 대칭키 알고리즘을 사용하여 데이터를 암호화/복호화 시에 javax.crypto.Cipher 클래스를 사용한다,&amp;nbsp;&lt;br /&gt;클래스의 인스턴스는 정적 메서드인 Cipher.getInstance() 를 호출하여 생성할 수 있는데, 이 때 호출 시 사용할 알고리즘, 운용 모드, 패딩 방식을 인자 값으로 넘겨줘야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;혼돈과 확산을 달성하기 위해 Substitution 과 Permutation을 이용한다. Subsititution은 문자를 다른 문자로 바꾸는 것이고, Permutation은 문자들의 순서를 바꾸는 것이다. Substituition과 Permutation을 한번 수행하는 것이 암호 알고리즘의 기본 수행 단위 이다. 암호문은 이를 여러번 수행할수록 안전하다. Substitution-Permutation을 연속으로 수행하도록 이어 놓은 것을 SPN(Subsititution Permutation Network)이라고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;SPN을 이용하는 대표적인 암호 알고리즘으로 AES가 있다. SPN을 이용하는 알고리즘은 보통 데이터를 블록 단위로 처리한다. AES의 경우 블록의 크기는 128비트(16바이트)이다. 그런데 모든 데이터가 16바이트 크기를 가질 수 없으므로, 데이터를 블록 단위로 나누어 처리하고 합치는 과정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;운용 모드&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;데이터를 블록으로 나누어 처리하고 합치는 것, 이것이 암호화해서 운용 모드가 하는 역할이다. 대표적인 운용 모드로는 ECB(Electronic Code Book) 와 CBC(Cipher Block Chaining)가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;- &lt;span style=&quot;color: #333333;&quot;&gt;ECB(Electronic Code Book)&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;1202px-ECB_encryption.svg.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xLUhx/btqOvdX23iT/yo14A9s82YVKVIqrtjrhnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xLUhx/btqOvdX23iT/yo14A9s82YVKVIqrtjrhnK/img.png&quot; data-alt=&quot;Electronic Code Book&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xLUhx/btqOvdX23iT/yo14A9s82YVKVIqrtjrhnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxLUhx%2FbtqOvdX23iT%2Fyo14A9s82YVKVIqrtjrhnK%2Fimg.png&quot; data-filename=&quot;1202px-ECB_encryption.svg.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Electronic Code Book&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;ECB는 단순히 블록 단위로 처리한 결과를 이어 붙이는 방식으로 같은 값을 갖는 원문 블록은 같은 암호 블록을 출력하기 때문에 원문의 패턴이 그대로 드러난다, 이는 암호문에서 원문을 유추할 수 있음을 의미하기 때문에 ECB는 확산의 성질을 달성하지 못한다고 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;- CBC(Cipher Block Chaining)&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;1202px-CBC_encryption.svg.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHSQ4p/btqOuIDXZTW/XkQKDRUkJ2biSxwmuTDjxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHSQ4p/btqOuIDXZTW/XkQKDRUkJ2biSxwmuTDjxK/img.png&quot; data-alt=&quot;Cipher Block Chaining&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHSQ4p/btqOuIDXZTW/XkQKDRUkJ2biSxwmuTDjxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHSQ4p%2FbtqOuIDXZTW%2FXkQKDRUkJ2biSxwmuTDjxK%2Fimg.png&quot; data-filename=&quot;1202px-CBC_encryption.svg.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cipher Block Chaining&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;CBC는 원문 블록을 그대로 암호화하지 않고, 직전에 암호화된 블록과 XOR 연산을 한 다음에 암호화를 수행한다. 그렇기 때문에 같은 내용을 갖는 원문 블록이라도 전혀 다른 암호문을 갖게 된다. 그런데 첫번째 블록은 직전 암호문이 없으므로 XOR 연산 대상이 없다. 이를 위해 CBC모드는 초기화 백터(Initialization Vector)를 입력 받는다. 초기화 벡터는 원문 블록을 XOR하는데 쓰이기 때문에 당연히 블록 사이즈와 동일한 크기여야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;CBC모드는 직전 블록이 다음 블록의 암호화에 관여하므로 일부 블록만 복호화하고 싶어도 전체를 복호화해야 한다.&lt;/p&gt;
&lt;p&gt;반면 ECB는 전체를 복호화 하지 않고 일부만 복호화하는 것이 가능하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;패딩(Padding)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;AES와 같은 16바이트 크기의 블록 암호 알고리즘을 사용하는데 원문의 크기가 16바이트의 배수가 아닐 경우, 마지막 블록은 16바이트보다 작은 크기가 된다. 이 때 마지막 블록의 빈 부분을 채워주는 방식을 패딩이라고 한다. 가장 유명한 패딩 방식인 PKCS5 / PKCS7이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;특정 암호화 알고리즘에서는(AES,DES 등) 입력문자열이 특정 바이트의 배수가 되어야 하는 상황에 Padding을 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;블럭사이즈가 8바이트로 설정해 놓은 상태에서 5바이트의 평문이 입력될 경우,&lt;/p&gt;
&lt;p&gt;[AA A1 A2 A3 A4 _ _ _] 이런식으로 블럭이 채워지게 되는데, 블럭사이즈인 8바이트 3바이트가 모자란 상태 패딩을 수행하게되면 [AA A1 A2 A3 A4 03 03 03] 모자란 바이트의 수로 채워주게 된다. 이러한 방식을 PKCS 방식이라고 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;참고 링크&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;a href=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1606558402082&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Java Cipher - 알고리즘, 운용 모드, 패딩의 이해&quot; data-og-description=&quot;자바에서는 대칭키 알고리즘을 사용하여 데이터를 암호화/복호화할 때 javax.crypto.Cipher 클래스를 사용한다. 이 클래스의 인스턴스는 정적 메서드인 Cipher.getInstance()를 호출하여 가져올 수 있는데,&quot; data-og-host=&quot;happinessoncode.com&quot; data-og-source-url=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot; data-og-url=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/index.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cN1pdV/hyIoTweihh/S2jV7tI20NKKUFZk19Rnd1/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912,https://scrap.kakaocdn.net/dn/EM6v5/hyIoRSH2bc/mf64hd6yoWjvi2XKcmVysk/img.png?width=1202&amp;amp;height=484&amp;amp;face=0_0_1202_484,https://scrap.kakaocdn.net/dn/cNHRwX/hyIm9AGp1h/FuYHqRDaFNE927L6brhcL0/img.jpg?width=196&amp;amp;height=216&amp;amp;face=0_0_196_216,https://scrap.kakaocdn.net/dn/bfhQI5/hyInn6L04t/kJHKPG86ack1WVt6OGok30/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912&quot;&gt;&lt;a href=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cN1pdV/hyIoTweihh/S2jV7tI20NKKUFZk19Rnd1/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912,https://scrap.kakaocdn.net/dn/EM6v5/hyIoRSH2bc/mf64hd6yoWjvi2XKcmVysk/img.png?width=1202&amp;amp;height=484&amp;amp;face=0_0_1202_484,https://scrap.kakaocdn.net/dn/cNHRwX/hyIm9AGp1h/FuYHqRDaFNE927L6brhcL0/img.jpg?width=196&amp;amp;height=216&amp;amp;face=0_0_196_216,https://scrap.kakaocdn.net/dn/bfhQI5/hyInn6L04t/kJHKPG86ack1WVt6OGok30/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Java Cipher - 알고리즘, 운용 모드, 패딩의 이해&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;자바에서는 대칭키 알고리즘을 사용하여 데이터를 암호화/복호화할 때 javax.crypto.Cipher 클래스를 사용한다. 이 클래스의 인스턴스는 정적 메서드인 Cipher.getInstance()를 호출하여 가져올 수 있는데,&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;happinessoncode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/31</guid>
      <comments>https://developer87.tistory.com/31#entry31comment</comments>
      <pubDate>Sat, 28 Nov 2020 15:50:46 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pattern] Chain of Responsibility Pattern</title>
      <link>https://developer87.tistory.com/30</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;책임 연쇄 패턴( Chain of Responsibility Pattern )&lt;/b&gt;&lt;/h3&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;체인에 들어가는 객체를 바꾸거나 순서를 바꿈으로서 역할을 동적으로 추가/제거 및 상황에 따라 동적으로 핸들러를 추가하거나 제거 할 수 있으며 이러한 변화가 전체 구조에 아무런 영향을 주지 않도록 클래스들 간의 낮은 결합도로 구현되어있다.&lt;/li&gt;
&lt;li&gt;명령에 대한 처리가 반드시 수행된다는 보장이 안되므로 반드시 명령이 처리 될 수 있도록 적절한 체인의 순서 구현 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;이미지 192.png&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;923&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NDFIg/btqN2Wbz7eG/GMyQo9KAk2M3plGO3RUnx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NDFIg/btqN2Wbz7eG/GMyQo9KAk2M3plGO3RUnx0/img.png&quot; data-alt=&quot;Chain of Responsibility 클래스 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NDFIg/btqN2Wbz7eG/GMyQo9KAk2M3plGO3RUnx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNDFIg%2FbtqN2Wbz7eG%2FGMyQo9KAk2M3plGO3RUnx0%2Fimg.png&quot; data-filename=&quot;이미지 192.png&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;923&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Chain of Responsibility 클래스 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;※ Sample Code&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606114543435&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract class Middleware {

    private Middleware next; 
	
    /**
     * Builds chains of middleware objects.
     */
    public Middleware linkWith(Middleware next) {
    	
        this.next = next;
        return next;
    }

    /**
     * Subclasses will implement this method with concrete checks.
     */
    public abstract boolean check(String email, String password);

    /**
     * Runs check on the next object in chain or ends traversing if we're in
     * last object in chain.
     */
    protected boolean checkNext(String email, String password) {
    	
        if (next == null) {
            return true;
        }
        
        return next.check(email, password);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;▲ 추상클래스 선언 ( java 8 이상부터는 interface의 default method로 구현해도 될 듯 하다. )&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606114593705&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ThrottlingMiddleware extends Middleware {

    private int requestPerMinute;
    private int request;
    private long currentTime;

    public ThrottlingMiddleware( int requestPerMinute ) {
    	
        this.requestPerMinute = requestPerMinute;
        this.currentTime = System.currentTimeMillis();
    }

    /**
     * Please, not that checkNext() call can be inserted both in the beginning
     * of this method and in the end.
     *
     * This gives much more flexibility than a simple loop over all middleware
     * objects. For instance, an element of a chain can change the order of
     * checks by running its check after all other checks.
     */
    @Override
    public boolean check(String email, String password) {
    	
        if (System.currentTimeMillis() &amp;gt; currentTime + 60_000) {
        	
            request = 0;
            currentTime = System.currentTimeMillis();
        }

        request++;
        
        if (request &amp;gt; requestPerMinute) {
        	
            System.out.println(&quot;Request limit exceeded!&quot;);
            Thread.currentThread().stop();
        }
        
        return checkNext(email, password);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1606114642196&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class UserExistsMiddleware extends Middleware {

    private Server server;

    public UserExistsMiddleware(Server server) {
    	
        this.server = server;
    }

    @Override
    public boolean check(String email, String password) {
    	
        if (!server.hasEmail(email)) {
            System.out.println(&quot;This email is not registered!&quot;);
            return false;
        }
        
        if (!server.isValidPassword(email, password)) {
            System.out.println(&quot;Wrong password!&quot;);
            return false;
        }
        
        return checkNext(email, password);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;▲ 사용자가 입력한 email / passowrd의 인증 프로세스&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606114655959&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class RoleCheckMiddleware extends Middleware {

    @Override
    public boolean check(String email, String password) {
		
        if (email.equals(&quot;admin@example.com&quot;)) {
            System.out.println(&quot;Hello, admin!&quot;);
            return true;
        }
        
        System.out.println(&quot;Hello, user!&quot;);
        return checkNext(email, password);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #333333;&quot;&gt;▲ 사용자 인증이 끝난 뒤 역할 확인 프로세스&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606114678076&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Server {

    private Map&amp;lt;String, String&amp;gt; users = new HashMap&amp;lt;&amp;gt;();
    private Middleware middleware;

    /**
     * Client passes a chain of object to server. This improves flexibility and
     * makes testing the server class easier.
     */
    public void setMiddleware(Middleware middleware) {
    
        this.middleware = middleware;
    }

    /**
     * Server gets email and password from client and sends the authorization
     * request to the chain.
     */
    public boolean logIn(String email, String password) {
    
        if (middleware.check(email, password)) {
            System.out.println(&quot;Authorization have been successful!&quot;);

            // Do something useful here for authorized users.

            return true;
        }
        return false;
    }

    public void register(String email, String password) {
    
        users.put(email, password);
    }

    public boolean hasEmail(String email) {
        return users.containsKey(email);
    }

    public boolean isValidPassword(String email, String password) {
        return users.get(email).equals(password);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #333333;&quot;&gt;▲ 사용자의 로그인 정보를 가지고 있는 클래스&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606114716331&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Client {

	private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	private static Server server;

	private static void init() {
		
		server = new Server();
		server.register(&quot;admin@example.com&quot;, &quot;admin_pass&quot;);
		server.register(&quot;user@example.com&quot;, &quot;user_pass&quot;);

		// All checks are linked. Client can build various chains using the same
		// components.
		Middleware middleware = new ThrottlingMiddleware(2);
		middleware.linkWith(new UserExistsMiddleware(server)).linkWith(new RoleCheckMiddleware());

		// Server gets a chain from client code.
		server.setMiddleware(middleware);
	}

	public static void main(String[] args) throws IOException {
		
		init();

		boolean success;
		
		do {
			
			System.out.print(&quot;Enter email: &quot;);
			String email = reader.readLine();
			System.out.print(&quot;Input password: &quot;);
			String password = reader.readLine();
			success = server.logIn(email, password);
			
		} while (!success);
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;▶ 실행 결과&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xPjSY/btqNXdsfrW6/iDqb4tsVk8uLVujAfV7RV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xPjSY/btqNXdsfrW6/iDqb4tsVk8uLVujAfV7RV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xPjSY/btqNXdsfrW6/iDqb4tsVk8uLVujAfV7RV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxPjSY%2FbtqNXdsfrW6%2FiDqb4tsVk8uLVujAfV7RV1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Java/Design Pattern</category>
      <category>chain</category>
      <category>Chain of Responsibility</category>
      <category>design pattern</category>
      <category>java</category>
      <author>예은파파</author>
      <guid isPermaLink="true">https://developer87.tistory.com/30</guid>
      <comments>https://developer87.tistory.com/30#entry30comment</comments>
      <pubDate>Mon, 23 Nov 2020 23:05:57 +0900</pubDate>
    </item>
  </channel>
</rss>