SSL
정의 :
웹서버와 웹브라우저 사이에 모든 정보를 암호화 해주는 방식
HTTPS라는 통신채널을 사용하며, 모든 웹서버와 웹브라우저가 SSL을 지원
특징 :
상호 인증 : 클라이언트와 서버간의 상호 인증(RSA, DSS, X.509)
기밀성 : 대칭키 암호화 알고리즘을 통한 데이터의 암호화(DES, 3DES, RC4 등)
데이터 무결성 : MAC 기법을 이용해 데이터 변조 여부 확인(HMAC-md5, HMAC-SHA-1)
작동 방법 :
HandShake 라는 루틴을 사용
1. " Client Hello " : 클라이언트가 CipherSuites 및 랜덤 값[해시 기반 난수]을 Server에 전달
CipherSuites란?인증, 키 계약, 암호화 및 무결성 보호에 사용되는 보안 알고리즘 및 키 크기를 정의하는 암호화 매개 변수의 조합
2. " Server Hello " : 클라이언트가 제공한 정보 중 사용 될 항목을 선택 후, 랜덤 값[해시 기반 난수]과 서버의 인증서를 보낸다.
3. " Authorization " : 서버의 인증서를 통해 인증기관을 확인하고 전달받은 랜덤값을 합하여 Pre-Master-Secret을 생성한다.
4. " Client Key Exhange " : 3번에서 생성한 Pre-Master-Secret 을 암호화 한 뒤 클라이언트의 인증서와 함께 서버에 전달한다.
5. " Authorization " : 전달받은 클라이언트의 인증서를 검증한다.
6. " Client Finished " : 클라이언트에게 완료 Alert을 전달한다.
7. " Server Finished " : 서버 측에 완료 Alert 을 전달한다.
8. " Exchange Messages " : 암호화된 메시지를 전달한다.
TLS
정의 : SSL 3.0버전에서 키 생성과 MAC의 계산 방법 등을 좀더 안전한 방법으로 개선하고 구현의 모호함 수정
OPENSSL
공개 키 기반(PKI)의 ITU-T 표준인 인증서 생성 방법 ( X.509 v3 )를 지원
기본적으로 Linux 계열을 지원하며, Window 버전을 다운 받기위해 해당 경로 참조
https://wiki.openssl.org/index.php/Binaries
X.509 v3 디지털 인증서의 구조
-
Certificate
-
Not Before 유효기간 시작 날짜
-
Not After 유효기간 끝나는 날짜
-
Public Key Algorithm 공개 키 알고리즘
-
Subject Public Key
-
-
Version 인증서의 버전을 나타냄
-
Serial Number CA가 할당한 정수로 된 고유 번호
-
Signature 서명 알고리즘 식별자
-
Issuer 발행자
-
Validity 유효기간
-
Subject 소유자
-
Subject Public Key Info 소유자 공개 키 정보
-
Issuer Unique Identifier (Optional) 발행자 고유 식별자
-
Subject Unique Identifier (Optional) 소유자 고유 식별자
-
Extensions (Optional) 확장
-
Certificate Signature Algorithm
-
Certificate Signature
PEM 인코딩 형식
Privacy Enhanced Mail (PEM)
ASCII (Base64)형식의 데이터가 포함되었으며 , -----BEGIN… 으로 시작하며 인증서 파일에 사용
참고 : .key는 PEM 포맷의 파일이지만 키 값이 있는 것을 명시하기 위해 사용
서버 PrivateKey 생성 [ PEM ]
OpenSSL> genrsa -out server.pem
Loading 'screen' into random state - done
Generating RSA private key, 512 bit long modulus
.++++++++++++
..................++++++++++++
unable to write 'random state'
e is 65537 (0x10001)
Private Key 를 이용한 인증서 생성
CERTIFICATE REQUEST (CSR)
인증기관으로 보내 인증서를 발급받게 하는 일종의 신청서
인증서 요청서 작성하기 [ cnf 파일을 읽지 못하여 bin 폴더에 이동 후, config 선언 ]
OpenSSL> req -new -key server.pem -out server.csr -config openssl.cnf
Loading 'screen' into random state - done
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:AU
State or Province Name (full name) [Some-State]:SERVER
Locality Name (eg, city) []:CITY
Organization Name (eg, company) [Internet Widgits Pty Ltd]:internet
Organizational Unit Name (eg, section) []:section
Common Name (eg, YOUR name) []:name
Email Address []:email
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:qwe123
An optional company name []:qwe123
OpenSSL> req -new -key client.der -out client.csr -config openssl.cnf
Loading 'screen' into random state - done
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:AU
State or Province Name (full name) [Some-State]:client
Locality Name (eg, city) []:city
Organization Name (eg, company) [Internet Widgits Pty Ltd]:internet
Organizational Unit Name (eg, section) []:section
Common Name (eg, YOUR name) []:name
Email Address []:email
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
CERTIFICATE (CRT)
Linux 계열에서 주로 사용, PEM or DER 으로 인코딩 될 수 있다.
x509 양식으로 요청 365일 간 sha256 암호화 방식으로 server.pem[개인키]로 인증합니다.
OpenSSL> x509 -req -in server.csr -days 3650 -sha256 -signkey server.pem -out server.crt
Loading 'screen' into random state - done
Signature ok
subject=/C=AU/ST=client/L=city/O=internet/OU=section/CN=name/emailAddress=email
Getting Private key
unable to write 'random state'
CERTIFICATE (CER)
Microsoft 계열에서 주로 사용, PEM or DER 으로 인코딩 될 수 있다.
PRIVATE KEY 생성
Distinguished Encoding Representation (DER)
바이너리 형식으로 인코딩된 인증서.
PKCS8 : 해당 내용은 [ Private-Key Cryptography Standard ] 에 의거하여 개인키에 대한 정보와 속성을 의미
TOPK8 : OPENSSL 내에서 PKCS8과 한쌍으로 쓰이며 PKCS8 file 형태로 나타낸다는 의미이다.
OpenSSL> pkcs8 -topk8 -nocrypt -in server.pem -outform DER -out server.private.der
PUBLIC KEY 생성
X509 구조의 인증서를 넣은 후, 바이너리 형태[DER] PUBLIC.KEY를 추출한다.
OpenSSL> x509 -in server.crt -out server.public.der -outform DER
writing RSA key
KEYTOOL
Java 는 KeyStore 라는 인터페이스를 통해 Private Key, Public Key 와 Certificate 를 추상화하여 제공
Java Key Store (JKS)
자바에서 제공하는 KeyTool을 이용하여 인증서를 생성
1. PrivateKey 와 CERTIFICATE 가 포함된 JKS 생성
keytool -genkey -v -keystore server.jks -alias server_private -keyalg RSA -sigalg sha256withRSA -keysize 1024 -validity 10000
keytool -genkey -v -keystore client.jks -alias client_private -keyalg RSA -sigalg sha256withRSA -keysize 1024 -validity 10000
-v : 결과를 상세하게 보기 옵션이다.
-keystore : 키가 저장될 JKS 파일의 이름
-alias : JKS 안에 저장될 Private Key 값의 별칭을 지정
-sigalg : 인증서의 서명 알고리즘 [ 기본 개인 키의 유형이 RSA이면 -sigalg옵션의 기본값은 SHA256withRSA ]
-keysize : 키값의 길이
-validity : 인증서의 유효기간 - 10000이 1일로 계산한다.
C:\Users\user>keytool -genkey -v -keystore server.jks -alias server_private -keyalg RSA -sigalg sha256withRSA -keysize 1024 -validity 10000
키 저장소 비밀번호 입력:
새 비밀번호 다시 입력:
이름과 성을 입력하십시오.
[Unknown]: 이름
조직 단위 이름을 입력하십시오.
[Unknown]: 부서명
조직 이름을 입력하십시오.
[Unknown]: 업체명
구/군/시 이름을 입력하십시오?
[Unknown]: 무슨 동인지 입력
시/도 이름을 입력하십시오.
[Unknown]: 어느 지역인지 입력
이 조직의 두 자리 국가 코드를 입력하십시오.
[Unknown]: 대한민국
CN=1, OU=q, O=w, L=e, ST=r, C=t이(가) 맞습니까?
[아니오]: 정보값 확인 Y or N
다음에 대해 유효 기간이 10,000일인 1,024비트 RSA 키 쌍 및 자체 서명된 인증서(SHA256withRSA)를 생성하는 중
: CN=1, OU=q, O=w, L=e, ST=r, C=t
<server_private>에 대한 키 비밀번호를 입력하십시오.
(키 저장소 비밀번호와 동일한 경우 Enter 키를 누름):
[server.jks을(를) 저장하는 중]
Warning:
JKS 키 저장소는 고유 형식을 사용합니다. "keytool -importkeystore -srckeystore server.jks -destkeystore server.jks -deststoretype pkcs12"를 사용하는 산업 표준 형식인 PKCS12로 이전하는 것이 좋습니다.
키를 생성하게 되면 C 드라이브에서 실행 시, 접속해 있는 User에 JKS가 생성되며, D 드라이브에서 실행 시킨다면 해당 폴더에 생성
2. 생성 된 JKS 에 대한 리스트 상세 보기
keytool -v -list -keystore server.jks
keytool -v -list -keystore client.jks
keytool -v -list -keystore server.jks
키 저장소 비밀번호 입력:
키 저장소 유형: jks
키 저장소 제공자: SUN
키 저장소에 1개의 항목이 포함되어 있습니다.
별칭 이름: server_private
생성 날짜: 2019. 10. 1
항목 유형: PrivateKeyEntry
인증서 체인 길이: 1
인증서[1]:
소유자: CN=1, OU=q, O=w, L=e, ST=r, C=t
발행자: CN=1, OU=q, O=w, L=e, ST=r, C=t
일련 번호: 5aed18f2
적합한 시작 날짜: Tue Oct 01 10:19:09 KST 2019 종료 날짜: Sat Feb 16 10:19:09 KST 2047
인증서 지문:
MD5: CE:70:27:53:CB:B9:B7:C1:E5:9A:14:22:5D:7B:1E:2D
SHA1: 57:EC:77:C8:E3:B2:05:30:3C:F0:D3:21:F3:35:07:41:F7:75:A6:BB
SHA256: B7:54:97:AA:D3:1B:40:33:B9:15:6F:21:75:69:7C:6B:1A:5B:5A:4D:72:FC:59:0D:CB:5F:BD:DB:D6:99:25:90
서명 알고리즘 이름: SHA256withRSA
주체 공용 키 알고리즘: 1024비트 RSA 키
버전: 3
확장:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D2 DC 41 A1 CD 72 65 5E AC 41 B0 31 E7 44 A4 66 ..A..re^.A.1.D.f
0010: 81 D5 92 E7 ....
]
]
*******************************************
*******************************************
Warning:
JKS 키 저장소는 고유 형식을 사용합니다. "keytool -importkeystore -srckeystore server.jks -destkeystore server.jks -deststoretype pkcs12"를 사용하는 산업 표준 형식인 PKCS12로 이전하는 것이 좋습니다.
3. 상위에 만들어둔 JKS 에서 자체 서명이 된 Public Key 추출
keytool -export -alias server_private -keystore server.jks -rfc -file Server.cer
-alias : 지정할 키의 별칭
-keystore : 지정할 키가 저장된 키 스토어 명
-rfc : 출력 포맷은 64 비트로 인코딩 된 PEM이고 그렇지 않으면 이진 DER이 만들어진다.
-file : 저장할 파일 명
C:\Users\user> keytool -export -alias server_private -keystore server.jks -rfc -file Server.cer
키 저장소 비밀번호 입력:
인증서가 <Server.cer> 파일에 저장되었습니다.
-----BEGIN CERTIFICATE-----
MIICKjCCAZOgAwIBAgIEWu0Y8jANBgkqhkiG9w0BAQsFADBIMQowCAYDVQQGEwF0
MQowCAYDVQQIEwFyMQowCAYDVQQHEwFlMQowCAYDVQQKEwF3MQowCAYDVQQLEwFx
MQowCAYDVQQDEwExMB4XDTE5MTAwMTAxMTkwOVoXDTQ3MDIxNjAxMTkwOVowSDEK
MAgGA1UEBhMBdDEKMAgGA1UECBMBcjEKMAgGA1UEBxMBZTEKMAgGA1UEChMBdzEK
MAgGA1UECxMBcTEKMAgGA1UEAxMBMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEAkT9fXOcX7vfSGBv5nEfwou4wMXQAx9b+rhPsH81oXCs3ud7+r/Lrq8fIyC6k
tLImB4/5KiCtIEYymYOK11aRtZ4EGkOxNHAxeV3Lvo1aWUHWZhLR4kcNQM1GRjZf
TtMNDSH3I+Ai8lSIzR3b0ZUxOme7g178tggAlFWJfKvvkdcCAwEAAaMhMB8wHQYD
VR0OBBYEFNLcQaHNcmVerEGwMedEpGaB1ZLnMA0GCSqGSIb3DQEBCwUAA4GBAFdG
WZus7/Ryh5+Xg9nIaWtLdXQxArm8swew5Cjfo3jpivO5OjfoJXmOgESOJxkxgAqF
/4me7Xh7IwlglaOeYGG/X7Ie0T97GzRV29PgwOUymXOsy0ukk5/cVPxsfNdSh3L1
HQfs1dtK6j+vK0+U57fRmkIOj0ERTHiJkcLNyjta
-----END CERTIFICATE-----
3. TrustStore 생성 [ 나의 PrivateKey와 서명 + 상대방의 Public Key 와 서명이 담긴 JKS ]
keytool -import -alias trustClient -file Client.cer -keystore server.jks
keytool -import -alias trustServer -file Server.cer -keystore client.jks
C:\Users\user>keytool -v -list -keystore server.jks
키 저장소 비밀번호 입력:
키 저장소 유형: jks
키 저장소 제공자: SUN
키 저장소에 2개의 항목이 포함되어 있습니다.
별칭 이름: trustclient
생성 날짜: 2019. 10. 1
항목 유형: trustedCertEntry
소유자: CN=1, OU=q, O=w, L=e, ST=r, C=t
발행자: CN=1, OU=q, O=w, L=e, ST=r, C=t
일련 번호: 758d8625
적합한 시작 날짜: Tue Oct 01 10:50:46 KST 2019 종료 날짜: Sat Feb 16 10:50:46 KST 2047
인증서 지문:
MD5: 0A:09:9B:3B:23:F6:33:F8:C5:0E:79:D0:D2:8E:E7:52
SHA1: CC:C1:A9:7F:34:E6:12:89:56:43:2D:C2:70:ED:B3:76:8D:32:FC:98
SHA256: B7:1F:1E:DC:32:8C:FC:24:91:F8:D7:8B:CD:46:D2:BE:63:B1:27:EC:E0:F1:93:B5:AB:06:29:98:A8:A9:FF:22
서명 알고리즘 이름: SHA256withRSA
주체 공용 키 알고리즘: 1024비트 RSA 키
버전: 3
확장:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: F4 29 4F 32 E4 9A 13 3E 71 4F 9B FA 36 B6 64 C3 .)O2...>qO..6.d.
0010: 04 BE EC 59 ...Y
]
]
*******************************************
*******************************************
별칭 이름: server_private
생성 날짜: 2019. 10. 1
항목 유형: PrivateKeyEntry
인증서 체인 길이: 1
인증서[1]:
소유자: CN=1, OU=q, O=w, L=e, ST=r, C=t
발행자: CN=1, OU=q, O=w, L=e, ST=r, C=t
일련 번호: 5aed18f2
적합한 시작 날짜: Tue Oct 01 10:19:09 KST 2019 종료 날짜: Sat Feb 16 10:19:09 KST 2047
인증서 지문:
MD5: CE:70:27:53:CB:B9:B7:C1:E5:9A:14:22:5D:7B:1E:2D
SHA1: 57:EC:77:C8:E3:B2:05:30:3C:F0:D3:21:F3:35:07:41:F7:75:A6:BB
SHA256: B7:54:97:AA:D3:1B:40:33:B9:15:6F:21:75:69:7C:6B:1A:5B:5A:4D:72:FC:59:0D:CB:5F:BD:DB:D6:99:25:90
서명 알고리즘 이름: SHA256withRSA
주체 공용 키 알고리즘: 1024비트 RSA 키
버전: 3
확장:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D2 DC 41 A1 CD 72 65 5E AC 41 B0 31 E7 44 A4 66 ..A..re^.A.1.D.f
0010: 81 D5 92 E7 ....
]
]
*******************************************
*******************************************
Warning:
JKS 키 저장소는 고유 형식을 사용합니다. "keytool -importkeystore -srckeystore server.jks -destkeystore server.jks -deststoretype pkcs12"를 사용하는 산업 표준 형식인 PKCS12로 이전하는 것이 좋습니다.
1. 만약 PrivateKey 및 인증서가 존재하며 JKS를 만들어야 할 경우, 아래 첨부된 ImportKey.java 내에서 저장될 명칭을 기재한다.
import java.security.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.security.spec.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Collection;
import java.util.Iterator;
public class ImportKey {
private static InputStream fullStream ( String fname ) throws IOException {
FileInputStream fis = new FileInputStream(fname);
DataInputStream dis = new DataInputStream(fis);
byte[] bytes = new byte[dis.available()];
dis.readFully(bytes);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
return bais;
}
public static void main ( String args[]) {
// 해당 JKS 에 대한 password
String keypass = "password";
// 해당 JKS 에 대한 alias
String defaultalias = "alias";
String keystorename = System.getProperty("keystore");
if (keystorename == null)
keystorename = "keystore.ImportKey";----------------------------저장될 Keystore 명칭 기재
// parsing command line input
String keyfile = "";
String certfile = "";
if (args.length < 2 || args.length>3) {
System.out.println("Usage: java comu.ImportKey keyfile certfile [alias]");
System.exit(0);
} else {
keyfile = args[0];
certfile = args[1];
if (args.length>2)
defaultalias = args[2];
}
try {
// initializing and clearing keystore
KeyStore ks = KeyStore.getInstance("JKS", "SUN");
ks.load( null , keypass.toCharArray());
System.out.println("Using keystore-file : "+keystorename);
ks.store(new FileOutputStream ( keystorename ),
keypass.toCharArray());
ks.load(new FileInputStream ( keystorename ),
keypass.toCharArray());
// loading Key
InputStream fl = fullStream (keyfile);
byte[] key = new byte[fl.available()];
KeyFactory kf = KeyFactory.getInstance("RSA");
fl.read ( key, 0, fl.available() );
fl.close();
PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
PrivateKey ff = kf.generatePrivate (keysp);
// loading CertificateChain
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream certstream = fullStream (certfile);
Collection c = cf.generateCertificates(certstream) ;
Certificate[] certs = new Certificate[c.toArray().length];
if (c.size() == 1) {
certstream = fullStream (certfile);
System.out.println("One certificate, no chain.");
Certificate cert = cf.generateCertificate(certstream) ;
certs[0] = cert;
} else {
System.out.println("Certificate chain length: "+c.size());
/**
* Run for through chained certificates
**/
// certs = (Certificate[])c.toArray();
int i = 0;
Iterator it = c.iterator();
while (it.hasNext()) {
certs[i] = (Certificate)it.next();
i++;
}
}
// storing keystore
ks.setKeyEntry(defaultalias, ff,
keypass.toCharArray(),
certs );
System.out.println ("Key and certificate stored.");
System.out.println ("Alias:"+defaultalias+" Password:"+keypass);
ks.store(new FileOutputStream ( keystorename ),
keypass.toCharArray());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
3. 해당 클래스안에 인증이 완료된 Private Key 와 Public Key를 넣는다.
C:\openssl\bin>java ImportKey server.private.der server.public.der
Using keystore-file : C:\Users\user\openssl_server.jks
One certificate, no chain.
Key and certificate stored.
Alias:NsH_keystore Password:nsh
'IT > ETC' 카테고리의 다른 글
OPENSSL 과 KEYSTORE (0) | 2020.11.10 |
---|---|
Windows에서 core process 수 지정하는 방법 (0) | 2019.08.16 |
Window10 파티션 분할 (0) | 2019.05.16 |