https를 지원하는 웹서버를 설정하거나 서명이나 암호화 관련된 개발을 하게되면 한번씩 인증서 관련된 파일을 다룰 일이 생기게 된다. 이때 항상 프로그램이나 라이브러리들이 지원하는 형식이 달라서 인증서 형식을 변환해아 하는데 현재 갖고있는 파일의 형식이 무엇인지를 알아야 제대로 활용이 가능하다. 인증서 파일의 경우 인코딩 방식과 확장자가 일치하는 경우도 있고, 그렇지 않은 경우도 있기 때문에 아래와 같이 비교해서 정리해 보았다.
인코딩 (확장자로 쓰이기도 한다.)
.der:
.pem: X.509 v3 파일의 한 형태
-----BEGIN XXX-----, -----END XXX----- 로 묶여있는 text file을 보면 이 형식으로 인코딩 되어있다고 생각하면 된다. (담고있는 내용이 무엇인지에 따라 XXX 위치에 CERTIFICATE, RSA PRIVATE KEY 등의 키워드가 들어있다)확장자
.crt, .cer 인증서를 나타내는 확장자인 cer과 crt는 거의 동일하다고 생각하면 된다. (cer은 Microsoft 제품군에서 많이 사용되고, crt는 unix, linux 계열에서 많이 사용된다.)
.key: 개인 또는 공개 PKCS#8 키를 의미.p12: PKCS#12 형식으로 하나 또는 그이상의 certificate(public)과 그에 대응하는 private key를 포함하고 있는 key store 파일이며 패스워드로 암호화 되어있다. 열어서 내용을 확인하려면 패스워드가 필요하다..pfx: PKCS#12는 Microsoft의 PFX파일을 계승하여 만들어진 포멧이라 pfx와 p12를 구분없이 동일하게 사용하기도 한다.참고: PEM 방식으로 인코딩된 pkcs8 형식(format) 비밀키(private key)를 암호화되지 않은 DER 인코딩으로 변경하는 명령어
openssl pkcs8 -topk8 -inform PEM -outform DER -in private.key -out private.der -nocrypt
암호화 복호화 코드를 작성해본 사람이라면 분명히 Padding과 관련된 코드를 한번이라도 보았을 것이다. 이름이 전혀 직관적이지 않다보니 처음 접했을 때는 도데체 뭘 의미하는지 알기가 어려웠지만 하나씩 차근차근 알아보도록 하자.
대칭키 알고리즘(ex: AES)을 사용 할 때 암호화 하려는 데이터의 길이가 긴 경우 ECB (Electronic Codebook), CBC(Cipher Block Chain) 등의 block cipher 방식을를 사용해서 데이터를 암호화 하게된다. 블록단위로 잘라서 암호화/복호화가 진행되기 때문에 정해진 마지막 블록의 사이즈와 실제 데이터의 크기가 맞지 않는 경우가 생길 수 있다. 이때 마지막 블록의 빈 공간을 채워넣는(padding) 방식을 말한다.
예를 들어 데이터가 17바이트인데 block size가 8바이트라면 총 3개의 블록이 필요하고 마지막 블록은 7바이트가 남기때문에 이부분을 특정 값으로 채워넣어서 암호화를 진행한다.
PKCS5Padding과 PKCS7Padding 둘다 빈 공간에 값을 채워넣는 규칙은 다음과 같다.
01을 채워넣고 (01은 1바이트를 16진수 표기한 값)02 02를 채워넣음03 03 03를 채워넣음대신 PKCS5Padding과 PKCS7Padding의 경우 block size의 제약 조건이 다르다.
PKCS1Padding는 앞서말한 PKCS5Padding/PKCS7Padding과는 방식도 다르고 사용처도 다르다. PKCS1Padding는 보통 RSA 알고리즘과 같이 사용되며 PKCS#1 v1.5 에 명시된 padding 방법을 사용한다.
Java에서 제공하는 Crypto 라이브러리의 경우 Cipher.getInstance("algorithm/mode/padding") 형식의 스트링으로 암호화 알고리즘, 모드, 패딩방식을 결정할 수 있다. 참고로 데이터의 길이가 길어서 (블럭의 갯수가 하나 이상)인 경우 ECB는 보안성이 취약하니 CBC를 꼭 사용해야 한다. (각 블럭의 데이터가 섞이지 않은 상태로 동일한 암호화를 적용하면 데이터에 패턴이 나타나게됨)
예시)
인증서의 정보를 보거나(View), 다른 포멧으로 변환(Transform), 합침(Combination) 등의 조작을 하기위해서 openSSL 명령어를 사용할 수 있다.
(openssl 명령어의 경우 inform 옵션이 따로 지정되지 않은경우 PEM형식으로 처리를 시도한다.)
View
Transform
Combination
외부 인증기관에서 인증서를 전달받지 않고, 내부적으로 사용할 RSA 키 페어가 필요하다면 아래 설명된 절차를 통해서 간단하게 키 페어를 만들어 낼 수 있다.
openssl genrsa -des3 -out private.pem 2048
private.pem파일을 열어보면 -----BEGIN RSA PRIVATE KEY----- 로 표시되는 것을 확인 할 수 있다.
RSA private key로부터 public key를 만들어 낼 수 있다. 어떻게 그게 가능한지 보기 위해서 아래 명령어를 사용해보자.
openssl rsa -text -in private.pem
위 명령어로 출력된 결과에 public key를 정의하는데 필요한 modulus와 publicExponent정보가 포함되어있는것을 알 수있다. 실제로 private key로부터 public key를 추출하기 위해서 다음 단계를 살펴보자.
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
public.pem 파일을 열어서 -----BEGIN PUBLIC KEY----- 로 표시되는것을 확인 하면 된다.