티스토리 뷰

출처 : https://velog.io/@dbadoy/Base64-Base58

 

Base64, Base58

Base64 Base64는 문자를 비트(8비트)로 바꾼 후, 6비트씩 나눠서 다시 표현한다. 예를 들어 abc 라면 ... ASCII 코드값 a(97) b(98) c(99) a 0 1 1 0 0 0 0 1 b 0 1 1 0 0 0 1 0 c 0 1 1 0 0 0

velog.io

 

Oracle에서 PostgreSql 로 컨버전을 하며 암호화에 대한 내용을 정리하고자 한다,,

 

일단, 본인이 작업할 내용은 Function을 생성하여 Input String을 AES-256에 IV(Initial Vector)를 사용하여 암호화한 후, Base64방식으로 Encoding을 하여 Data를 저장할 예정이다.

암호화한 값은 Byte형태로 Return하기 때문에 저장할 때, DB에 저장할 때 Text형태로 저장하기 위해 바이너리 데이터를 Base64로 인코딩하여 사용할 것이다.

 

먼저 개념 정리부터 차근차근 시작해보자.

 

인코딩

  •  문자나 기호를 부호화(컴퓨터가 이용할 수 있는 신호)하는 것을 인코딩이라 한다.

 

인코딩 방식

  • 다양한 문자포맷에 대응하기 위해 Byte에 대한 인코딩 개념으로 사용한다.

 

1. ASCII

- 최초의 문자코드. 라틴 문자, 숫자, 특수문자를 128개의 코드값에 1:1 대응

- 1byte에서 7bit를 사용해 128개 문자 표현, 나머지 1bit는 에러 검출을 위한 Parity bit

 

2. Base64

- A~Z, a~z, 0~9 , +, / (64개로 표현)

- 64진수로 표현

- 3바이트를 4바이트 64진수로 표현

 

3. hex(base16)

- 0~9, A~F (16개로 표현)

- 16진수로 표현

- 1바이트를 2바이트 16진수로 표현

 

Base64 왜 써야함?

보통 네트워크 송수신은 OS에서 담당하므로, OS는 어플리케이션단에서 전달받은 문자열을 알아서 변환하여 전송하거나 수신한다. 기본적인 알파벳과 숫자는 안전하지만, 특수 문자들은 바이너리 코드로 바꾸는 규칙이 charset간 다를 수 있다. 따라서 서로 다른 시스템간에 규칙이 다를 수 있어 몇몇 문자열이 깨질 수 있다. 그래서 어떤 시스템에서든 바꾸는 방법이 동일한 a~z, 0~9, + / 를 사용하여 encoding을 하는 것이 base64를 쓰는 이유다.

 

자세한 내용을 해당 블로그를 참고하면 좋을 것 같다. Base64는 왜 쓰는 것일까? (tistory.com)

 

 

암호화

데이터를 보안하기 위해 데이터를 변조하는 작업을 암호화라 한다.

 

암호화 방식

 

  • 단방향 암호화 (해시)

단방향 암호화는 주로 인증과정에서 많이 사용된다. 예를 들어 비밀번호를 ‘123’이라고 지정했을 때, 이를 암호화하여 ‘ASHDwhe.qw’라는 아무런 유사성 없는 암호문을 만들어 낸다. 단방향 암호화의 특징은 복호화가 불가능하기 때문에, Input 값을 암호화하여 저장된 암호화값과 대조하여 인증하는 방식을 사용한다.

대표적으로 많이 사용하고 있는 알고리즘은 SHA-256 암호화 알고리즘이다.

 

 

  • 비밀키 암호화(대칭키)

비밀키 암호화는 말 그대로 비밀키를 사용하여 암호화와 복호화하는 과정을 가진다. 평문에 암호화 키 값을 이진수 연산 처리하여 암호문을 생성하고, 암호문을 받은 수신자는 동일한 암호화 키 값을 역으로 대입하여 암호문을 해독한다. 따라서 비밀키 암호화를 위해서는 송신자와 수신자 모두 동일한 암호화 키를 공유하고 있어야 한다.

대표적으로 많이 사용하고 있는 알고리즘은 aes 암호화 알고리즘이다.

 

 

  • 공개키 암호화(비대칭키)

공개키 암호화는 공개키와 개인키라고 불리는 서로 다른 두 개의 키를 사용한다. 앞선 비밀키 암호화 방식과 비교해보면 송, 수신자에게 공개된 공개키를 사용하여 암호화하는 점은 비슷하지만, 복호화는 개인키를 가진 사람만 할 수 있다는 점에서 차이가 생깁니다. 조금 더 복잡해 보이는 해당 방식은 비밀키 암호화 방식보다 처리가 느리기 때문에 실제 암호화 시스템은 비밀키 암호화 방식과 공개키 암호화 방식을 혼합하여 구축된다.

 

 

그렇다면 이제 postgresql에서 대칭키암호화인 aes-256을 사용하여 base64로 인코딩해보자.

 

postgresql의 암호화 기능을 사용하기 위해 아래와 같은 확장을 진행해준다.

 

 

CREATE EXTENSION pgcrypto;

 

Postgresql 암호화 가이드

 

암호화 방식

blowfish = bf

rijndael = aes 

des      = des 

3des     = 3des 

 

암호화 모드

cbc (default)

- 보안성이 높은 암호화 방법으로 가장 많이 사용됨.

- 평문의 각 블록은 xor연산을 통해 이전 암호문과 연산되고 첫번째 암호문에 대해서는 IV가 암호문 대신 사용됨.

 

ecb 

- 가장 단순한 모드로 블록단위로 순차적으로 암호화 하는 구조

 

패딩

pkcs — 가변 길이 자료 (기본값)

none — 자료는 암호 블록의 배수 크기여야 함

 

 

Postgresql 암호화 function

 

아래의 예제와 같이 진행하면, 암호화 function 자체에서 bytea값을 return 시켜주기 때문에 암호화된 byte값이 출력된다.

encrypt(암호화할 문자열, 암호키, 암호화 방식-암호화 모드/pad:패딩) ;
example ) SELECT encrypt( 'text text', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aes');

또한 해당 aes암호화를 128, 256 어떻게 줄 것인지 결정하기 위해서는 키값의 byte만 정해주면 알아서 암호화가 진행된다.

즉, 키값을 32byte(256bit)으로 지정해주면 자동으로 aes256으로 암호화가 진행된다. 

 

아래의 사이트에서 내용을 확인할 수 있다.

https://www.postgresdba.com/bbs/board.php?bo_table=B12&wr_id=70

 

여기까지 진행이 됐다면 거의 다 온셈이다. 이제 byte값을 base64로 Encoding만 하면 본래의 목적을 달성하는 것이기 때문이다.

 

SELECT encode(encrypt( 'text text', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aes'), 'base64');

===> FKs9X/Ew4NBWliB/lX8ybw==

이렇게 암호화된 값을 Base64로 인코딩해주면 올바르게 인코딩 된 값이 나오는 걸 볼 수 있다. '=' 값은 패딩이다. 

 

 

이제 암호화의 보안을 좀 더 강화하기 위해 iv를 사용해보자.

iv란 초기화벡터로 첫 블록을 암호화할 때 사용되는 값을 의미한다.

SELECT encode(encrypt_iv( 'texttext', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaa', 'aes'), 'base64');

=====> 6osdgBzcV5QGBg+umudZwg==

 

이제 복호화를 진행해보자.

select convert_from( decrypt_iv(decode(enc, 'base64'), 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaa', 'aes'),'utf8')

위와같이 암호화의 역순으로 복호화를 해주면 된다.

 

테스트

select convert_from( decrypt_iv(decode(enc, 'base64'), 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaa', 'aes'),'utf8')
FROM (SELECT encode(encrypt_iv( 'texttext', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'aaaaaaaaaaaaaaaa', 'aes'), 'base64') AS enc)  t;


=====> texttext

 

기존 Oracle 암호화 선언

   encrypted_raw      RAW (2000);             -- 암호화된 RAW타입 데이터
   key_bytes_raw      RAW (32);               -- 암호화 KEY (32RAW => 32Byte => 256bit)
   encryption_type    PLS_INTEGER :=          -- 암호화 알고리즘 선언
                            SYS.DBMS_CRYPTO.ENCRYPT_AES256
                          + SYS.DBMS_CRYPTO.CHAIN_CBC
                          + SYS.DBMS_CRYPTO.PAD_PKCS5;

Oracle에선 위와같이 암호화 타입을 지정해주었는데, 비교해보면 Postgresql은 간략하고 직관적인 코딩인 것 같다.

 

여기까지 본래의 목적을 달성함과 더불어, 부족했던 암호화와 인코딩에 대한 지식도 더해진 것 같다.

끗!

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
26 27 28 29 30 31
글 보관함