-
DB 서버 id, password 암호화Security 2023. 3. 8. 10:37
들어가기 전에
회사의 서비스가 커지면서 신경쓰지 않고 넘어간 작업들을 다시 고려해야하는 상황이 되었다.
초기에는 서비스가 시장에서 니즈가 있는지 빠르게 확인해보기 위해 결과물을 만들기만 급급했는데 사용자가 생기고 서비스가 다양해지면서 보안 및 서비스 관리가 필요해졌다.
이번에 알아볼 내용은 DB 서버 접속에 필요한 id, password 암호화 하는 것이다.
How to encrypt the database server ID and password
해당 키워드로 검색엔진과 ChatGPT 를 사용하여 조사를 해보았다.
- 암호화 알고리즘을 선택
☞ AES, RSA, Blowfish 등 여러 가지 암호화 알고리즘이 있다.
☞ 시스템에 적합하고 충분한 보안을 제공하는 암호화 알고리즘을 선택 - 고유한 키를 생성
☞ 데이터베이스 서버 id 와 password 를 암호화하고 복호화하는 데 필요한 키가 필요하다.
☞ 강력하고 안전한 고유한 키를 생성 - 암호화 구현
☞ 암호화를 지원하는 프로그래밍 언어나 라이브러리를 사용하여 데이터베이스 서버 id 와 password 를 암호화한다.
☞ 암호화 과정은 일반 텍스트로 이루어진 데이터베이스 서버 id 와 password 를 키가 올바르면 복호화할 수 있는 암호화된 텍스트로 변환하는 것이다. - 고유한 키를 안전하게 저장
☞ 암호화에 사용되는 키는 미승인된 접근을 방지하기 위해 안전하게 저장한다.
☞ 키 관리 시스템과 같은 안전한 위치에 키를 저장하고, 인가된 직원만 접근할 수 있도록 제한한다. - 복호화 구현
☞ 암호화된 데이터베이스 서버 id 와 password 가 필요한 경우, 같은 키를 사용하여 암호화된 텍스트를 일반 텍스트 형식으로 복호화를 해야한다.
☞ 다시 한번 암호화를 지원하는 프로그래밍 언어나 라이브러를 사용한다. - 안전한 통신 채널 사용
☞ 암호화된 데이터베이스 서버 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. 이러한 방법은 '보물상자안에 뭐가 들었냐' 보다는 '이 보물상자를 누가 보냈냐' 에 초점을 둔 방법입니다.
즉, 철수의 개인키로 암호화 한 보물상자는 철수의 공개키를 통해서만 열어볼 수 있기 때문에, 어떤 보물상자가 철수의 공개키로 열린다면, 이 보물상자는 철수가 보낸게 확실하다는 뜻
대칭 키 비대칭 키 암호화 요약
- 대칭 키 암호화는 똑같은 개인키를 송.수신자가 공유하여 정보를 암.복호화 하는 것을 의미합니다.
- 비대칭 키 암호화는 공개키와 개인키를 각각 암.복호화에 적용하여 암.복호화 하는 것을 의미합니다.
☞ 상대방의 공개키를 통한 암호화, 상대방이 개인키를 통한 복호화
: 정보 자체에 대한 암호화가 필요할 때 사용
☞ 자신의 개인키를 통한 암호화, 자신의 공개키를 통한 복호화
: 정보를 생산(송신)한 사람의 신원에 대한 정보가 필요할 때 사용
데이터 보안 관점

- 사용자가 데이터를 서버로 보내는 과정에서 개인정보와 같은 중요한 데이터는 암호화해서 보내야한다.
- 서버만 유일하게 갖고 있는 개인키로만 복호화할 수 있게 서버의 공개키로 암호화해 데이터를 전송해야 한다.
☞ 제 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 프레임워크에서 지원하는 암호화 알고리즘이 있을까?
조사를 해보니 두 가지 방법을 알게되었다.
- 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)도 지원한다. - 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 - 암호화 알고리즘을 선택