ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Linux] OpenSSL 인증서
    서버 2016. 12. 23. 14:16

    OpenSSL이란?

    인터넷을 통해 클라이언트와 서버가 통신할 때 통신 내용을 안전하게 보호하는 방법으로 SSL(Secure Sockets Layer)을 사용할 수 있습니다. SSL은 서버 인증(Server Authentication), 클라이언트 인증(Client Authentication) 그리고 데이타 암호화(Data Encryption) 기능을 제공합니다. 

    인증(Authentication)은 통신의 상대방이 맞는지 확인하는 절차를 의미합니다. 암호화는 데이타가 누출되더라도 외부에서 이 내용을 해독할 수 없게 하는 걸 의미합니다. 

    SSL을 사용하는 URL은 https 라는 스킴(scheme)을 사용하여 구분합니다. 예를 들어서 이렇습니다.


    https://google.com
    최근 버전의 SSL은 이제 TLS(Transport Layer Security)라고 이름이 바뀌었습니다. 현재 IETF(Internet Engineering Task Force)가 TLS 표준을 유지 관리하고 있습니다

    공개키, 비밀키, 인증서 (Public Keys, Private keys, Certificates)

    인증을 수행할 때 SSL은 공개키 암호화(public-key cryptography)라는 기술을 사용합니다. 공개키 암호화는 공개키(public key)와 비밀키(private key) 이 둘의 조합에 근거한 알고리즘입니다. 공개키로 암호화된 데이타는 그 공개키와 짝이 되는 비밀키에 의해서만 해독이 가능합니다. 반대로 비밀키로 암호화된 데이타 역시 짝이 되는 공개키로 해독할 수도 있습니다. 
    이 키 쌍을 가지고 있는 소유자는 이 중에서 공개키를 아무에게나 공개할 수 있습니다. 하지만 비밀키는 비밀스럽게 보관해야 합니다. 인증서(Certificate)는 소유자의 공개키가 맞는지를 검증하는 도구입니다.X.509 표준을 준수하는 인증서는 다음과 같은 데이타와 서명(signature) 영역을 가지고 있습니다. 
    • 공개키를 소유하고 있는 자의 구별 가능한 이름 
    • 공개키를 발급(issue)한 자의 구별 가능한 이름 
    • 이 인증서가 언제까지 유효한지를 나타내는 유효기간 
    • 공개키 그 자체
    VeriSign과 같은 인증 기관 (CA, Certificate Authority)을 통해 인증서를 발급 받을 수도 있고 스스로 자기 서명 인증서(self-signed cerficate)를 만들 수도 있습니다. 스스로 인승서를 만들었을 경우, 소유자와 발급자가 같습니다. 인증서를 발급하는 인증 기관은 서로간에 어떤 계층(hierarchy) 관계가 있습니다.루트 CA는 자기-서명 인증서를 가지고 있습니다. 하지만 그 하부 CA들은 자기 직속 상관이 발급한 인증서를 가지고 있습니다. 그래서 특정 CA는 이런 인증서들의 묶음을 가지게 되는데 이를 인증서 체인(certificate chain)이라고 합니다. 인증서 체인은 자기 직속 상위 CA가 발급한 인증서를 가지고 있고, 그 상위 CA는 또 그 위의 상위 CA가 발급한 인증서를 가지고 있는 식입니다. 

    PEM 포맷

    PEM(Privacy-enhanced Electronic Mail) 포맷은 인증기관에서 가장 많이 사용하는 포맷입니다. PEM 인증서는 보통 .pem, .crt, .cer, .key 와 같은 확장자를 가집니다. 이 포맷은 Base64로 인코딩된 ASCII 텍스트 파일이고 "------BEGIN CERTIFICATE----"와 "----END CERTIFICATE----"와 같은 시작과 끝을 알리는 문구가 들어 갑니다. 

    OpenSSL 취약점

    2014년 4월 HeartBleed라는 버그가 OpenSSL에서 발생하였습니다.

    HeartBleed란?

    HeartBleed란 OpenSSL 1.0.1 버전에서 발견된 매우 위험한 취약점 입니다. OpenSSL을 구성하고 있는 TLS/DTLS의 HeartBeat 확장규격에서 발견된 취약점으로, 해당 취약점을 이용하면 서버와 클라이언트 사이에 주고받는 정보들을 탈취할 수 있습니다.

     OpenSSL은 정해진 규격의 네트워크 보안 프로토콜을 범용 라이브러리로 구현하기 위한 목적으로 만들어졌으며, SSL이나 TLS를 이용한 암호화를 구현할 수 있습니다. 강력한 암호화 기능을 제공하기 때문에, 보안이 중요한 대형 포털서비스, 이메일 서비스, 금융권 등에서 데이터 통신 시 OpenSSL을 사용하고 있습니다.


     

    HeartBleed 취약점은 OpenSSL 라이브러리의 구조적인 취약점입니다. OpenSSL의 확장규격 중 하나인 HeartBeat는 서버와 클라이언트 사이에 무슨 문제는 없는지 또는 안정적인 연결을 유지하기 위한 목적으로 일정 신호를 주고 받을 때 사용하는 확장규격입니다. 클라이언트는 HeartBeat 확장프로토콜을 이용하여 임의의 정보를 그 정보의 길이와 함께 서버에 전송합니다. 그 후 서버는 전달받은 정보를 다시 클라이언트에 전달해 주는 과정을 통해 자신의 존재 사실을 알려줍니다. 

    이 때 클라이언트로부터 전달받은 정보와 그 정보의 길이가 일치하지 않는다면, 클라이언트의 요청에 서버는 응답을 하지 않는 것이 정상적인 동작입니다. 이번에 발견된 HeartBleed 취약점은 서버가 클라이언트로부터 전달받은 정보의 내용과 그 정보의 길이의 일치 여부를 검증하지 않은 채 정보를 보내주면서 문제가 발생된 것입니다.


    정상적인 요청과 정상적인 반환 값의 예제

    payload의 길이를 조작하여 정보유출 예제


    payload란 실제 전송되는 데이터입니다. 위 정상적인 요청일 경우 서버에게 요청하는 글자와 글자의 수가 일치하지만 정보유출 예제의 경우 서버에게 요청한 글자와 요청받고자 하는 글자의 수가 일치하지 않습니다. 서버는 이러한 요청을 검증하지 않고 요청받은대로 전달하기 위해 서버내에 저장되어 있는 정보들을 전송하게 됩니다. 이것이 바로 HeartBleed 취약점이 발생되는 과정입니다.

    클라이언트는 한번에 최대 64KB의 정보를 요청할 수 있습니다. 실제로 64KB에 들어갈 수 있는 정보는 매우 작습니다. 그러나 해당 취약점을 이용하여 시스템 메모리에 저장되어 있는 무의미한 작은 정보들을 지속적으로 유출시키면, 이러한 무의미한 정보들이 모여 하나의 완전한 유의미한 정보가 될 수 있습니다. 이러한 과정을 통하여 공격자는 시스템 메모리에 저장되어 있는 정보들을 유출시킬 수 있으며, 이 정보들에는 개인키, 관리자 정보 등 민감한 정보들도 포함되어 있습니다. 특히 개인키의 경우 암호화하여 전달되는 데이터를 모두 열람할 수 있는 핵심정보이기 때문에 사안이 매우 심각하다고 할 수 있습니다.


    HeartBleed 명칭의 유래는 해당 취약점으로 공격할 때마다 작은 정보들이 새어 나오는 것을, 심장이 한번씩 뛸 때마다(HeartBeat) 심장에서 피가 한 방울씩 떨어지는 치명적인 심장출혈(HeartBleed)로 비유하여 명명한 것입니다.

    SSL 인증서 생성

    key 파일 생성

    key 파일에 패스워드를 넣어 생성하면, 후에 다른 서비스에 연동하여 해당서비스 구동할 때마다 key파일의 암호를 물어봅니다. 패스워드를 제거하더라도 SSL 암호화 통신에는 문제가 없어서 제거해도 상관없습니다. 호스팅업체에서 제공하는 로드밸런서에 사설인증서를 올릴 때에도 패스워드를 제거해야 합니다.

    $ openssl genrsa -des3 -out 파일이름.key 1024
    $ openssl genrsa -out 파일이름.key 1024 # 패스워드 제거 생성
    $ openssl rsa -in 기존파일이름.key -des3 -out 새로운파일이름.key # 기존에 생성된 key파일에 암호 추가하여 재생성
    $ openssl rsa -in 기존파일이름.key -out 새로운파일이름.key # 기존에 생성된 key파일의 암호를 제거하여 재생성

    인증요청서(csr) 생성

    공개키 인증서를 신청하기 위해 신청자가 인증기관에 보내는 메세지입니다. 또는 인증서 발급 신청서(전자문서, 파일)입니다. 해당 파일을 만들기 위해선 key 파일이 존재해야합니다.

    $ openssl req -new -key server.key -out server.csr
    Enter pass phrase for server.key:  # 서버의 개인키 비밀번호 입력
     
    # -> 사용자의 경우에 맞게 적절히 입력
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [XX]:
    State or Province Name (full name) []:
    Locality Name (eg, city) [Default City]: 
    Organization Name (eg, company) [Default Company Ltd]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) []:
    Email Address []:
     
     
    # -> 아래 내용이 필요할 시 비밀번호를 추가적으로 생성할 수 있지만 보통경우 그냥 엔터를 쳐서 넘어가도 무관
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
     
    # 서버 인증요청서인 server.csr 파일 생성

    인증서(crt) 생성

    위에서 만든 개인키와 인증요청서로 인증서를 생성합니다.

    $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt 


    댓글