심심해서 하는 블로그 :: 'Computer Science' 카테고리의 글 목록
Singleton

싱글톤이란?

하나! 오직 하나!


싱글톤 패턴은 클래스의 인스턴스가 오직 하나임을 보장하는 디자인 패턴이다.

어떤 클래스의 인스턴스를 생성하고 소멸하는 과정이 빈번하게 발생한다면, 고민해도 될 만한 패턴


대표적인 형태 - Eager initialization

public class Singleton{
	// 인스턴스를 Static 생성한다. 
	private static final Singleton instance = new Singleton();

	// private로 선언된 생성자
	private Singleton(){
		System.out.println("Create Instance");
	}

	// 인스턴스를 사용할 때는 이렇게 호출한다.
	public static Singleton getInstance(){
		return instance;
	}
}


싱글톤 패턴을 사용하는 코드에서 나타나는 특징은 크게 세 가지 입니다.


  1. private로 선언된 생성자

단 하나의 인스턴스를 보장하기 위해서, 클래스 외부에서 새로운 인스턴스의 생성을 막아야 하므로 private로 접근을 제어한다.


  1. Static으로 선언된 인스턴스 멤버 변수

일반적으로 우리가 new 를 사용하여 클래스의 인스턴스를 선언하는 방법을 동적 생성이라고 하는데, 이 때는 메모리 구조상 Heap에 위치하게 된다.

Heap에 있는 인스턴스는 메모리 할당과 해제를 거치게 되는데, 이 연산이 많은 사용자들이 사용하는 서버에서 동시에 이루어 진다면, 부하가 될 수 있다.

반면 Static으로 선언된 인스턴스는 최초 클래스 로드시에 메모리에 적재된 후, 계속 메모리에 남게 된다.


  1. 오직 getInstance() 함수로 Instence 접근

이 클래스의 인스턴스를 접근할 수 있는 곳은 오로지 getInstance() 입니다.


위의 세 가지 조건을 만족한다면 클래스의 인스턴스가 1개인 클래스를 생성가능합니다.

이 방법이 가지는 단점은 이 클래스를 사용하든 안하든 항상 메모리 상에 상주한다는 겁니다.

getInstance() 가 실행 되기 전부터 메모리에 상주하여 낭비를 한다는 것이 마음에 썩 들지는 않습니다.

그래서 클래스를 사용할 때 메모리에 인스턴스를 로드하는 방법을 고안합니다.





Lazy Initialization

public class Singleton{
	// 미리 생성하지 않는다.
	// private static final Singleton instance = new Singleton();
	private static Singleton instance = null;

	// private로 선언된 생성자
	private Singleton(){
		System.out.println("Create Instance");
	}

	// 인스턴스를 사용할 때는 이렇게 호출한다.
	public static Singleton getInstance(){
		// 추가!! 최초로 사용할 때 인스턴스를 생성한다.
		if (instance == null){
			instance = new Singleton();
		} 
		return instance;
	}
}


이전 코드와 비교 하기 위해서 주석으로 이전 코드를 남겨 두었다.


  1. 미리 생성하지 않는다.

클래스의 인스턴스를 사용하기 전부터 메모리에 상주하던 방법이 아닌 최초로 사용하는 곳에서 인스턴스를 생성합니다.

getInstance() 함수가 한 번이라도 실행되어야 이 클래스를


  1. 단 하나의 Instance 보장 문제

우연히 같은 시간에 여럭 개의 쓰레드가 getInstance()를 호출된다면, 하나의 인스턴스를

이 경우에 단 하나의 Instance를 보장 가능하다고 말 할 수 없습니다.

아래의 코드는 Thread-Safe 를 붕괴해보는(?) 소스코드 입니다.


import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Runner implements Runnable{
   public static final CyclicBarrier gate = new CyclicBarrier(20);

   @Override
   public void run() {
      try {
         gate.await();
         Singleton s = Singleton.getInstance();
      } catch (InterruptedException | BrokenBarrierException e) {
        e.printStackTrace();
      }
   }

   public static void main(String[] args) {      
      for(int i=0; i<20; i++) {
         Runner broker = new Runner();
         Thread worker = new Thread(broker);
         worker.start();
      }
   }
}


이 소스 코드는 20개의 쓰레드가 동시에 getInstance() 를 실행하는 소스 코드입니다.

실행 결과를 보면 여러 개의 인스턴스가 생성되는 것을 확인 할 수 있습니다.



Lock을 걸어버리자

public class Singleton{
	private static Singleton instance = null;

	// private로 선언된 생성자
	private Singleton(){
		System.out.println("Create Instance");
	}

	// 추가!! Lock을 걸어보자
	public static synchronized Singleton getInstance(){
	// public static Singleton getInstance(){
		if (instance == null){
			instance = new Singleton();
		} 
		return instance;
	}
}


synchronized 로 선언된 영역은 Lock을 걸어 주는 역할을 수행하므로 하나의 쓰레드씩 이 함수를 수행하게 되므로 Thread-Safe 문제를 보완해 줍니다.

하지만 우리가 병렬로 수행하기 위한 목적으로 멀티쓰레드를 쓰는데, synchronized 구간에서 병렬성이 무너지기 때문에 성능저하가 발생할 수 있습니다.






holder에 의한 초기화

public class Singleton{
	// private로 선언된 생성자
	private Singleton(){
		System.out.println("Create Instance");
	}
	
	// Holder Class 추가
	private static class Holder {
		static{
			System.out.println("Holder Class");
		} // Holder 클래스를 메모리에 로드할 때 메세지를 보여주기 위함
		private static final Singleton instance = new Singleton();
	} 	

	public static Singleton getInstance(){
		return Holder.instance;
	}
	// getInstance() 말고 다른 함수를 호출하였을 때 인스턴스 생성 여부 확인용
	public static void print(){
		System.out.println("Singleton.print()");
	}
}


Singleton 클래스 내부에 Holder 클래스를 작성하고 그의 멤버 변수로 Singleton 클래스의 인스턴스를 생성합니다.

앞서 소개한 두 가지 방법에서 발생한 문제점을 어느 정도 보완하는지 체크해 보았습니다.


  1. 사용 전에 미리 생성하지 말 것

getInstance() 호출 전 Singleton 클래스의 인스턴스가 static 맴버 변수로 작성되지 않았으므로 인스턴스가 생성되지 않습니다.

위의 소스코드에서getInstance() 를 실행하지 않고 print() 함수만 실행했을 때 결과를 보면 쉽게 이해하실 수 있을 겁니다.


  1. Thread-Safe 보장

getInstance() 함수가 실행되면 Static으로 선언된 Holder 클래스는 JVM의 Class Loader 에 의해 메모리에 적재됩니다.

Holder는 Singleton 클래스의 인스턴스를 가지고 있으니 Thread-Safe를 붕괴할 수 있는 경우는 Holder 클래스가 Class Loader에 의해 메모리에 적재될 때 중첩되어 Load되는 경우 뿐입니다.

하지만 Class가 초기화되는 과정은 Java Language Specification (JLS)에 의해 시퀀스하게 진행됩니다.

그래서 synchronized로 실행했을 때처럼 Lock을 제공하지만 더 좋은 성능을 보장하는 방법을 제공합니다.


긴 글 읽어 주셔서 감사합니다.

공감 버튼은 작성자에게 큰 동기부여가 됩니다.


,

1. Chocolaty Package Manager

Mac Book의 brew, RedHat 계열 리눅스의 yum, Python의 pip, Debian 계열 리눅스의 apt-get, NodeJS의 npm 등 Package Manager는 개발자들이 Commend Line 상으로 쉽게 Package를 설치하고 Upgrade 할 수 있는 편리한 Tool이다. 


Windows에서 일반적으로 MySQL을 설치하는 순서

1. MySQL 홈페이지로 간다. (구글 - MySQL 설치 검색 - 홈페이지 접속) 

2. MySQL 인스톨러를 다운로드 받은 뒤 실행한다.

3. 모니터를 가만히 쳐다본다.


RedHat 계열 리눅스에서 MySQL을 설치한다면

1. sudo yum install -y mysql

2. 끝



Command Line이 익숙하지 않는다면 직접 홈페이지를 찾아가서 설치하는 것도 좋지만, 리눅스나 Mac OS를 사용하다가 Windows에 환경설정을 하고자 하면, 귀찮다. 매우 귀찮다. 마침 새로운 개발 노트북에 개발 환경을 설정하는 과정에서 혹시 Windows에도 Package Manager가 있을까 했는데, Chocolaty라는 Package Manager가 있었다.


설치 과정  

https://chocolatey.org/install 로 접속하게 되면 PowerShell 또는 cmd로 설치가 가능한 명령어를 제공한다.



Windows PowerShell을 이용해서 밑의 코드를 복사-붙여넣기 후 실행을 하면 혼자서 열심히 동작을 수행한다. 완료가 된 후에 choco라고 명령어를 타이핑했을 때, 아래 그림처럼 버전 정보를 제공하면, 성공적으로 설치가 완료된 것이다. 




패키지 검색 / 설치 / 갱신 / 삭제  

설치가 완료되었으면 한 번 실행을 해보자. Sublime Text를 다운로드하기 위해 우선 Sublime Text가 Choco에 등록되어 있는지 확인하는 절차를 먼저 가진다.  cmd나 PowerShell 실행할 때 관리자 권한으로 실행을 해야 패키지를 정상적으로 설치 할 수 있다. 

choco search sublime



와.. 많기도 하다.  우리는 그 중에서 SublimeText3를 설치해 보자. 

choco install -y sublimetext3


설치가 끝났다. 설치 경로는 C:\Program Files\Sublime Text 3에 설치되어있다. 간혹 C:\tools나 C:\ProgramData 경로에 설치되는 패키지도 있다. Sublime Text 3을 저는 잘 사용하지 않기 때문에, 다시 삭제하도록 하겠다.


choco uninstall sublimetext3 


update나 upgrade를 이용하면 버전을 최신 버전으로도 관리가 가능하다. Windows에서도 이런 툴을 사용할 수 있어서, 나중에 포맷이나 새로운 컴퓨터를 또 얻는다면, Command만 파일에 잘 저장하여, 실행하면 간단하게 개발 환경을 구성할 수 있을 것으로 기대한다.


 



,

정보처리기출_2006~2015.zip

1. 합격했습니다!!





2017년에 지금까지 제가 한 일 중에 가장 잘한 일이라고 생각해요.

직접 서울 공단에 가서 자격증을 수령했습니다. 여권같이 생긴 게 멋있더라고요.

저는 2017년 1차 필기와 1차 실기 시험을 쳤고요. 그동안 공부를 했던 경험들을 떠올리면서 포스팅을 진행할게요

시험을 준비하시는 많은 분들께 도움이 될 수 있었으면 합니다.

(참고로 저는 4학년 소프트웨어학과 전공자입니다)


2. 필기 공부방법

공단에서 2017년부터 정보처리기사 시험의 유형을 다르게 하겠다고 선언했었습니다. 이제 겨우 시험을 칠 자격을 얻었는데 실기는 서술형으로 나온다고 하질 않나.. 필기시험은 어렵게 낸다 하질 않나. 운이 지지리도 없다고 생각했어요. 그래도 4년 동안 대학교에서 공부를 했으니까 어느 정도는 알겠지 했는데, 기출문제를 풀어보니까 막상 그런 건 또 아니더라구요.(이럴려고 4년 공부했나.. 자괴감 들고...)




저 같은 경우에는 자격증 공부를 할 때, 책 없이 하기에는 많이 힘이 들어서 시나공 summary 정보처리기사 필기 책을 사용했습니다. 이 책은 정말 간단한 요약정리와 기출문제들로 구성되어 있어요. 그리고 필기 기출문제 파일을 따로 얻어서 문제를 풀었습니다. 파일로 첨부해 드렸으니까 공부하실 때 요긴하게 사용하세요. 


저는 일단 파일에 있는 기출문제를 2012년부터 2015년까지 출력해서 문제를 풀었습니다. 

프린트한 문제를 풀고 나서, 오답을 체크할 때 summary 책을 이용해서 어떤 개념이 있었는지를 프린트한 기출문제에 다시 적어서 암기를 하고 넘어가는 방법으로 매 회를 진행하였습니다. 


기출문제를 공부하시다 보면 반복되는 문제가 한두 문제씩 나옵니다. 이 문제 같은 경우에는 반드시 꼭꼭꼭 집고 가시는 게 좋습니다. 실제 시험을 치면 생판 처음 보는 문제들도 있지만, 오아시스 같은 이런 문제들이 빈번하게 출제됩니다. 심지어 답도 똑같이 출제되는 경우도 있으니까 과락을 면하기 위해서 반드시 꼭 공부하시길 바랍니다.


보통 필기를 공부하신 분들 후기를 보면 전자계산기 구조 과목과 데이터 통신 과목이 어렵다고 하시는 분들이 많습니다. 저도 또한 저 두 과목이 가장 공부하면서 어렵다고 느낀 점이 범위가 넓고, 외울 게 너무 많습니다.  특히 데이터 통신은 프로토콜을 외우는 게 정말 힘들었습니다. 그래서 복습을 할 때에도 이 두 과목에는 좀 더 신경을 쓰면서 공부를 했습니다. 파트별로 공부를 하시는 분들은 데이터베이스, 운영체제, 소프트웨어 공학을 먼저 공부해서 점수를 끌어올리고 나머지 두 과목에서 과락을 면하자는 목표를 가지고 공부를 하는 게 좋습니다.  먼저 공부하는 3과목의 경우에는 기출 문제에서 반복되는 문제가 많고, 외우는 게 어렵다고  두 과목보다는 적습니다. 


필기시험은 과목당 30분씩 2시간 반 동안 시험을 보고 절반 이상 시간이 지나면 퇴실이 가능합니다. 

수능 과학 탐구영역처럼 30분씩 딱딱 정해서 과목별 시험지를 배부하는 것은 아닙니다. 모든 과목이 있는 시험지를 배부하고 순서도 원하는 데로 푸시면 됩니다. 그리고 시험지는 나중에 집에 가져가실 수 있는데, 시험이 끝나고 6시쯤에 가채점 답안이 공단에서 공시합니다. 그 동안 시험치신 분들이 이의를 제기할 수도 있고, 그게 받아 지는 경우 문제의 답도 달라질 수 있으니. 시험 결과가 나올 때까지 가채점은 그냥 가채점이라고 생각하시면 마음 편합니다. 실제로 제가 친 시험에도 문제에 오류가 있어서 해당 문제에 답이 없다라고 정정되었습니다.



전자 계산기 과목에 조금 더 많이 신경을 쓰다 보니 전자계산기 과목 점수가 높게 나왔어요. 물론 찍은 것도 어느 정도 맞아서 높은 점수가 나왔을 뿐이지 그동안 공부하면서 푼 기출문제의 평균은 60점대 초반을 왔다 갔다 했었어요. 필기는 다시 말씀드리지만 기출문제를 정확하게 푸는 것이 가장 중요하다고 생각합니다.


 3. 실기 공부방법

필기를 무사히 통과하고 실기 준비를 시작했어요. 예전에는 실기도 객관식이고 데이터베이스와 알고리즘을 어느 정도 맞추면 사실상 합격이라 사람들이 저 두 과목만 공부를 하고 합격을 하는 사례가 많아지자 공단에서 싹 다 서술형, 단답식으로 변경하겠다고 공언해 버렸죠.


실기 책도 역시 시나공으로 준비했습니다.

실기는 3시간 동안 시험을 치며, 총 20문제에 합격은 60점이상, 문제마다 배점은 각각 달리되어 있습니다.


알고리즘 - 25점

데이터베이스 - 25점

업무 프로세스 - 15점

전산영어 - 10점

IT 신기술 동향 및 시스템 관리 - 25점 


저는 일단 알고리즘과 데이터 베이스는 무조건 다 맞추겠다고 목표를 세웠습니다. 전공 수업으로 웬만한 것은 풀 수 있고, 신기술 동향이나 전산 영어는 외워야 할 범위가 엄청 많습니다. 거기다가 영어 풀네임을 요구하는 문제가 간혹 있기 때문에 외우기 부담이 되는 경우도 있어요. 이 두 과목은 매일매일 어느 정도 범위를 정해놓고 꾸준히 보는게 중요한 거 같습니다. 시간이 없다면 보안에 관련된 전산 영어를 보고 가시는 걸 추천합니다. 


알고리즘은 C / Java의 입출력문, 연산식, 조건문 등 간단한 문법과 문제를 푸는 방법에 대해서 이해를 하면 충분히 맞출 거라고 생각해요. 데이터 베이스는 쿼리문, 관계 대수, 정규화를 집중적으로 공부했습니다. 알고리즘은 전체 코드를 코딩하는 개념보다는 빈칸에 들어가야 할 코드에 대하여 푸는 문제가 나왔었고, 데이터베이스는 요구하는 사항에 대한 쿼리를 작성하는 문제가 나왔습니다. 


직접 데이터베이스나 컴파일러를 설치해서 실행해 보는 것이 이해하는데 가장 편하겠지만, 이쪽으로 갈 생각 없이 단순히 스펙으로 자격증을 따겠다고 생각하신 분들은 교재에 나온 문제를 모두 풀어보는 것이 좋습니다. 알고리즘과 데이터베이스는 약간의 암기 + 많은 응용을 요구하기 때문에 문제를 많이 풀면서 이해하는 것이 좋습니다.


업무 프로세스는 엄청 긴 지문을 읽고 각각에 해당되는 부분을 찾아 넣는 문제가 나왔는데, 시험 치기 전에 간단하게 몇 문제를 풀어보면 어려움 없이 문제를 해결하실 수 있을 거라 생각합니다. 



서술형으로 변경된 후 처음으로 치러진 시험이라 그런지 1회 난이도는 생각했던 것보다 쉬웠습니다. 답안 채점도 생각보다 후하게 준 거 같아요. 인터넷에 떠도는 가채점 답안으로 채점한 결과보다 높은 결과가 나오면서 무사히 합격했습니다. 시험을 친지 꽤 오래돼서 문제에 대한 기억과 공부한 방법에 대해서 가물가물하긴 해요. 하지만 궁금하신 걸 물어보신다면 답변해 드리겠습니다. 다들 좋은 결과 있으시길 바랍니다. 


도움이 되셨다면 밑에 공감 하트 한 번씩만 눌러주세요. 하트는 저에게 큰 힘이 됩니다.

,

1. LED 회로 구성하기


이전 포스트에서는 NodeJS의 serialport 패키지를 이용해서 아두이노에 연결된 센서의 값을 받아오는 과정을 진행했어요. 이번에는 라즈베리파이의 GPIO에 LED와 버튼을 연결하고 버튼을 누르면 LED가 켜지고 꺼지는 기능을 구현해 보겠습니다. 물론 NodeJS를 이용해서 말이죠!


우선 LED와 버튼 두 개를 이용해서 회로를 간단하게 구현을 해보려구 해요. 버튼 하나는 On 버튼으로 다른 버튼은 Off 버튼으로 사용하면 끄고 켜고 기능을 할 수 있겠죠? 물론 버튼 하나 만으로도 구현이 가능해요. 근데 아두이노나 라즈베리파이에 쓰는 버튼은 한 번 누르면 한번으로 인식하지 않고 여러 번으로 인식해서 그냥 두 개를 씁니다.



그림과 같이 구성합니다. 매번 느끼지만 라즈베리파이의 GPIO에.. 좀.. 아두이노처럼 GPIO 위치를 기판에 새겨 주면 좋겠다는 생각을 매번 해요. 지금은 아무 코드도 작성하지 않았으니까, 버튼을 눌러도 아무런 반응이 없을 거예요. 이제 코드를 작성해서 버튼에 따라서 LED가 켜지고 꺼지도록 만들어 볼게요!!


2. onoff 패키지 사용하기


라즈베리파이로 프로젝트를 진행하는 사람이 많아져서 그런가요?? 이런 패키지들이 생각보다 많네요. 

우선 onoff 패키지를 설치합니다. 프로젝트 파일들이 있는 경로에서 아래와 같이 명령어를 입력합니다.


npm install onoff --save


설치가 완료된 후 이제 소스코드를 작성해 봅시다. LED는 18번에 ON 버튼은 24번, OFF 버튼을 23번에 연결한 후 작성된 코드입니다. 여러분이 하실 때에는 연결하신 번호대로 작성해주시면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// GPIO : LED 제어 부분
var GPIO = require('onoff').Gpio,
    LED = new GPIO(18'out'),
    ON_sw = new GPIO(24'in''both'),
    OFF_sw = new GPIO(23'in''both');
 
ON_sw.watch(function(err, state){
         if(state == 1){
                 LED.writeSync(1);                               
         }
});
 
OFF_sw.watch(function(err, state){
         if(state == 1){
                 LED.writeSync(0);
         }
});
 
 
 
cs


작성을 한 후 실행을 하면 파란 버튼을 누르면 불이 꺼지고 빨간 버튼을 누르면 불이 켜지는 걸 확인했습니다. 

스마트 스위치 같은 것을 실습하는 데에 좋은 패키지가 아닐까 생각합니다.





,

1. 아두이노 - 센서 조립


요새 설계과목에 제출할 과제로 스마트 스위치를 만들고 있어요. 라즈베리파이2랑 아두이노, 조도센서를 이용해서 날이 너무 밝으면 불을 꺼주고, 날이 너무 어두우면 불을 켜주는 기능을 만들고 있는데 그러려면 아두이노에서 센서 값을 받은 다음 라즈베리파이로 전송하는 과정이 설계상 필요하더라고요. 라즈베리파이2가 웹서버로 NodeJS를 사용하고 있는데 설마.. 시리얼 통신 패키지도 있나 했더니.. 정말 있네요.. node.. 당신은 도대체..


개발 보드 : 아두이노 나노, 조도 센서, 라즈베리파이2

OS : 라즈베리안 OS

언어 : NodeJS

(굳이 위의 개발보드와 OS가 아니더라도 가능합니다. 저도 Window에서 Test 후 파이로 옮겨서 수행했습니다.)



우선 조도 센서를 아두이노와 연결해요. 조도 센서는 TEMT6000 센서를 사용했습니다.

VCC - 5V, GND - GND, OUT - ANALOG 중 하나에 점핑 선을 연결해줍니다. 

아두이노 나노는 A0, A1 등등 A로 시작하는 곳이 ANALOG에요.

다른 조도 센서를 사용하시는 분이라면 제품 번호를 확인하시고 연결하세요. 



그리고 아두이노를 라즈베리파이에 USB 선을 이용해서 연결해줍니다. 그 후 SSH로 접속한 후  dmesg | tail 명령어를 입력해 USB 포트 번호를 확인합니다. 저는 ttyUSB0에 아두이노 나노가 있다고 하네요. 



Windows 환경이나 리눅스 쉘 커맨드에 익숙하지 않다면 연결 후 아두이노 스케치를 실행해서 USB 포트 정보를 확인할 수도 있습니다. 마찬가지로 ttyUSB0에 연결되어 있음을 알 수 있죠. 이 정보는 이어서 소개할 serialport 패키지를 사용하는데 필요하니까 반드시 알아 두시는 게 좋아요!!


2. serialport 패키지 사용하기


serialport는 웹서버로 주로 사용하는 NodeJS에서 센서 값을 읽고 기기를 제어할 수 있게 하는 패키지에요!!

우선 nodeJS 프로젝트를 만든 후 해당 경로에서 리눅스 명령어 쉘(Windows에서는 cmd) 아래의 명령어로 serialport 패키지를 설치합니다. 


npm install serialport --save


설치가 완료되면 자바 스크립트 파일을 하나 만든 후 아래와 같이 코드를 작성해 봅시다.


1
2
3
4
5
6
7
8
9
10
11
var SerialPort = require('serialport'),
      portName = '/dev/ttyUSB0',
      sp = new SerialPort(portName),
      sensorVal = 0;
 
sp.on('open'function(){
    console.log('Serial Port OPEN');
    sp.on('data'function(data){
        console.log("Light Sensor Value : ", data[0]);
});
}); 
cs


시리얼 포트를 통해 아두이노에서 송신된 데이터를 수신하는 코드에요. 성공적으로 수신하면 화면에서 조도 센서 값을 읽을 수가 있어요. 그리고 이제 아두이노 스케치를 이용해서 아두이노에서 시리얼 통신으로 센서 값을 보내는 코드를 작성해 봅시다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void setup()
{
  // 전송 속도를 설정해줍니다.     
    Serial.begin(9600); 
}
void loop()
{
    int val;
 
    // 조도 센서의 측정된 값을 읽어옵니다. 
    // 센서에 연결한 아날로그 포트 번호를 매개변수로 지정합니다.
    // 저는 A1에 연결하였으므로 1번을 사용했습니다.
    val = analogRead(1);         
    
    // 조건문은 무시하셔도 됩니다. 
    // Serial.write(val)을 통해 시리얼 통신을 한다는 점만 기억하시면 됩니다.
    if(val > 40)
        Serial.write(val);    
    else if(val < 5)
        Serial.write(val);    
     
    delay(1000);
}
 
 
cs



센서 값을 시리얼 통신을 통해서 성공적으로 전송받을 수 있는 것을 확인하였습니다. 다시 말씀드리지만 이것은 NodeJS를 이용해서 작성된 코드입니다. 물론 NodeJS 외에도 다른 언어를 이용해서 라즈베리파이와 아두이노 간의 시리얼 통신이 가능합니다. 


도움이 되셨나요?? 아래에 하트 버튼은 저에게 큰 힘이 됩니다. 즐거운 하루되세요!! 

,

1. Overview

접근제어(Access Control)란??

접근제어는 자원에 대한 권한이 없는 주체(Subject)가 해당 자원의 사용을 막는 것을 의미한다.

접근제어를 하기 위해서 주체를 구별하기 위한 Identification과 본인 여부를 확인하는 인증 절차가 필요하다.

특히 인증의 성공 여부에 따라 리소스에 접근할 권한을 줄지 안 줄지 결정되므로 인증이 핵심 절차이다.


주체(Subject)는 컴퓨터를 사용하는 사람, 그룹, 프로세스, 컴퓨터와 같이 정보를 요청하는 요소이며,

객체(Object)는 파일이나 폴더, 디바이스, 메모리 등 정보를 가지고 있는 요소이다. 

주체는 접근 권한에 따라 객체를 읽거나, 쓰기, 실행이 가능하며 권한은 객체별로 다른 형태로 부여한다.


요구사항

- 신뢰가능한 입력(reliable input) : 신뢰가능함은 인증을 통과한 주체가 행하는 입력을 의미한다.

- 포괄적 vs 세분화 : 권한의 범위를 어느 수준까지 설정하는가 문제

- 최소 권한 : 주체에게 너무 큰 권한을 부여하면 시스템의 문제의 여지가 될 수 있다.

- 열린 정책 vs 닫힌 정책 / 정책 간 충돌 문제

- 정책 관리 : 관리자만이 정책을 변경할 수 있다.

- 동시성 제어 : 하나의 객체에 여러 주체가 동시에 접근할 경우 어떻게 처리할지 문제

- 의무의 분리 : 중요한 행위는 반드시 두 개이상의 user나 권한으로 나누어서 실행한다.


2. DAC(Discretionary Acess Control)

주인장 맘대로

자원의 주인이 해당 자원에 대한 다른 사람들의 권한을 결정하여 접근 제어를 하는 방법이다.

따라서 이 방법을 사용하기 위해서 각자를 구별할 ID와 해당 자원의 소유권, 그리고 다른 유저에게 분배된 권한을 정리할 파일이 필요하다. 권한을 저장하는 방법은 Access Control List, Capability List, Access Matrix가 있다. Access Matrix의 경우에는 사용자가 많고 자원들이 많은 실제 상용 시스템에서 사용하면 공란이 많은 희소 행렬의 형태라 공간 낭비가 심해 사용하지 않는다.




Access Control List vs Capability List

ACLs는 자원에 대하여 각 사용자들의 권한을 저장하는 방법이고 CL은 반대로 사용자에 대하여 각 자원들의 권한을 저장하는 방법이다. 다시 말해 ACLs는 자원 중심, CL은 사용자 중심의 저장 방법이다. 따라서 사용자에 비해 자원이 많은 개인용 PC 같은 환경에서는 ACLs, 사용자의 수가 많은 웹 서버같은 환경에서는 CL이 더욱 유용한 방법이다. 


DAC 장점

- 사용자가 접근 권한을 관리 할 수 있어서 보안 관리자가 업무가 줄어 든다.

- 권한을 수정이 쉽고 새로운 권한을 적용하기 쉽다.


DAC 단점

- 위의 그림처럼 권한을 부여한 사용자의 의도하지 않은 대로 정보가 흘러갈 수 있다.

- 루트의 권한이 너무 강력하다. 

- 주체와 객체의 수가 증가한다면 복잡해지고 크기가 커지는 문제도 있다.

- 소유자를 쉽게 변경이 가능하다는 점을 악용한 프로그램들도 많다 



Unix / Linux의 파일 시스템

리눅스의 파일 시스템의 정보는 inode 저장된다. inode에는 하나의 파일 또는 디렉터리의  UID, GID, 소유권이 명시 되어있으며 12개의 비트로 특수권한 / 읽기 / 쓰기 / 실행 권한을 표기한다. 이 inode들은 디스크 상에 inode 테이블이나 리스트에 저장이 되어진다. 그리고 파일을 열면 해당 파일의 inode는 메인 메모리에 상주하는 inode 테이블에 저장된다. 


DAC 취약점 실습


위 그림은 file1의 소유주 csos가 user1에게 읽기 권한을 부여하는 과정이다.


리눅스에서 setfacl 또는 chacl 명령어로 파일 시스템 상의 ACL을 변경할 수 있고 getfacl 명령어로 해당 파일의 ACL정보를 확인 할 수 있다. 파일의 소유자의 UID, GID 정보와 각 사용자와 그룹에 대하여 권한, 마스크 정보도 추가된 확장된 ACL을 사용한다는 것을 알 수 있다. 파일 시스템에 접근하는 경우 파일의 ACL을 확인하여 소유자 -> 지정한 유저 -> 그룹 -> 외부자로 순으로 연산 처리한다.



user1으로 접속을 변경하고 csos가 읽기 권한을 준 file1을 복사하여 user1의 영역으로 복사하였다. 이제 user1은 file1의 사본 file2의 소유자이므로 file1에 대한 모든 권한을 행사할 수 있다. 이처럼 DAC는 원 소유자 csos의 의도와 다르게 흐름을 변경할 수 있는 취약점이 있다.

,

1. ISAM 트리구조

정적 트리구조

삽입 / 삭제를 하여도 트리의 구조가 변화하지 않는 것이 특징이다. 만일 페이지에 더 이상 데이터를 추가할 수 없다면 오버플로우 페이지를 생성하여 마지막 리프노드에 체인으로 연결하여 추가한다.


오버플로우 페이지

위의 그림 왼쪽 트리 구조에서 7을 삽입하는 연산이 수행한다고 가정하자. 루트에서 시작해서 리프 노드에 도달하면 7이 들어갈 노드가 (6*, 9*)로 채워져 들어갈 공간이 없다. 이때 ISAM 트리 구조는 트리의 구조를 변형시키지 않고 아래에 7이 들어갈 수 있는 공간을 만든 후 다음 7을 삽입한다. 이 때 새로 만들어진 이 공간을 오버플로 페이지라고 한다. 


오버플로 페이지를 생성함에 따라서 얻을 수 있는 이득은 오버플로가 발생하는 경우 삽입 / 삭제 연산이 B+ 트리보다는 빠르다는 점이다. 아래에 설명할 B+트리는 동적 트리구조로 만약 위의 그림과 같은 상황이 발생하면 트리 구조를 변형을 하여 삽입을 시도하기 때문이다. 또한 Lock을 거는 경우 트리의 내용물에는 변화가 없기 때문에 리프 노드에만 Lock을 걸면 된다. 하지만 오버플로 페이지가 많이 발생할수록 위 그림에서 눈치챘을지도 모르지만 데이터를 물리적으로 정렬하지 않기 때문에 데이터를 탐색하는 속도는 늦어어진다는 단점이 있다.


2. B+ 트리구조

적 트리구조

ISAM 트리와 달리 삽입 / 삭제시에 트리구조가 변화가 발생하는  특징이 있다. 또한 Root 노드를 제외한 나머지 노드들은 데이터를 반드시 절반 이상 점유해야 하는 필수 조건이 있다. 



삽입 연산

위의 트리에서 8을 삽입한다고 가정하자. 8은 L2에 삽입되어야 하지만 현재 노드가 꽉 차있어서 삽입을 할 수 없다. B+ 트리는 오버플로 페이지를 생성하지 않고 L2를 쪼개서 새로운 노드를 만드는 방법을 사용한다. 8을 포함한 L2의 구성 요소 (5,6,7,8,9) 중 중간 값인 7은 상위 단계 노드로 Copy up 되고 트리구조의 특징상 기존의 L2(5,6,7,8,9)는 L2(5,6), L3(7,8,9)로 갈라지게 되어 아래 그림과 같이 된다.



따라서 삽입 연산 중 리프 노드에서 오버플로가 발생하면 B+트리는 해당 노드의 중간 값이 상위 노드로 Copy up 하는 과정이 발생한다. 만일 Copy-up 과정에서 상위 레벨 노드마다 오버플로가 발생한다면 어떻게 트리구조가 변화할까?



위의 그림과 같은 트리에서 15가 삽입된다고 가정하자. 15가 삽입될 노드는 L4인데 L4가 가득 차있으니까 아까 위에서 Copy up을 시도한다. L4(13,14,15,16,18) 중에서 중간 값인 15가 상위 단계 노드로 Copy up이 되려는 순간 상위 노드가 꽉 차있다. 따라서 상위 노드도 분열이 되어야 하는데 이 과정에서 분열된 상위 노드들을 연결할 새로운 루트 노드가 필요하다.  상위 노드의 값 (5, 7, 13, 15, 20) 중 중간 값인 13이 한 단계 상승한 Push up 과정이 발생하고 나머지 (5,7) (15,20)이 다음 노드로 연결되는 아래 그림과 같은 트리구조로 변화한다.



기존 트리의 높이는 1이였지만 삽입의 결과로 높이가 2로 변화하였다. B+트리는 이처럼 트리의 구조를 유지하기 위해서 Copy up / Push up 알고리즘을 사용하고 경우에 따라서 트리의 높이가 변화할 수도 있다.


삭제 연산

삭제 연산에서 가장 중요한 키워드는 루트를 제외한 각 노드는 점유율을 항상 50%이상 유지한다는 점이다. 만약 50프로가 안된다면 인접한 노드에서 빌려온다. 그런데 빌려 오니까 인접 노드도 점유율 50%를 만족하지 못한다면 인접 노드와 병합하는 방법으로 점유율 50%를 유지한다.


 

위 그림(아까 삽입한 결과)에서 24*를 삭제하는 연산을 수행한다고 하자. L6은 이제 데이터가 (21*)만 존재하게 되어 데이터의 점유율이 50프로 미만이 되어버렸다. 따라서 인접 노드인 L5에서 데이터를 (18*)를 빌려온다. L5도 (15*, 16*)을 가지고 있고 L6도 (18*, 21*)로 50프로를 유지할 수 있으므로 L6의 최솟값 18*을 상위 노드에 20*으로 Copy up 하는 것으로 마무리한다. 결과는 아래의 그림과 같다.



이번에는 L1의 1을 삭제한다고 가정하자. 1이 삭제된 L1은 (2*)만 남아 50프로를 유지할 수 없고 인접 노드 L2의 5*를 빌려서 채울려고 하지만 그렇게 진행하면 L2도 (6*)만 남아 점유율 50프로를 만족하지 못한다. 따라서 L1과 L2는 합병이 된다.



합병을 하고 상위 노드 I1의 5*를 삭제하니 I1도 50프로를 만족하지 못한다. 인접 노드 L2에서 데이터를 하나 빌릴려고 하니 연산 결과 L2도 50%를 만족하지 못한다. 따라서 합병을 해야하는 상황이 발생한다. 



합병을 할 때 상위 노드의 값은 한 단계 내려와 Pull down되어 I1, I2와 함께 합쳐진다.  그 외 여기서 다루진 못했지만 만약 I1이 데이터가 4개 있고 삭제당한 I2의 데이터가 1개 있다면 합병하게 되면 5개가 돼버려서 오버플로가 발생하는 경우가 있다. 이 경우에는 재분산(Re-distribution)을 사용하여 2개 / 3개로 다시 나누어 주는 과정이 있다. 기존의 트리의 높이는 2였지만 모든 삭제 연산을 수행한 후에 보면 높이 1의 트리로 변화하였다. 


트리 구조를 유지하면서 이득 / 손해

우선 이득은 데이터 탐색 속도가 ISAM보다 빠르다. 오버플로 페이지가 발생하지 않고 데이터가 삽입되면 그 데이터를 물리적으로 정렬하기 때문이다. 대신 삭제나 삽입의 경우 트리 구조를 유지해야 하는 면에서 ISAM에 비하면 복잡한 과정이 있기 때문에 비용이 좀 더 드는 손해는 있다. 하지만 인덱스를 사용하는 이유는 탐색 속도의 향상이므로 대부분 상용 DBMS에서는 B+ 트리를 사용하여 인덱스를 만든다.

,

1. Rainbow Table attack

답지를 들고 있단다.

앞서 비밀번호는 대부분 해시함수를 사용하여 그 결과 값을 데이터베이스에 저장한다고 했다. 따라서 복호화가 불가능한 상태라 평문(비밀번호)의 내용을 관리자한테까지 숨길 수 있는 장점을 가지고 있다. 이에 따라 공격자들은 사전에 해쉬함수에 입력한 값과 해쉬 결과 값을 저장한 일종의 정답지(Rainbow Table)를 가지고 비밀번호를 확인 할 수 있게 되었다. 이런 공격 우연하게 같은 비밀번호를 사용하는 경우에 여러 계정이 동시에 피해를 볼 수 있는 단점이 있다. 따라서 이 공격에 대안으로 Salted hash가 등장하였다.


2. Salted hashed

양념을 촵촵촵

기존에는 패스워드만 해시함수에 통과시켰으나 최근에는 가입 시간이나 난수(Random Number)를 비밀번호와 같이 해시 값에 포함한다. 이 때 추가적으로 포함된 가입 시간이나 난수를 Salt라고 한다. 치킨에다가 양념을 어떤 것을 사용하냐에 따라 맛이 달라지 듯이 서로 다른 계정이 같은 비밀번호를 사용하더라도 Salt가 다르면 완전 다른 해시 값이 달라지며, 설령 같은 해시 값을 같더라 하여도 Salt 값이 전혀 다르기 때문에 평문을 유추하기 힘들다. 이 Salt는 해쉬 결과 또는 Salt 평문을 패스워드 관리 테이블에 같이 보관한다.


Salted hash의 경우 Salt의 길이가 길면 길수록 무차별 대입공격이 강력하다. OpenBSD는 Blowfish라는 블록 암호화 기법을 가지고 있으며 128bit의 Salt를 사용하여 192비트의 해시 값을 만들어 낸다.


시간을 끌자

해시 함수는 암호화보다 소요하는 시간이 짧다. 따라서 암호문을 무차별 대입으로 푸는 것보다 해시함수에 무차별로 대입하는 것이 소모하는 시간이 짧아 이 시간을 늘려야 할 필요성이 있다. 이에 따라 개발자들은 해시함수를 1000번이상 반복으로 실행하여 고의적으로 시간을 늦추려 하고 있다. 


3. Bloom Filter

사용자 교육의 한계

뉴스에서 보안 사고가 발생하여도, 청개구리 같은 사용자들이 많다. 비밀번호를 길고 자연어 사용을 제한하고 취약한 비밀번호 사용을 금지해도 외우기 귀찮고 손에 안 익는 비밀번호를 사용하기 싫어서 무시하고 사용하며, 일정 주기마다 비밀번호를 변경하라는 메세지가 뜨면 "다음에 할게요~ㅎㅎ" 하고 그냥 넘어가 버리는 경우도 많다. 따라서 말 안듣는 사용자를 교육시키기보다 애시당초 시스템에서 보안이 취약한 비밀번호에 대하여 거절을 하게 만든다.


너만 갖고 있냐?? 나도 갖고 있어!!

Rainbow Table은 공격자도 가질 수 있지만, 개발자들 또한 해당 테이블을 가질 수 있다. 따라서 개발자들은  
사용자가 회원가입할 때 Rainbow Table에 있는 비밀번호에 대하여 사용을 금지하는 방법을 선택하는데 이러한 과정을 Proactive Password Checking이라 하며 금지된 비밀번호를 걸러 내는 필터를  Bloom Filter라고 한다. 이 방법을 사용하면 사용자는 취약한 비밀번호를 사용이 금지되어지며 공격자가 가지고 있는 패스워드 사전도 취약하게 된다. 설령 공격자가 갱신을 한 패스워드 사전을 가지고 있다 하여도 개발자가 해당 사전을 역시 수집이 가능하므로 금지 비밀번호를 갱신하면 된다.


,

Brute Force Attack

무차별 대입 공격은 사용자가 입력할 수 있는 모든 글자에 대하여 하나하나 대입을 하면서 비밀번호를 풀어 내는 방법이다. 예전에 여자친구가 아이폰 백업 비밀번호를 잃어 버린적이 있어서 풀어주기 위해 툴을 사용한 적이 있는데 대부분의 툴들은 무차별 대입공격을 기반으로 한다. 특수문자와 영어 대소문자, 숫자로 구성된 비밀번호 9자리를 푸는데 요구되는 시간이 1030년이라고 뜬 적이 있다. 이처럼 무차별 대입공격에 강한 비밀번호가 되기 위해서는 비밀번호를 길고 복잡하게 만들어야 할 필요가 있다. 최근에는 빠른 연산이 가능한 GPU와 멀티 쓰레드처럼 병렬처리를 사용하여 시간을 단축하는 기법도 사용한다.


Dictionary Attack

비밀번호 크랙툴 중에 기본적으로 사전 공격이 있는 툴도 있는데. 공격자가 무차별 대입 공격에서 시간이 많이 걸리는 점을 우회하기 위해서 착안한 방법이다. 이 사전 공격은 공격자가 대부분의 사람들은 자연어를 이용하여 비밀번호를 만든다는 점과 사람들이 자주 사용하는 비밀번호 정보를 수집하여 사전으로 만들고 그 사전의 단어를 기반으로 대입을 하여 비밀번호를 푸는 방법을 말한다. 이 방법을 사용하면 무차별 대입공격보다 한참 적은 시도로 비밀번호를 크랙할 수 있는 장점이 있다. 


Rainbow Table Attack

비밀번호는 대부분 암호화 해시 함수를 사용한 결과 값을 데이터베이스에 저장이 된다. 해시 함수는 일방향 함수로 암호화 과정만 있고 복호화 과정이 없는 특징이 있어서 해당 값을 복호화하는 것은 불가능하다. 하지만 공격자가 해시함수에 다양한 값을 입력하여 얻은 해시 값들을 정리해놓은 테이블(Rainbow Table)이 있다면 해당 데이터 베이스에서 비밀번호를 알아 낼 수도 있다. 또한 우연하게 같은 비밀번호를 사용하는 사람들이 있다면 데이터 베이스에 저장된 해시 값이 같으므로 하나의 비밀번호를 크랙하는 동시에 여러 계정이 폭발하는 문제도 발생할 수 있다.


Exploiting multiple password use

워낙 많은 사이트와 SNS가 있다보니 같은 아이디에 같은 패스워드를 사용하는 경우가 많다. 따라서 만약 하나의 사이트의 아이디, 패스워드가 크랙이 되면 연쇄적으로 다른 사이트도 피해를 볼 수 있다. 가급적 비밀번호를 사이트 마다 다른 것을 쓰는 것을 권장하는 이유다.  


Workstation hijacking

PC방에서 컴퓨터를 켜놓고 잠깐 자리를 비운사이 아직 로그인되어 있는 사이트에 공격자가 앉아서 공격을 하는 방법. 

(좀 성격 안 좋은 형님들이 동생들이 자리 비운 사이에 아이템을 다 팔아버리거나 버려버리는...)

자리를 비우는 경우에는 화면보호기나 컴퓨터를 끄고 가는 것이 좋다.


Exploiting User Mistake

간혹 로그인할 때 아이디를 입력하는 곳에 비밀번호를 입력하여 로그인 버튼을 누르는 경우가 있는데, 로그나 암호화 되지 않은 패킷을 캡쳐하여 비밀번호를 획득할 수 있다. 


개인정보가 들어 있는 비밀번호 사용

주변에 이런 비밀번호 쓰는 사람이 많다. 외우기 귀찮고 까먹을 까봐 자신의 이름을 그대로 사용하거나 생년월일, 전화번호 등등을 사용하여 비밀번호를 사용하는 건데 공격자가 공격할 대상에 대한 정보를 입수하여 사전에 넣고 비밀번호를 크랙할 수도 있으니 사용하지 말 것을 권장한다.


Phishing

보안 카드의 번호를 전부 다 입력하라, 주민등록번호를 말해달라, 비밀번호를 말해달라 등 컴퓨터적인 기술을 이용한 것이 아니라 사회 공학적인 요소를 활용하여 상대방을 속여서 비밀번호 등을 획득하는 방법. 때로는 카페이나 도서관 등에서 대화하는 내용을 수집하여 개인정보를 획득하고 비밀번호를 얻는 방법도 있다.  


Shoulder attack

가장 비밀번호를 뺏기 쉬운 방법. 지하철이나 PC방 등 사람 많은 곳에서 비밀번호를 작성하고 있는 사람 어깨너머로 비밀번호를 훔쳐보는 방법... 비밀번호 입력할 때 주변을 잘 살펴보자.




'Computer Science > Computer Security' 카테고리의 다른 글

[접근 제어] Overview & DAC  (0) 2016.11.30
[보안] Salted hash / Bloom Filter  (0) 2016.10.23
사용자 인증 / 식별  (0) 2016.10.22
[보안] 암호화 & 해시함수  (0) 2016.10.14
[버퍼 오버플로우] 개요  (0) 2016.10.03
,

1. 필요성

사용자 식별의 필요성

회원가입 과정을 생각해보면 ID 중복 체크를 반드시하여 중복되는 ID에 대한 사용을 금지하는 과정을 쉽게 볼 수 있을 것이다. 왜냐하면 멀티 유저 시스템에서는 각각 유저들에 대한 권한이 다르게 설정되어 있기 때문에 사용자간의 식별을 위해서 중복을 피한다. 예전에는 영문과 숫자 조합의 아이디를 사용하였지만 최근에는 이메일이나 휴대전화번호도 중복이 되지 않는 점을 착안하여 아이디로 사용하기도 한다. 


사용자 인증의 필요성

이제 아이디를 정상적으로 만들어 회원가입을 한 후 해당 사이트에 로그인을 하고자 한다. 아이디를 입력하고 우리는 비밀번호를 입력한다. 비밀번호로 나 자신이 해당 계정의 주인임을 인증하는 것이다. 식별과 비슷한 이유로 사용자 간의 권한은 서로 다르기 때문에 해당 권한을 사용할 사람이 맞는지 아닌지를 입증을 할 필요가 있다. 


2. 인증 방법의 분류

Something you know

당신만이 알 수 있는 내용으로 사용자를 인증하는 방법이다. 대표적으로 Password나 Pin이 있으며, 간혹 비밀번호나 아이디를 찾고자 할 때 "당신이 가장 소중하게 여기는 것은?"이라는 질문을 하는 경우도 해당한다. 

이 방법의 장점은  주인이 분실하거나 유출이 의심될 때 쉽게 비밀번호를 변경을 할 수 있다는 점이다. 그에 반해 단점은 본인이 아닌 다른 사람이 해당 비밀번호를 알고 있다면 쉽게 접속하여 권한을 남용하여 시스템에 해를 입힐 수 있다. 따라서 비밀번호를 인증으로 사용하는 경우에는 저장할 때 암호화 해시를 사용하는 등 비밀번호의 보관에 신경을 더욱 쓸 필요가 있다.


Something you have

은행에서 공인 인증서를 발급 받으면 보안카드나 OTP를 발급 받을 수 있다. 또는 회사에 입사하면 사원증을 발급 받는데 그것을 이용하면 회사의 입구에 카드를 대어 사원을 인증하는 경우도 본 적이 있을 것이다. 

이처럼 개인이 가지고 있는 것으로 인증을 하는 방법도 있다. 이 방법은 해당 기기를 분실 / 도난 당하지 않는다면 안전하게 개인을 인증할 수 있는 장점이 있다.


Something you are

요즘 최신 스마트폰에 내장된 지문 / 홍채 인식처럼 생채정보를 활용하여 인증을 하는 방식이다. 사용자만이 가질 수 있는 것을 이용하기 때문에 해당 사용자만이 사용할 수 있는 장점이 있어 강력하지만 만약 유출이 되어진다면 변경이 불가능하다. 일반적으로 홍채의 경우가 가장 정확성이 뛰어나지만 비용적으로 아직 비싼 기술이다.


바이오 인증 과정은 우선 사용자는 자신의 신체 특징(지문, 홍채)을 입력하면 컴퓨터에서 특징점을 분석하여 데이터베이스에 저장한다. 사용자는 인증이 필요한 경우 해당 인식기에 자기의 지문, 홍채 등을 입력하면 데이터 베이스에 저장된 특징점과 입력된 특징점을 비교하여 해당사람이 맞는지 아닌지를 인증한다. 수사와 같이 특수한 경우에는 데이터 베이스에 범죄자로 추정되는 지문을 입력하여 특징점과 데이터베이스 내부의 모든 데이터와 특징점과 비교하여 해당 사람이 누구인지를 확인하는 절차를 가진다.


Something you are/not

최근에 나의 페이스북이 내가 사는 곳이 아닌 엉뚱한 곳에서 접속을 한 이력이 있다고 페이스북에서 경고메세지를 보내 주었다. IP나 Mac Address로 평소에 접속하는 곳이 아닌 엉뚱한 곳에서 접속하는 경우 당신이 맞는지 아닌지 확인을 해주는 기능이 페이스북에 있었나보다.. 이처럼 사용자의 Mac 주소나 IP 주소로도 인증이 가능하며 이 경우는 이동이 잦은 경우에는 IP주소가 달라지고 다양한 기기를 사용하면 Mac 주소의 변별력이 떨어지므로 이동을 하지 않거나 해당 디바이스가 고정된 경우에 사용하는 것이 좋다.


3. 스마트 카드

Memory 카드

Memory 카드는 데이터를 저장할 수는 있지만 연산이 불가능한 카드다. 일반적으로 카드의 자기선이나 내부의 메모리 칩에 데이터를 저장되어 있으며 카드를 사용할 때 비밀번호를 입력하는 것으로 보안을 강화한다. 우리가 은행에서 사용하는 신용카드가 이와 같은 형태를 가지고 있으며 비밀번호 4자리를 사용하는 대신 입력의 횟수를 제한하여 무차별 대입 공격을 방지한다.


스마트 토큰(OTP)

데이터의 저장 뿐만 아니라 마이크로프로세서가 내장되어 있어 연산이 가능하다. 일반적으로 키패드와 함께 있어 키패드로 비밀번호를 입력하면 내부 연산으로 One Time Password(OTP)를 생성하여 디스플레이에 보여준다. OTP는 임시적인 비밀번호로 한번 사용하게 되면 Dynamic Password Generator에 의해 새로운 일회용 비밀번호를 생성하는 방법인 Challenge-response를 사용한다. 


스마트 카드

스마트 토큰의 기능과 메모리 카드의 기능을 한 카드에 모은 것이 스마트 카드이다. 메모리가 있어서 데이터를 저장할 수 있으며 프로세서가 있어서 연산에 가능하며 입출력장치도 가지고 있다. 메모리는 카드의 유통기한동안 바뀌지 않는 데이터를 저장하는 ROM, 어플리케이션 데이터와 프로그램을 가지고 있는 EEPROM, 어플리케이션이 수행할때 임시적으로 데이터를 생성하는 RAM을 가지고 있다.



,