Skip to content

OpenSSL

OpenSSL은 네트워크를 통한 데이터 통신에 쓰이는 프로토콜인 TLS와 SSL의 오픈 소스 구현판이다. C 언어로 작성되어 있는 중심 라이브러리 안에는, 기본적인 암호화 기능 및 여러 유틸리티 함수들이 구현되어 있다.

Category

Password security

Algorithms

E.T.C

Libraries

Terms/Formats

인터넷을 통해 보안을 보장하는 데 사용되는 인증서에는 여러 포맷이 있습니다. 다음은 여러 다른 유형의 인증서를 빠르게 설명한 것입니다.

Abstract Syntax Notation One (ASN.1)
추상 구문 기법, 네트웍상의 데이터 교환을 정의한 프로토콜
Basic Encoding Rules (BER; .ber)
BER(Basic Encoding Rules) 포맷은 ASN.1 표준의 일부로서 정의되는 인코딩 포맷 중 하나입니다. 이것은 추상적인 정보를 구체적인 데이터 스트림으로 인코딩하기 위한 표준입니다. BER와 DER(Distinguished Encoding Rules) 및 CER(Canonical Encoding Rules) 하위 세트 두 개입니다.
Certificate Authority (CA)
인증 기관
Certificate File (.crt, .cer)
CRT - Security Certificate File Format
security CeRTificate file, 줄여서 crt를 사용한다.
확장자가 .crt 또는 .cer인 파일에는 바이너리 데이터의 포맷을 지정하기 위한 ASN.1 표준에 의해 정의되는 일련의 규칙인 DER(Distinguished Encoding Rules)를 사용하는 단일 X.509 인증이 포함되어 있습니다.
인증서 파일이다 라는 의미로 붙이며, 거의 대부분 PEM 포맷이며, 주로 유닉스/리눅스 기반 시스템에서 통용되는 확장자 이다. cer 확장자를 붙이기도 한다. (.crt 확장자 보다는 파일 포맷이 명확하도록 .pem 또는 .der 붙이는걸 권장)
.cer 파일은 대부분 PEM 포맷이며 바이너리 포맷일때도 있으며, 주로 Windows 기반에서 인증서 파일임을 구분하기 위해서 사용되는 확장자 이다. crt 확장자와 거의 동일한 의미이며, cer 이나 crt 확장자 모두 윈도우에서는 기본 인식되는 확장자이다. 저장할때 어떤 포맷으로 했는지에 따라 다르며, 파일 생성자가 이름 붙이기 나름이다.
Certificate Revocation List (CRL) / Online Certificate Status Protocol (OCSP)
인증서 유효성 점검을 위한 표준/방법
Certificate Signing Request (CSR; .csr)
거의 대부분 PEM 포맷이다. SSL 발급 신청을 위해서 본 파일 내용을 인증기관 CA 에 제출하는 요청서 파일임을 구분하기 위해서 붙이는 확장자 이다. (Base64 Text 파일)
Distinguished Encoding Rules (DER) .der
DER(Distinguished Encoding Rules) 포맷은 암호화에 사용되어 X.509 인증과 같이 디지털 방식으로 서명해야 하는 데이터가 고유한 일련 번호를 가진 표식을 생성하도록 보장합니다. DER 포맷을 사용하면 X.509 인증의 서명과 검증이 가능해집니다.
Distinguished Encoding Representation (DER) 의 약자이며, 바이너리 포맷이다. 바이너리 인코딩 포맷을 읽을수 있는 인증서 라이브러리를 통해서만 내용 확인이 가능하다. 사설 또는 금융등 특수 분야 및 아주 오래된 구형 시스템을 제외하고는, 최근 웹서버 SSL 작동 시스템 에서는 흔히 사용되는 포맷은 아니다. (바이너리 이진 파일)
Elliptic Curve Digital Signature Algorithm (ECDSA)
타원곡선을 이용한 전자서명 알고리즘
Java Key Store (.jks)
Java 기반의 독자 인증서 스토어 포맷이다. pfx 와 마찮가지로 개인키+서버인증서+루트인증서+체인인증서를 모두 담을수 있어서 SSL 인증서 파일 관리시 유용하다. Java 기반의 Tomcat 서버에서 SSL 적용시 가장 많이 사용되는 포맷이다. (예, sslcert.co.kr_xxx.jks) (바이너리 이진 파일) (jks 등은 인증서라기 보다는 인증서를 모아 놓은 저장소,스토어,바구니 용도 파일)
Key File (.key)
주로 openssl 및 java 에서 개인키 파일임을 구분하기 위해서 사용되는 확장자이다.
PEM 포맷일수도 있고 DER 바이너리 포맷일수도 있으며, 파일을 열어봐야 어떤 포맷인지 알수가 있다.
저장할때 어떤 포맷으로 했는지에 따라 다르며, 확장자는 이름 붙이기 나름이다. (예, sslcert.co.kr_xxx.key.pem)
Privacy-enhanced Electronic Mail (Privacy Enhanced Mail, PEM)
.pem은 Base64 인코딩된 ASCII 텍스트 이다. 또는 Privacy Enhanced Mail은 공용 키 암호화를 사용하여 이메일을 보안하기 위한 포맷입니다. 이것은 S/MIME 메시지 헤더에서의 사용을 허용하는 텍스트 전용 인코딩입니다. .pem 포맷은 텍스트 헤더에 의해 둘러 싸여 있는 X.509 인증(바이너리 DER 포맷)의 base64 인코딩입니다.
개인키, 서버인증서, 루트인증서, 체인인증서 및 CSR 등 SSL 관련 모든 과정에서 사용되는 기본 포맷이며, 가장 광범위하고 거의 99% 시스템에 호환되는 산업 표준 포맷이다. (대부분 Base64 Text 파일)
Public Key Cryptography Standards (PKCS)
Private Key를 저장하는 문법에 관한 표준
PKCS#1, PKCS#8, PKCS#12 등을 사용
Public Key Cryptography Standard #7 (PKCS#7; .p7b, .p7c, .p7s)
확장자가 .p7b인 파일에는 한 개 이상의 X.509 인증이 포함되어 있는 PKCS#7(Public Key Cryptography Standard #7) 메시지가 들어 있습니다. S/MIME 보안 메일 표준은 디지털 방식으로 서명되고 암호화된 메시지에 대해 PKCS#7을 사용합니다.
PKCS#7 포맷이며, '서버인증서+루트인증서+체인인증서' 를 모두 담을수 있어서 SSL 인증서 적용이나 또는 이전시 상당히 유용하고 편리하다. Windows 에서는 자동으로 인식하며, 일부 서버에서는 p7b 포맷으로만 인증서 설정이 되는 경우가 있다. (Base64 Text 파일) (pfx 와 달리 p7b 는 개인키가 포함되지 않음) (일부에서는 .p7c 라는 확장자를 붙이기도 함) (예, sslcert.co.kr_xxx.p7b) (p7b 등은 인증서라기 보다는 인증서를 모아 놓은 저장소,스토어,바구니 용도 파일)
Public Key Cryptography Standard #12 (PKCS#12; .p12, .pfx)
확장자가 .p12인 파일에는 PKCS#12(Public Key Cryptography Standard #12)를 준수하는 암호화된 파일 포맷이 들어 있습니다. 이것은 사용자의 개인 키, 인증서, 기타 기밀 정보들을 저장 또는 운송하기 위한 휴대용 포맷입니다. 이 표준은 공용/개인 키 사용에서부터 암호 기반 개인 보호 형식의 낮은 보안에 이르는 몇 가지 개인 정보 보호 및 무결성 모드 하에 직접적인 개인 정보의 전송을 지원합니다.
PKCS#12 바이너리 포맷의 인증서 스토어 이며, Personal Information Exchange Format 를 의미한다. 주로 Windows IIS 기반에서 인증서 적용/이동시 활용된다. 주요 장점으로는 개인키,서버인증서,루트인증서,체인인증서를 모두 담을수 있어서 SSL 인증서 적용이나 또는 이전시 상당히 유용하고 편리하다. Tomcat 등 요즘에는 pfx 설정을 지원하는 서버가 많아지고 있다. (예, sslcert.co.kr_xxx.pfx) (바이너리 이진 파일) (pfx/p12 등은 인증서라기 보다는 인증서를 모아 놓은 저장소,스토어,바구니 용도 파일)
Public Key Infrastructure (PKI)
공개키 기반 구조
Rivest–Shamir–Adleman (RSA)
공개키 암호시스템의 하나
X.509
공개키 인증서와 인증 알고리즘을 사용하기 위한 PKI 표준

파일 확장자 저장 패턴

  • 인코딩에 따른 구분
    • Distinguished Encoding Representation (DER; .der) - ASN.1을 표현하는 방식의 종류. (바이너리로 저장됨)
    • Privacy Enhanced Mail (PEM; .pem) - Base64로 인코딩된 ASCII 텍스트 (표준으로 더 자주 사용됨)
  • 내용에 따른 구분
    • Private Key (.key) - 개인키
    • Certificate (.cer는 Windows 에서 주로 사용, .crt는 *NIX 에서 주로 사용) - 인증서
    • PKCS #12 (.p12, .pfx) - 하나의 파일에 개인키, 인증서 등을 같이 저장하는 방식에 대한 표준
    • Certificate Signing Request (.csr) - 인증서 발급을 위해 내 개인키 서명을 CA에게 보내기 위한 파일
    • Serial (.srl) - CA가 인증서를 발급할 때 Serial 을 관리하기 위한 파일

인증서 추출하기

openssl을 사용하여 HTTPS로 연결하는 서버의 SSL 인증서를 아래와 같이 출력할 수 있다.

#!/usr/bin/env bash

if [[ -z $(which openssl) ]]; then
    echo "Not found openssl."
    exit 1
fi

SERVER_HOST=$1
SERVER_PORT=${2:-443}
if [[ -z $SERVER_HOST || -z $SERVER_PORT ]]; then
    echo "Usage: $0 {server_host} {server_port:443}"
    exit 1
fi

echo "QUIT" | openssl s_client -connect "$SERVER_HOST:$SERVER_PORT" 2>&1 | openssl x509 -inform PEM -text

출력 결과를 CA 목록에 추가하면 된다. 위 스크립트 파일을 get-server-certificate로 저장한 후 아래와 같이 실행한다.

## Ubuntu:
$ sudo ./get-server-certificate nexus.local > /etc/ssl/certs/nexus.local

신뢰할수 있는 루트 인증서 등록 하는 법

OpenSSL:X509#신뢰할수 있는 루트 인증서 등록 하는 법 항목 참조.

Command-line example

Convert format

PEM -> DER
x509 -inform PEM -in 변환할파일명.pem -out 변환된파일명.der
DER -> CRT
x509 -inform DER -in 변환할 파일명.der -out 변환된파일명.crt

How to create a certificate

인증서 생성 방법에 대하여 정리한다.

Self Signed Certificate bash script

한번에 개인키(private.key)와 인증서(certificate.crt)가 생성되는 스크립트는 아래와 같다.

$ openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:4096 -keyout private.key -out certificate.crt -subj '/CN=localhost'

인증서 파일은 아래와 같이 읽을 수 있다.

$ openssl x509 -text -noout -in certificate.crt

스크립트로 작동시키고 싶을 경우 아래의 내용을 참조.

#!/bin/bash

echo "###########################################"
echo "## Generate Self Signed Certificate(SSC) ##"
echo "###########################################"

if [[ -z $(which openssl) ]]; then
    echo "Not found openssl."
    exit 1
fi

DAYS=36500 ## 100 years
KEYSIZE=2048
#KEYSIZE=4096
PRIVATE_KEY_FILE=$CERTS_DIR/onlyoffice.key
REQUEST_FILE=$CERTS_DIR/onlyoffice.csr
CERTIFICATE_FILE=$CERTS_DIR/onlyoffice.crt

COUNTRY=NO
STATE=NO
LOCATION=NO
ORGANIZATION=NO
ORGANIZATIONAL_UNIT=NO
COMMON_NAME=NO

## sets certificate subject
SUBJ="/C=${COUNTRY}/ST=${STATE}/L=${LOCATION}/O=${ORGANIZATION}/OU=${ORGANIZATIONAL_UNIT}/CN=${COMMON_NAME}"

## Create the server private key
openssl genrsa -out "$PRIVATE_KEY_FILE" $KEYSIZE

## Create the certificate signing request (CSR)
openssl req -new -sha256 -key "$PRIVATE_KEY_FILE" -out "$REQUEST_FILE" -subj "${SUBJ}"

## Sign the certificate using the private key and CSR
openssl x509 -req -sha256 -days $DAYS -in "$REQUEST_FILE" -signkey "$PRIVATE_KEY_FILE" -out "$CERTIFICATE_FILE"

## Check a certificate.
openssl x509 -in "$CERTIFICATE_FILE" -text -noout

echo Done.

Strengthening the server security

This section provides you with instructions to strengthen your server security. To achieve this you need to generate stronger DHE parameters.

$ openssl dhparam -out "$DHPARAM_FILE" 2048

SSL 작동 원리

Process_of_the_SSL_certificates.jpg

개인키를 생성한다. Triple DES (-des3)보다 AES를 사용하자.2

$ openssl genrsa -aes256 -out server.key 2048

인증 요청서 CSR (Certificate Signing Request)파일을 생성한다.

$ openssl req -new -key server.key -out server.csr

패스워드 제거는 선택사항이다. 제거를 안한다면 Httpd등에서 인증서에 접근할 일이 생기면(ex. 재부팅)암호를 입력해야 한다.

$ openssl rsa -in server.key -out server.key.insecure

사설 인증서(CRT)를 생성한다.

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

sigkey flag

사설인증서를 생성할 때 -signkey옵션을 사용해 개인키를 전달하는데, 인증절차상 사설기관에서 요구하는 파일은 CSR파일과 공개키인 것을 감안하면 이상하게 생각될 수 있다. 이 내용에 대해선 메뉴얼 페이지에서 확인 가능하다.

-signkey filename

    this option causes the input file to be self signed using the supplied private key.

    If the input file is a certificate it sets the issuer name to the subject name (i.e. makes it self signed) changes the public key to the supplied value and changes the start and end dates. ...

즉, 내부적으로 공개키를 만든다.

Config file

Hot to use API

Examples

openssl rsa -in key.pem -out keyout.pem
To remove the pass phrase on an RSA private key
openssl rsa -in key.pem -des3 -out keyout.pem
To encrypt a private key using triple DES
openssl rsa -in key.pem -outform DER -out keyout.der
To convert a private key from PEM to DER format
openssl rsa -in key.pem -text -noout
To print out the components of a private key to standard output
openssl rsa -in key.pem -pubout -out pubkey.pem
To just output the public part of a private key
openssl rsa -in key.pem -RSAPublicKey_out -out pubkey.pem
Output the public part of a private key in RSAPublicKey format

Generate private key from an existing crt file

간단한 예는 아래와 같다.

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
       -keyout mysitename.key -out mysitename.crt

RSA 개인키, 공개키 생성

## 개인키:
$ openssl genrsa -out private.pem 1024

## 개인키를 이용한 공개키 생성:
$ openssl rsa -in private.pem -out public.key -pubout -outform derwriting RSA key
  • -des, -seed, -aes256, ...: 해당하는 방식으로 키 암호화. 미사용시 암호화 X
  • -passout pass:PASSWORD: 키를 암호화할 경우 암호 지정. 미사용시 입력 프롬프트가 뜸
  • -f4 (0x10001), -3: E value 지정. 기본값: -f4
  • 1024, 2048, 3072, 4096, ...: Private Key Bit 크기.

CSR 만들기

openssl req -new -key key.pem -out my.csr
  • -md5, -sha1, -sha256, ...: 서명에 사용할 Digest. 기본값은 버전마다 다르고 적당히 sha256 사용. 전체 목록은 openssl dgst -h
  • -subj: 인증서 주제 설정. 미사용시 입력 프롬프트 표시
    • Example: -subj "/C=KR/O=sho/CN=SHO Certificate"
    • /C= - 국가
    • /ST= - State, 한국이라면 시/도
    • /L= - Location
    • /O= - Organization, 회사명
    • /OU= - Organization Unit, 부서명
    • /CN= - Common Name

CSR로부터 인증서 생성

X.509 V3 확장 설정 (아래에서 사용할 ca.ext, end.ext 파일)

Web TLS 인증서 (CA용; ca.ext):

basicConstraints = critical, CA:TRUE
#basicConstraints = critical, CA:TRUE, pathlen:0

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = cRLSign, keyCertSign

Web TLS 인증서 (End-entity; 사이트용; end.ext):

basicConstraints = critical, CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = DNS:blog.iolate.kr, IP:1.1.1.1

CA 인증서 생성:

openssl x509 -req -days 3650 -extfile ca.ext -signkey key.pem -in my.csr -out root.crt
  • -set_serial 1: 시리얼 값 지정. 미지정시 임의값 생성
  • -md5, -sha1, -sha256, ...: 서명에 사용할 Digest. 전체 목록은 openssl dgst -h
    • 직접 신뢰 설정을 하는 Root CA 가 아니라면, sha256 사용. sha1 등 취약한 digest 사용시 브라우저에서 경고함

End-entity 인증서 생성:

openssl x509 -req -days 365 -extfile end.ext -CA root.crt -CAcreateserial -CAkey my.key -in my.csr -out end.crt
openssl x509 -req -days 365 -extfile end.ext -CA root.crt -CAserial root.srl -CAkey my.key -in my.csr -out end.crt
  • -CAcreateserial: 시리얼 자동 지정 및 시리얼 파일 생성 (.srl)
  • -CAserial root.srl: CAcreateserial 로 한번 발급한 이후에는 이 옵션으로 시리얼 생성 파일 입력
  • -md5, -sha1, -sha256, ...: 서명에 사용할 Digest. sha1 등 취약한 digest 사용시 브라우저에서 경고함

생성된 파일 정보 확인

CSR / 인증서 / 개인키

openssl [req/x509/rsa] -noout -text -in [my.csr/end.crt/my.key]
openssl [req/x509/rsa] -noout -modulus -in [my.csr/end.crt/my.key] | openssl md5

파일 암호화

개인키 파일 암호화

$ openssl aes-256-cbc -in secret.txt -out secret.txt.enc
$ openssl aes-256-cbc -d -in secret.txt.enc -out secret.txt

Chiper 목록은 openssl --help로 확인.

공개키 파일 암호화

Encrypt a file using a public SSH key

## Generate the symmetric key (32 bytes gives us the 256 bit key):
$ openssl rand -out secret.key 32
## Encrypt the file you’re sending, using the generated symmetric key:
$ openssl aes-256-cbc -in secretfile.txt -out secretfile.txt.enc -pass file:secret.key
## Encrypt the symmetric key, using the recipient’s public SSH key:
$ openssl rsautl -encrypt -oaep -pubin -inkey <(ssh-keygen -e -f recipients-key.pub -m PKCS8) -in secret.key -out secret.key.enc
## Delete the unencrypted symmetric key, so you don’t leave it around:
$ rm secret.key

Decrypt a file encrypted with a public SSH key

## First decrypt the symmetric.key:
$ openssl rsautl -decrypt -oaep -inkey ~/.ssh/id_rsa -in secret.key.enc -out secret.key
## Now the secret file can be decrypted, using the symmetric key:
$ openssl aes-256-cbc -d -in secretfile.txt.enc -out secretfile.txt -pass file:secret.key

Troubleshooting

x509: certificate signed by unknown authority

OpenSSL:X509#certificate signed by unknown authority항목 참조.

error:0A000126:SSL routines::unexpected eof while reading

Ubuntu 22.04의 OpenSSL 문제인 것 같습니다.

sudo apt update
sudo apt upgrade -y

-_- ;; 엥?

List of Block cipher

블록 암호 (Block cipher)

알고리즘

3-Way, AES, Akelarre, 아누비스, 아리아, 블로피시, 카멜리아, CAST-128, CAST-256, CMEA, CS-Cipher, DEAL, DES, DES-X, FEAL, FOX, FROG, G-DES, GOST, ICE, IDEA, 이라크 블록 암호, KASUMI, KHAZAD, Khufu and Khafre, LOKI89/91, LOKI97, 루시퍼, MacGuffin, Madryga, MAGENTA, MARS, MISTY1, MMB, NewDES, Noekeon, RC2, RC5, RC6, REDOC, 레드 파이크, S-1, SAFER, SEED, Serpent, SHACAL, SHARK, Skipjack, 스퀘어, TEA, 3DES, 투피시, XTEA

설계

파이스텔 암호, 키 스케줄, Product cipher, S-box, SPN

암호해독

무차별 대입 공격, 선형 공격 / 차분 공격, Mod n, Related key, XSL

표준

AES process, CRYPTREC NESSIE

기타

쇄도 효과, 블록 크기, 초기화 벡터(IV), 키 크기, 운용 방식, Piling-up lemma, 취약 키

See also

Favorite site

License issue

OpenSSL C Programming

Guide

References


  1. IT_story_web_-_what_is_ssl.zip 

  2. 대칭키 암호화 (5) - AES, 3DES 

  3. Jopenbusiness-OpenSSL.pdf 

  4. Opentutorials-HTTPS_and_SSL.pdf 

  5. Apache_-create_CSR_and_apply_ssl-_HanbiroSSL.pdf 

  6. Linux_personal_signature_generation_SSL_certificates_-_Zetawiki.pdf 

  7. Generating_keys_and_certificate_signing_requests_-Web_Fundamentals-_Google_Developers.pdf 

  8. Solanara-OpenSSL.pdf