ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DB 서버 id, password 암호화
    Security 2023. 3. 8. 10:37

     

    들어가기 전에

    회사의 서비스가 커지면서 신경쓰지 않고 넘어간 작업들을 다시 고려해야하는 상황이 되었다.

     

    초기에는 서비스가 시장에서 니즈가 있는지 빠르게 확인해보기 위해 결과물을 만들기만 급급했는데 사용자가 생기고 서비스가 다양해지면서 보안 및 서비스 관리가 필요해졌다.

     

    이번에 알아볼 내용은 DB 서버 접속에 필요한 id, password 암호화 하는 것이다.

     

    How to encrypt the database server ID and password

    해당 키워드로 검색엔진과 ChatGPT 를 사용하여 조사를 해보았다.

     

    1. 암호화 알고리즘을 선택
      ☞ AES, RSA, Blowfish 등 여러 가지 암호화 알고리즘이 있다.
      ☞ 시스템에 적합하고 충분한 보안을 제공하는 암호화 알고리즘을 선택
    2. 고유한 키를 생성
      ☞ 데이터베이스 서버 id 와 password 를 암호화하고 복호화하는 데 필요한 키가 필요하다.
      ☞ 강력하고 안전한 고유한 키를 생성
    3. 암호화 구현
      ☞ 암호화를 지원하는 프로그래밍 언어나 라이브러리를 사용하여 데이터베이스 서버 id 와 password 를 암호화한다.
      ☞ 암호화 과정은 일반 텍스트로 이루어진 데이터베이스 서버 id 와 password 를 키가 올바르면 복호화할 수 있는 암호화된 텍스트로 변환하는 것이다.
    4. 고유한 키를 안전하게 저장
      ☞ 암호화에 사용되는 키는 미승인된 접근을 방지하기 위해 안전하게 저장한다.
      ☞ 키 관리 시스템과 같은 안전한 위치에 키를 저장하고, 인가된 직원만 접근할 수 있도록 제한한다.
    5. 복호화 구현
      ☞ 암호화된 데이터베이스 서버 id 와 password 가 필요한 경우, 같은 키를 사용하여 암호화된 텍스트를 일반 텍스트 형식으로 복호화를 해야한다.
      ☞ 다시 한번 암호화를 지원하는 프로그래밍 언어나 라이브러를 사용한다.
    6. 안전한 통신 채널 사용
      ☞ 암호화된 데이터베이스 서버 id 와 password 를 통신할 때, HTTPS 또는 SSH 와 같은 안전한 통신 채널을 사용하여 공격자가 가로채는 것을 방지 해야한다.

    그렇다면 1번부터 차례대로 구체화를 시켜보자!

     

    암호화 알고리즘

    정의

    ☞ 평문(Plaintext): 해독 가능한 형태의 메시지(암호화 전 메시지)
    ☞ 암호문(Cipertext): 해독 불가능한 형태의 메시지(암호화된 메시지)
    ☞ 암호화(Encryption): 평문을 암호문으로 변환하는 과정
    ☞ 복호화(Decrytion): 암호문을 평문으로 변환하는 과정
    ☞ 전자서명
      1) 송신자의 Private Key 로 메시지를 서명하여 전달
      2) 수신자측에서는 송신자의 Public Key 를 이용하여 서명값을 검증
    ☞ 양방향 암호화: 암호화와 복호화 과정을 통해 송.수신간 주고받는 메시지를 안전하게 알 수 있다.
    ☞ 단방향 암호화: 해싱(Hashing)을 이용한 암호화 방식으로, 평문을 암호문으로 암호화는 가능 하지만 암호문을 평문으로 복호화는 불가능

    * 여기서 잠깐 송신자 수신자를 헷갈릴 수 있으니 확인하고 가자 (필자는 가끔 헷갈리더라..)

     

    송수신

    위 이미지로 바로 설명할 수 있다.

    송신자(Sender)는 인터넷 환경으로 가기 전 복합기이고, 수신자(Receiver)는 인터넷 환경을 지나간 후 PC, Laptop, 복합기가 된다.

    송신자는 자료를 보내는 쪽, 수신자는 자료를 받는 쪽

     

    암호화 분류

     

    양방향 암호화(대칭/비대칭 키)

    • 대칭 키: 같은 키를 이용하여 메시지를 암.복호화 하는 것
    • 비대칭 키: 메시지를 암호화 하는 키와 복호화 하는 키가 다른 것

    ☞ 암호화 알고리즘에 따라 사용방식이 다를수도 있다.
    ☞ 전자서명을 위한 알고리즘에서는 Private Key 로 메시지를 서명하고, Public Key 로 검증
    ☞ 메시지 교환에서는 Public Key 로 메시지를 암호화하고, Private Key 로 복호화한다.

     

    대분류 중분류 알고리즘 설명
    대칭 키 방식 블록 암호 알고리즘 DES - 64bit 블록, 128bit 암호화 키 사용
    - 평문을 64bit 로 나눠 각 블록에 치환과 전치를 16Round 반복하여 암호화
    3-DES 암호화 키 2개를 사용하여 [암호화(k1) → 복호화(k2) → 암호화(k1)] 순으로 암호화
    AES - 128bit 평문을 128bit 로 암호화
    - 키 크기에 따라 10/12/14회 Round 수행
    - 라운드키의 수 = N+1개 
    SEED - KISA 주관, ETRI 에서 개발
    - 국제표준 부합, 민간 사용 목적
    ARIA - NSRI 에서 개발
    - 공공 사용 목적, 비밀 키 규격이 AES 와 동일
    스트림 암호 RC-4 - TLS, WEP 등에서 사용
    - Octet(2진부호모음, 8bit) 단위 기반 암호화
    비대칭 키 방식 인수분해 RSA - 큰 숫자를 소인수분해 하는 것이 어렵다는 것에 기반하여 개발
    - 공개키만 가지고 개인키 추측불가
    이산대수 DSA - 이산대수의 어려움을 안정성의 바탕으로 개발

     

    대칭 키 암호화

    • 종류: AES128, AES256, SEED(국내표준)
    • 암.복호화 키가 같다.
    • 문제점: 수신측에 키를 전달하는 과정에서 유출될 우려가 있다.
    • 스트림기반, 블록기반의 암호화로 나눌 수 있다.

     

    대칭 키

    스트림기반 암호화

    • 비트단위로 암호화하는 방식
    • LFFSR, MUX generator 등의 스트림기반 암호화 알고리즘
    • 속도가 빠르고 오류 전파 현상이 없다는 장점
    • 주로 오디오/비디오 스트리밍 시 사용

     

     

    블록기반 암호화

    • 블록 단위로 암호화를 수행하는 방식
    • 문자열 단어 하나하나를 블록으로 나누어 암호화하는 과정
    • DES, AES, IDEA, SEED 등의 블록기반 암호화 알고리즘

     

     

    비대칭 키 암호화

    • 종류: DSA(전자서명), RSA(메시지 암.복호화)
    • 대칭 키에 비해서는 느리다는 단점
    • 키 생성시 Private Key 와 Public Key 2개의 키가 도출되며, Public Key 는 공개해도 문제가 되지 않는다.
    • 개인키로 암호화를 하는 방식과 공개키로 암호화를 하는 방식 두 가지로 나누어진다.
    • 인수분해, 이산대수, 타원곡선 암호화로 나뉜다.

     

    비대칭 키를 사용하여 두 가지 암호학적 문제를 해결할 수 있다.

    • 데이터 보안
    • 인증

     

     

    공개키로 정보를 암호화하는 경우

    • 공개키는 누구나 알 수 있도록 공개된 키, 어떤 정보를 특정 사용자에게 보낼 때 해당 사용자의 공개키를 통해 정보를 암호화하여 전송합니다.
    • 예를 들자면, 부산에 사는 철수는 누구나 알 수 있는 영희의 공개키를 통해 보물상자를 암호화한 후 영희에게 보낸다.
    • 보물상자는 영희의 공개키로 암호화 되었기 때문에 열어보기 위해서 영희의 개인키가 필요하다.
      ☞ 공개키로 암호화 되었다면 개인키로 해제할 수 있습니다. 공개키로 해제는 불가능
    • 영희의 개인키는 영희만 가지고 있기에, 받아 본 보물상자를 안전하게 열어볼 수 있다.
    • 대칭키에서의 키값 교환에 따른 문제를 해결한 방법이라 할 수 있다.

     

    개인키로 정보를 암호화하는 경우

    • 개인키는 본인만 가지고 있는 키, 어떤 정보를 특정 사용자에게 보낼 때 본인의 개인키를 통해 정보를 암호화하여 전송합니다.
    • 예를 들자면, 부산에 사는 철수는 본인의 개인키를 통해 보물상자를 암호화한 후 영희에게 보낸다.
    • 보물상자는 철수의 개인키로 암호화 되었기 때문에 열어보기 위해서 철수의 공개키가 필요하다.
      ☞ 철수의 공개키는 누구나 알 수 있도록 공개 되어있습니다.
    • 영희는 보물상자를 받아 본 후 공개되어있는 철수의 공개키를 통해 보물상자를 열어볼 수 있다.

     

    여기서 생기는 의문!

     

    Q. 다른사람들이 이 보물상자를 중간에서 가로챈다면 공개된 철수의 공개키를 통해 보물상자를 열어볼 수 있지 않나요?

    A. 맞습니다. 누구나 열어볼 수 있습니다.

    Q. 그렇다면 보안에 취약한게 아닌가요? 이런 방법을 왜 쓰는건가요?

    A. 이러한 방법은 '보물상자안에 뭐가 들었냐' 보다는 '이 보물상자를 누가 보냈냐' 에 초점을 둔 방법입니다.

    즉, 철수의 개인키로 암호화 한 보물상자는 철수의 공개키를 통해서만 열어볼 수 있기 때문에, 어떤 보물상자가 철수의 공개키로 열린다면, 이 보물상자는 철수가 보낸게 확실하다는 뜻

     

    대칭 키 비대칭 키 암호화 요약

    1. 대칭 키 암호화는 똑같은 개인키를 송.수신자가 공유하여 정보를 암.복호화 하는 것을 의미합니다.
    2. 비대칭 키 암호화는 공개키와 개인키를 각각 암.복호화에 적용하여 암.복호화 하는 것을 의미합니다.
      ☞ 상대방의 공개키를 통한 암호화, 상대방이 개인키를 통한 복호화
      : 정보 자체에 대한 암호화가 필요할 때 사용
      ☞ 자신의 개인키를 통한 암호화, 자신의 공개키를 통한 복호화
      : 정보를 생산(송신)한 사람의 신원에 대한 정보가 필요할 때 사용

     

    데이터 보안 관점

    • 사용자가 데이터를 서버로 보내는 과정에서 개인정보와 같은 중요한 데이터는 암호화해서 보내야한다.
    • 서버만 유일하게 갖고 있는 개인키로만 복호화할 수 있게 서버의 공개키로 암호화해 데이터를 전송해야 한다.
      ☞ 제 3자가 클라이언트에서 서버로 전송하는 데이터를 볼 수 없다

     

    인증 관점

    • 클라이언트와 서버는 서로 확인하기 위해 Handshake 과정을 진행한다.
      ☞ 이 때 서버에서는 CA(공인 인증 기관)에서 인증받은 인증서(CA의 개인키로 암호화된 전자 서명)를 클라이언트로 보낸다.
    • 사용자는 CA의 목록을 확인해서 공인 인증기관이 서명한 인증서인지 확인한다.
    • CA의 공개키를 이용해서 해당 인증서를 복호화한다.
    • 복호화에 성공하면 서버의 공개키를 얻는다.
    • 공인 인증 기관에서 서명 받은 서버의 인증서가 공인 인증 기관의 공개키로 복호화가 가능하다는 것이 해당 기관은 인증 받은 단체라는 것을 확인할 수 있다.

     

    ECC(Elliptic Curve Cryptography)

    • 타원곡선 암호화로 RSA 에 비해 짧은 길이의 키를 사용하면서도 비슷한 수준의 안정성을 제공
    • 비트코인 및 이더리움에서 ECC 알고리즘을 이용한다.

    ECC 기반의 암호화

    • ECDSA(Elliptic Curve Digital Signature Algorithm)
      ☞ 전자서명(ECC 암호화 알고리즘을 전자서명에 사용한 것)
    • ECDH(Elliptic Curve Diff-Hellman)
      ☞ 키 교환 알고리즘(자신의 Private Key 와 상대방의 Public Key 를 사용하여 공통된 Secret Key 를 도출)
    • ECIES(Elliptic Curve Integreated Encryption Scheme)
      ☞ 통합 암호화 방식(Public Key 로 암호화하고 Private Key 로 복호화)

     


    단방향 암호화

    • Hash 를 이용하여 암호화하는 과정
    • 평문을 암호화할 수 있지만, 복호화는 불가능하다.
    • 데이터의 진위여부는 확인하고 싶은데, 본 데이터의 Privacy 를 지키고 싶은 경우 사용한다.
    • ex) Bcrpyt-JWT (참고: 인증 & 인가)
    • Hash 할 때, Hash 값은 크기와 알고리즘에 따라 암호문의 결과가 완전 상이하다.

    단방향 Hash 알고리즘

    알고리즘 분류 알고리즘 명 MD 길이 블록 길이 최대 메시지 길이
    MD5 MD5 128bit 512bit 무한
    RIPEMD RIPEMD-160 160bit 512bit 2^64 - 1bit
    SHA-1 SHA-1 160bit 512bit 2^64 - 1bit
    SHA-2 SHA-224 224bit 512bit 2^64 - 1bit
    SHA-2 SHA-256 256bit 512bit 2^64 - 1bit
    SHA-2 SHA-384 384bit 1024bit 2^128 - 1bit
    SHA-2 SHA-512 512bit 1024bit 2^128 - 1bit
    SHA-3 SHA-2 와 디자인이
    달라짐
         

     

    대칭 키 암호화 중 대표되는 AES 알고리즘의 자세한 암호화 과정을 보시려면 여기를,

    비대칭 키 암호화 중 대표되는 RSA 알고리즘의 자세한 암호화 과정을 보시려면 여기를 확인해보세요.

     

    고유한 키를 생성

    • 암호화와 복호화에 필요한 고유 키는 암호학에서 사용되는 핵심 요소이다.
    • 키는 암호화 알고리즘이 평문을 암호문으로 변환하는 데 사용되며, 복호화 알고리즘이 암호문을 다시 평문으로 변환하는 데 사용된다.
    • 암호화와 복호화에 사용되는 키는 대칭형 또는 비대칭형일 수 있다.
    • 대칭키 암호화에서는 암호화와 복호화에 동일한 키가 사용된다. 즉, 데이터를 암호화하는 데 사용되는 키는 데이터를 복호화하는 데에도 사용된다.
    • 대칭 암호화 알고리즘의 예로는 AES, DES 및 Blowfish 가 있다.
    • 비대칭키 암호화에서는 공개 키와 개인 키 두 개의 키가 사용된다.
    • 공개 키는 암호화에 사용되고, 개인 키는 복호화에 사용된다. 공개 키는 자유롭게 배포되지만, 개인 키는 비밀로 유지된다.
    • 비대칭 암호화 알고리즘의 예로는 RSA 및 ElGamal 이 있다.
    • 암호화와 복호화의 강도와 보안은 사용된 키의 강도에 따라 결정된다.
    • 무작위로 충분히 긴 강력한 키를 사용하고, 평문 또는 키 자체에 대한 무단 액세스를 방지하기 위해 안전하게 보관하는 것이 중요하다.

     

    암호화 구현

    암호화를 지원하는 프로그래밍 언어 및 라이브러리는 많이 있다. 가장 인기 있는 프로그래밍 언어로는 다음과 같은 것이 있다.

    • Java: Java는 Java Cryptography Architecture (JCA) 및 Java Cryptography Extension (JCE)과 같은 암호화 알고리즘 및 도구의 다양한 범위를 제공한다.
    • Python: Python은 대칭 및 비대칭 암호화, 메시지 다이제스트 및 키 유도 기능과 같은 다양한 암호화 원시 자료를 제공하는 암호화 라이브러리인 cryptography를 포함한다.
    • C/C++: C 및 C++는 OpenSSL 과 같은 다양한 암호화 라이브러리를 제공합니다. 이는 AES, RSA 및 SHA와 같은 다양한 암호화 알고리즘을 지원한다.
    • JavaScript: JavaScript는 AES 암호화, RSA 암호화 및 SHA 해싱과 같은 다양한 암호화 원시 자료를 제공하는 Web Crypto API 를 포함한다.
    • PHP: PHP는 비밀번호 해싱, Blowfish 암호화 및 OpenSSL 암호화와 같은 다양한 암호화 함수를 포함한다.
    • Ruby: Ruby는 AES, RSA 및 SHA와 같은 다양한 암호화 알고리즘을 지원하는 OpenSSL 라이브러리를 포함한다.
    • Go: Go는 AES, RSA 및 SHA와 같은 다양한 암호화 알고리즘을 지원하는 crypto 패키지를 포함한다.

    기타 인기있는 암호화 라이브러리로는 Bouncy Castle, Cryptlib 및 Crypto++ 등이 있다. 이러한 라이브러리는 대칭 및 비대칭 암호화, 메시지 다이제스트 및 키 유도 기능과 같은 다양한 암호화 원시 자료를 제공한다.

     

    여기서 조금 더 내 상황의 맞는 시나리오를 생각해보자

     

    현재 상용되는 서버의 구조는 Spring Boot 기반으로 비즈니스 로직이 처리되고 있다.

    그렇다면 Spring Boot 프레임워크에서 지원하는 암호화 알고리즘이 있을까?

     

    조사를 해보니 두 가지 방법을 알게되었다.

    1. Spring Boot는 Java의 내장 암호화 API, Java 암호화 아키텍처(JCA)와 Java 암호화 확장(JCE)에서 사용 가능한 다양한 암호화 알고리즘 및 메커니즘을 지원한다. Spring Boot에서 사용할 수 있는 일반적인 암호화 알고리즘은 다음과 같다.
      ☞ AES (고급 암호화 표준)
      ☞ RSA (Rivest-Shamir-Adleman)
      ☞ DES (데이터 암호화 표준)
      ☞ Triple DES (3DES)
      ☞ Blowfish
      ☞ Twofish

      Spring Boot는 이러한 암호화 알고리즘의 다양한 동작 모드, 예를 들어 전자 코드 북(ECB), 암호 블록 연쇄(CBC), 암호 피드백(CFB) 및 출력 피드백(OFB)도 지원한다.
    2. Spring Boot는 Bouncy Castle과 같은 제3자 라이브러리를 사용하는 방법으로 암호화 및 복호화를 사용할 수 있다.

    JCA(Java Cryptography Architecture) 소개

    • JCA는 자바 프로그래밍 언어의 암호화를 위한 프레임워크이다. JDK1.1 java.security 패키지에 처음 소개되었다.
    • Provider 기반 아키텍처를 사용하고 암호화, 키 생성 및 관리, 'secure random number' 생성, 인증서 검증 등의 API를 포함하고 있다.
    • JCA는 구현 독립성/호환성, 알고리즘 확장성을 고려하여 설계되었다.
      ☞ 구현 독립성: 보안 기능별 독립된 제공자(provider)로 프로그래밍
      ☞ 구현 호환성: 프로그램들간 추상화된(고정되지 않은) 제공자를 통해서 호환
      ☞ 알고리즘 확장성: 대부분의 알고리즘을 지원하고, 임의의 제공자(provider) 추가 가능
    • JDK 1.4 이상에서는 JCE(Java Cryptography Extention)도 기본 포함된다.
    • 관련 암호 서비스를 정의하고 지원하기 위한 'Provider Framework'(java.security, javax.crypto, javax.crypto.spec, javax.crypto.interfaces 패키지)와 'Provider'(실제 암호 구현 내용이 포함된 Sun, SunRsaSign, SunJCE 패키지)를 제공한다.

    기타 JDK 암호 라이브러리

    • JSSE(Java Secure Socket Extension): SSL/TLS 기능 제공
    • JGSS(Java Generic Security Services): Kerberos, 네트워크 보안 기능 제공
    • SASL(Simple Authentication and Security Layer): 네트워크 보안 기능 제공

    구조

     

     

    위 그림에서 보듯 각각의 애플리케이션은 'Provider Framework'를 통해서 각각의 독립적인 'Provider'에 접근해서 암호 기능을 구현할 수 있다.

     

    키 관리

    • 키와 인증서들의 저장소를 관리하는 'keystore'가 있다.
    • java.security.KeyStore 클래스
    • .jks 파일 형태로 구현됨(또는 3DES로 암호화된 .jceks)
    • 애플리케이션은 각각의 'Provider'로부터 개별적인 keystore 구현 가능

    주요 클래스

    클래스 명(인터페이스 명) 내용
    Provider 기본 Provider 클래스
    Security Provider 및 'security property' 관리
    SecureRandom 난수(random number) 생성
    MessageDigest 해시값 생성
    Signature 전자 서명 & 검증
    Cipher 블록 암호(AES, DES, DESede, Blowfish, IDEA 등), 스트림 암호(RC4 등), 비대칭 암호(RSA 등), 패스워드 암호(PBE 등) 등 제공
    MAC(Message Authentication Codes) MAC(해시값 생성 & 무결성 보장 기능)
    Key(key) 기본 키 클래스(인터페이스)
    KeyFactory 키 타입 변환
    SecureKeyFactory 대칭 키 타입 변환
    KeyPairGenerator 공개키/개인키 생성
    KeyGenerator 대칭 키 생성
    KeyAgreement 키 교환 정보
    KeyStore 키 관리
    AlgorithmParameters 알고리즘 파라미터
    AlgorithmParameterGenerator 알고리즘 파라미터 생성
    CertificateFactory 인증서, 인증서폐기목록(CRL) 생성
    CertPathBuilder 인증서체인 생성
    CertPathValidator 인증서체인 검증
    CertStore 인증서, 인증서폐기목록(CRL) 관리

     

    JCE(Java Cryptography Extension) 소개

    JCE는 JCA 보다 더 강력한 확장된 보안 기능을 제공한다. 미국에서 보안상 이유로 2000년 이후에 해외로 보급되었다.

     

     

    위 그림에서 보듯 JCA(java.security 패키지)와 JCE(javax.crypto 패키지)가 분리되어 있는 것을 알 수 있다. JDK1.4 이상부터 모두 기본으로 포함되어 있다.

     

    SUN JCE 와 BouncyCastle 비교

      장점 단점
    SUN JCA/JCE - JDK에 포함되어 있다.
    - 'provider'를 선택해서 사용할 수 있다.
    - JDK 별로 provider 가 일치하지 않아서 동작하지 않을 수 있다.
    - 알고리즘을 많이 제공하지 않는다.
    Bouncy Castle - JCA보다 많은 알고리즘을 지원한다.
    * SEED128 알고리즘 지원
    - 사용에 아무런 제한이 없다(128bit 암호키 제한 등)
    라이브러리 파일을 프로젝트에 추가해야한다.

     

    기본적인 키 생성, 암호화, 전자서명 등은 JCA/JCE로 가능하다. 하지만 JDK 별로 호환이 안되는 경우가 있고, 많은 알고리즘을 지원하지 않기 때문에 BouncyCastle 등의 라이브러리를 사용하는 것도 좋은 방법이다.

     

     

    자 이제 무엇이 필요하고 어떤 순서로 작업을 진행할 지 알았으니 실제 구현을 해보자!

     

    현재 작업 중이며 완료되면 캡처 본과 함께 정리해서 업로드 할 계획입니다

    'Security' 카테고리의 다른 글

    Spring Security + JWT, Servlet Filter  (0) 2021.12.21
    JWT (JSON Web Token) 소개  (0) 2021.11.17
Designed by Tistory.