1. 애플리케이션 보안

인증과 인가

인증

사용자가 누구인지 확인하는 것

인가

해당 리소스에 대한 접근 허가의 문제

서버에서 모든 요청과 인증에 대해 인증과 인가 작업을 수행해야 하는데 Spring Web MVC로 개발할 때는 Controller로 요청이 전달되기 전에 HandlerInterceptor로 우리가 원하는 코드를 먼저 실행할 수 있고 Spring Security를 사용하면 SecurityFilterChain을 통해 우리가 원하는 코드를 먼저 실행할 수 있다.

HTTP Stateless

  • stateless: 서버가 클라이언트의 상태를 보존하지 않는 것으로 여러 서버를 운영해도 항상 같은 응답을 받을 수 있다.

    • 장점: 서버 확장성이 좋다.

    • 단점: 클라이언트가 매 요청마다 추가 데이터를 전송해야 한다.

  • stateful: 서버가 클라이언트의 상태를 보존하는 것으로 sticky session같이 항상 동일한 서버로 보내주는 로드밸런서가 필요하다.

    • 장-단점: stateless와 반대된다.

가장 오래되고 잘 알려진 것으로 간단하고 브라우저에 의해 잘 지원된다. 하지만, 4kb의 데이터 제한이 있고 민감하지 않은 사용자의 선호 통계등의 저장에 쓰인다.

document.cookie = "name=tutorialsPoint";
let user = document.cookie.getItem("name");

이렇게 사용 가능하다.

Session storage

쿠키와 비슷하지만 현재 세션에만 저장된다. 유저가 브라우저를 종료하면 함께 삭제된다는 의미로 로그인 인증 같은 민감한 정보의 저장에 쓰인다.

웹 어플리케이션에게 사용자의 브라우저에 데이터 저장을 할 수 있게 해주는 웹 스토리지로 세션 스토리지에 저장된 정보는 해당 사이트에 특정되서 다른 사이트와 공유되지 않는다. HTML5에 새로 소개된 기능이다.

로컬 스토리지와도 비슷하지만

  • Session Storage는 오직 만들어진 사이트에서만 사용 가능하다.

  • 다른 사이트와 공유되지 않는다.

  • 영속적이지 않다.

  • 해당 탭에서만 유효하다.

sessionStorage.setItem("name", "tutorialsPoint");
var name = sessionStorage.getItem("name");

Local Storage

비교적 가장 최근의 개념으로 더 많은 정보의 저장이 가능하고 브라우저를 종료해도 데이터가 삭제되지 않는다. 오프라인 데이터 같은 사용자가 나중에 엑세스 해야 하는 데이터를 저장하는데 유용하다.

username, 주소, preference setting 같은 인풋을 서버에 보내 저장할 수도 있지만 사용자의 컴퓨터에 저장하는 방법이 local storage다.

기본 데이터 저장은 key/value 쌍으로 이루어지며

localStorage.setItem('key', 'value');
localStorage.getItem('key');
localStorage.removeItem('key');

이렇게 사용 가능하다.

Interceptor vs Filter in Spring

Filter

Filter는 웹 서버의 일부분으로 스프링 프레임워크가 아니다. 서블릿에 도달하려는 requests에 대해 필터를 통해 조작하거나 제어할 수 있다. 또는, clients에 도달하려는 response를 제어할 수도 있다.

Spring Security가 Filter를 사용하는 좋은 예로 Spring Security 세팅을 위해선 DelegateFilterProxy만 추가해주면 되는데 그렇게 하면 모든 오가는 요청을 intercept한다. Spring Security가 Filter를 사용하기 때문에 Spring MVC와 분리되어 사용될 수 있다.

주로

  • 인증

  • 로깅 및 검사

  • 이미지 및 데이터 압축

  • Spring MVC에서 분리하려는 모든 기능

등에 사용할 수 있다.

Filter를 사용하기 위해서는 Filter를 implements하고 ServletRequest, ServletResponse, FilterChain을 조작할 수 있는 doFilter를 Override 해주고 컴포넌트 스캔을 위한 @Component를 붙여주면 끝난다

@Component
public class LogFilter implements Filter {
    private Logger logger = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException {
        logger.info("Hello from: " + request.getLocalAddr());
        chain.doFilter(request, response);
    }
}

Interceptor

HandlerInterceptors는 Spring MVC의 일부분으로 DispatcherServlet과 Controllers 사이에 위치한다. 우리는 requests가 controller에 도달하기 전과 view의 렌더 전후를 intercept 할 수 있다.

주로

  • 애플리케이션 로깅과 같은 크로스 컷팅 문제 처리

  • 세부적인 권한 검사

  • Spring context 또는 모델 조작

Handlerinterceptor interface를 implements하면 사용할 수 있고 preHandle() ,postHandle(), afterCompletion()를 Override 하면 된다.

public class LogInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
      throws Exception {
        logger.info("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 
      throws Exception {
        logger.info("postHandle");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 
      throws Exception {
        logger.info("afterCompletion");
    }
}

checksum(검사합)

데이터의 오류 확인 방법으로 널리 사용되며 일정 자릿수를 정하고 범위를 넘는 자리 올림은 버려서 자릿수를 유지한다.

암호화와 복호화

암호화는 평문을 알기 어렵도록 변환해서 암호문을 만드는 작업으로 암호문을 다시 평문으로 변환하는 작업을 복호화라고 한다. 일반적으로는 암호문을 평문으로 되돌릴 수 있지만 평문으로 되돌릴 수 없는 암호화도 있다.

예를 들어 사용자의 패스워드를 평문으로 저장하거나 복호화 가능한 형태로 암호화해서 저장하지 않고 평문으로 되돌릴 수 없는 형태로 암호화해서 저장해서 패스워드가 유출됐을 때 사용자의 패스워드가 직접적으로 드러나지 않게 한다.

단방향 암호화

주어진 평문을 통해 원래 값을 추정할 수 없다면 단방향 암호화라고 불린다.

단방향 암호화를 위해 암호학적 해시 알고리즘을 사용하며 해시 알고리즘은 다음의 성질을 갖는다.

  1. 역상 저항성: 해시 값에서 원래 값을 찾을 수 없어야 한다.

  2. 제2 역상 저항성: 원래 값과 다르지만 동일한 해시 값으로 변환되는 다른 값을 찾을 수 없어야 한다.

  3. 충돌 저항성: 동일한 해시 값으로 변환되는 두 개의 값을 찾을 수 없어야 한다.

세 가지를 모두 만족해야 암호학적 해시 알고리즘이라고 할 수 있다.

Hashing algorithm

해시란 임의의 길이의 데이터를 고정된 길이의 데이터로 매싱하는 알고리즘으로 해시 함수는 암호학적 해시 알고리즘과 비암호학적 해시 함수로 구분될 수 있다.

Hash의 특징은

  • 단방향성

  • 입력 값의 크기와 상관 없이 결과 값의 길이가 일정

  • 데이터 무결성 확보와 관련해 IT기술 전반에서 사용

암호학적 해시 알고리즘에는 MD-5(패스워드 단방향 암호화에는 사용해서는 안된다) SHA-1, 128, 256, 512 Argon2, Balloon 등을 사용한다.

Hash는

  • 무결성 확보

    • 인증서 검증

    • 디지털 포렌식

    • 디지털 서명(Hash + PKI)

  • 패스워드 단방향 암호화

  • 블록체인

등에 쓰인다.

블록체인은 어떤 블록의 해시 알고리즘에 의해 나온 결과를 다른 블록의 해시 알고리즘에 인수로 넣어서 또 다시 해시, 그것의 연속으로 만약 이걸 해킹하려면 앞단의 것을 변조해야 하는데 그게 얼기설기 엮여있기 때문에 사실상 변조가 불가능한 것이다.

Salt가 필요한 이유

Hashing을 하기 전에 사용자가 입력한 pw에 내부 개발자가 알고 있는 Salt값을 앞 뒤에 추가로 넣음으로써 브루트포스 어택에 더 강력하게 대응할 수 있다. 암호에 간을 친다고 해서 salt라고 부른다.

대칭키 시스템(Symmetric key)

키 하나로 암호화/복호화를 모두 수행하는 방식으로 비대칭키 방식에 비해 효율적이다.

DES, 3DES, SEED-128, ARIA, AES-128, AES-256 등이 유명하다

0100 0001 - 평문      0x41
1101 0101 - key
1001 0100 - 암호문    0x94

위처럼 key와 함께 xor연산을 하면 암호화를 하고, 거꾸로 복호화도 가능하다 따라서 key의 길이가 길수록 보안성이 높아진다.

key가 노출되면 보안이 끝나기 때문에 보통 개인 파일 암호화, 랜섬웨어가 암호화할때도 대칭키 암호화 방식이 쓰인다. 실시간 스트리밍 암호화 등에도 쓰인다.

비대칭키 시스템(Asymmetric key)

한 쌍의 키가 서로 상호작용하는 구조를 갖는다. 두 키 중 하나로 암호화 하면 쌍을 이루는 다른 키로 복호화한다. 보통 public key와 private key로 구분하며 PKI(Public Key Infrastructure) 기술의 근간을 이룬다

RSA-2048, ECC알고리즘이 있다.

  • key는 소수만 가능하다.

65 ^ 5 mod 323 = 12
12 ^ 29 mod 323 = 65

public으로 공개되는 값은 5와 Molulus 323이고 복호화 키인 29는 공개되지 않는다.

만약 키가 커진다면 소인수분해를 진행해야 되기 때문에 양자컴퓨팅이 상용화되지 않는이상 풀기는 힘들다. 추가적으로 비대칭키는 연산 자체가 많아지기 때문에 성능 이슈가 크다. 모바일 기기에서 쓰기 좋지는 않다.

보안성은 좋지만 암/복호화 속도가 느리기 때문에 전자서명 등에 쓰인다.

디지털 서명

디지털 서명이란 private key로 해시 결과를 암호화, public key를 문서와 함께 전송한다. 받는 쪽에서 문서를 hashing하고 public키로 받은 해싱을 복호화해서 비교, 같으면 문서가 변조되지 않은 것, 다르면 변조된 것

공개키 신뢰를 위한 검증체계(SSL 포함)

위의 방법은 문제가 두 가지 있다.

  1. 컴퓨팅 비용이 너무 비싸다. 실험하신분 자료를 봐도 리소스가 상당히 많이 든다

그게 PKI 인증 체계의 필요성이다.

RA(Registration Authority): 사용자의 신분을 확인하고 CA간 인터페이스를 제공하는 기관 CA(Certification Authority): 인증서 발급과 취소 등의 실질적인 업무를 하는 기관으로 yessign 등이 있다.

사용자가 RA에게 인증서를 요청하면 RA가 신청자를 확인하고 CA가 신청자에게 X.509 형식의 public key와 일련의 내용이 담긴 파일을 주는데 이게 SSL인증서라고 불린다.

PKI 인증체계와 더불어 SSL 인증서 발급 과정에 대해 자세히 이야기 하자면

  1. 서버의 public key와 private key를 생성한다.

  2. 인증서를 발급받기 위해 서버는 CA에 아래의 정보들을 전달한다.

    1. 1번에서 생성한 서버의 public key

    2. 서버의 각종 정보

  3. (CA) 2번에서 서버로부터 받은 정보들을 담아 SSL 인증서를 발급한다.

  4. (CA) 3번에서 만든 인증서를 암호화하기 위한 CA의 public key와 private key를 생성하고 CA의 private key를 이용해 SSL 인증서를 암호화한다.

  5. 4번에서 암호화한 SSL 인증서를 다시 서버에 전달한다

출처: Cookie... -> tutorialspoint Filter, Interceptor -> Bealdung 보안 -> 외워서 끝내는 SSL과 최소한의 암호기술 SSL -> nurisis's blog

Last updated