cbed7b9ddac5f28840372b86759bf576.ppt
- Количество слайдов: 46
6. Authentication 데이타베이스 실험실 김희수, 백주현 1
Contents n Message Digests n MACs n Signatures n Certificates 2
Introduction n Authentication l 신원을 증명하는 과정 l 사례 u 자동 현금 인출기 u 신용 카드 u 비디오 숍 n Cryptographic concepts l Message digests l Digital signatures l Certificates 3
Message Digest (1/6) n 입력 데이타가 일방향 함수를 통해서 축약된 데이타 n Getting l l n public static Message. Digest get. Instance(String algorithm) throws No. Such. Algorithm. Exception public static Message. Digest get. Instance(String algorithm, String provider) throws No. Such. Algorithm. Exception, No. Such. Provider. Exception Feeding l public void update(byte input) l public void update(byte[] input, int offset, int len) 4
Message Digest (2/6) n Digesting l l public byte[] digest(byte[] input) l n public byte[] digest( ) public void reset( ) One, Two, Three! // Define byte[] input. Data first. Message. Digest md = Message. Digest. get. Instance(“SHA”) ; md. update(input. Data) ; byte[] digest = md. digest( ) ; 5
Message Digest (3/6) n Digest Streams // Obtain a message digest object. Message. Digest md = Message. Digest. get. Instance(“MD 5”) ; // Calculate the digest for the given file. File. Input. Stream in = new File. Input. Stream(args[0]) ; byte[ ] buffer = new byte[8192] ; int length; while (( length = in. read(buffer)) != -1) md. update(buffer, 0 , length) ; byte[ ] raw = md. digest( ) ; 6
Message Digest (4/6) // Obtain a message digest object. Message. Digest md = Message. Digest. get. Instance(“MD 5”) ; // Calculate the digest for the given file. Digest. Input. Stream in = new Digest. Input. Stream(new File. Input. Stream(args[0], md) ; byte[ ] buffer = new byte[8192]; while (in. read(buffer) != -1) ; byte[ ] raw = md. digest( ) ; 7
Message Digest (5/6) n Protected Password Login l 클라이언트 u message digest 생성 및 전송 l 서버 umessage digest 검증 Client Network name random number timestamp password digest algorithm 8
// 클라이언트 프로그램 // import Protection ; public class Protected. Client { public void send. Authentication(String user, String password, Output. Stream out. Stream) throws IOException, No. Such. Algorithm. Exception { Data. Output. Stream out = new Dataoutput. Stream(out. Stream) ; long t 1 = (new Date( ) ). get. Time( ) ; double q 1 = Math. random ( ) ; byte[ ] protected 1 = Protection. make. Digest(user, password, t 1, q 1) ; out. write. UTF(user) ; out. write. Long(t 1) ; out. write. Double(q 1) ; out. write. Int(protected 1. length) ; out. write(protected 1) ; out. flush( ) ; } 9
public static void main(String[ ] args) throws Exception { String host = args[0] ; int port = 7999 ; String user = “Jonathan” ; String password = “buendia” ; Socket s = new Socket(host, port) ; Protected. Client client = new Protected. Client( ) ; Client. send. Authentication(user, password, s. get. Output. Stream( ) ) ; s. close( ) ; } } 10
// Protection 클래스 // public class Protection { public static byte[ ] make. Digest (String user, String password, long t 1, double q 1) throws No. Such. Algorithm. Exception { Message. Digest md = Message. Digest. get. Instance(“SHA”) ; md. update(user. get. Bytes( ) ) ; md. update(password. get. Bytes( ) ) ; md. update(make. Bytes ( t 1, q 1 ) ) ; return md. digest ( ) ; } public static byte[ ] make. Bytes (long t, double q ) { try { Byte. Array. Output. Stream byte. Out = new Byte. Array. Output. Stream( ) ; Data. Output. Stream data. Out = new Data. Output. Stream(byte. Out) ; data. Out. write. Long ( t ) ; data. Out. write. Double ( q ) ; return byte. Out. to. Byte. Array ( ) ; } catch (IOException e ) { return new byte [0] ; } } } 11
// 서버 프로그램 // import Protection ; public class Protected. Server { public boolean authenticate(Input. Stream in. Stream) throws IOException, No. Such. Algorithm. Exception { Data. Input. Stream in = new Data. Input. Stream(in. Stream) ; String user = in. read. UTF ( ) ; long t 1 = in. read. Long ( ) ; double q 1 = in. read. Double ( ) ; int length = in. read. Int ( ) ; byte[ ] protected 1 = new byte[length] ; in. read. Fully(protected 1) ; String password = lookup. Password(user) ; byte[ ] local = Protection. make. Digest(user, password, t 1, q 1) ; return Message. Digest. is. Equal(protected 1, local) ; } 12
protected String lookup. Password(String user) { return “buendia” ; } public static void main(String[ ] args ) throws Exception { int port = 7999 ; Server. Socket s = new Server. Socket( port ) ; Socket client = s. accept ( ) ; Protected. Server server = new Protected. Server ( ) ; if (server. authenticate (client. get. Input. Stream ( ) ) ) System. out. println(“Client logged in. ”) ; else System. out. println(“Client failed to log in. ”) ; s. close ( ) ; } } 13
Message Digest (6/6) n Double-Strength Password Login Client Network name random number timestamp password random number 2 timestamp 2 digest algorithm 14
// 추가된 클라이언트 프로그램 // public void send. Authentication(String user, String password, Output. Stream out. Stream) throws IOException, No. Such. Algorithm. Exception { Data. Output. Stream out = new Dataoutput. Stream(out. Stream) ; long t 1 = (new Date( ) ). get. Time( ) ; double q 1 = Math. random ( ) ; byte[ ] protected 1 = Protection. make. Digest(user, password, t 1, q 1) ; long t 2 = (new Date( ) ). get. Time( ) ; double q 2 = Math. random( ) ; byte[ ] protected 2 = protection. make. Digest(protected 1, t 2, q 2) ; out. write. UTF(user) ; out. write. Long(t 1) ; out. write. Double(q 1) ; out. write. Long(t 2) ; out. write. Double(q 2) ; out. write. Int(protected 2. length) ; out. write(protected 2) ; out. flush( ) ; } 15
// 추가된 Protection 클래스 // public static byte[ ] make. Digest (byte[ ] mush, long t 2, double q 2) throws No. Such. Algorithm. Exception { Message. Digest md = Message. Digest. get. Instance (“SHA” ) ; md. update(mush) ; md. update(make. Bytes ( t 2, q 2 ) ) ; return md. digest ( ) ; } 16
// 추가된 서버 프로그램 // public boolean authenticate(Input. Stream in. Stream) throws IOException, No. Such. Algorithm. Exception { Data. Input. Stream in = new Data. Input. Stream(in. Stream) ; String user = in. read. UTF ( ) ; long t 1 = in. read. Long ( ) ; double q 1 = in. read. Double ( ) ; long t 2 = in. read. Long( ) ; double q 2 = in. read. Double( ) ; int length = in. read. Int ( ) ; byte[ ] protected 2 = new byte[length] ; in. read. Fully(protected 2) ; String password = lookup. Password(user) ; byte[ ] local 1 = Protection. make. Digest(user, password, t 1, q 1) ; byte[ ] local 2 = Protection. make. Digest(local 1, t 2, q 2 ) ; return Message. Digest. is. Equal(protected 2, local 2) ; } 17
MACs(1/3) n 입력 데이타와 키를 기반으로 짧은 요약 값 생성 n Setting Up l public static final Mac get. Instance(String algorithm) throws No. Such. Algorithm. Exception l public static final Mac get. Instance(String algorithm, String provider) throws No. Such. Algorithm. Exception, No. Such. Provider. Exception l public final void init(Key key) throws Invalid. Key. Exception l public final void init(Key key, Algorithm. Parameter. Spec params) throws Invalid. Key. Exception, Invalid. Algorithm. Parameter. Exception 18
MACs (2/3) n Feeding l l public final void update(byte[ ] input) throws Illegal. State. Exception l n public final void update(byte input) throws Illegal. State. Exception public final void update(byte[ ] input, int offset, int len) throws Illegal. State. Exception Calculating the Code l public final byte[ ] do. Final( ) throws Illegal. State. Exception l public final void do. Final(byte[ ] output, int out. Offset) throws Illegal. State. Exception, Short. Buffer. Exception l public final byte[ ] do. Final(byte[ ] input) throws Illegal. State. Exception l public final void reset( ) 19
MACs (3/3) n For Instance Secure. Random sr = new Secure. Random( ) ; byte[ ] key. Bytes = new byte[20] ; sr. next. Bytes(key. Bytes) ; Secret. Key key = new Secret. Key. Spec(key. Bytes, “Hmac. SHA 1”) ; Mac m = Mac. get. Instance(“Hmac. SHA 1”) ; m. init(key) ; m. update(input. Data) ; byte[ ] mac = m. do. Final( ) ; 20
Hash Functions l Converts a string of data of any size into a fixed-length hash l One-way funtion l Chances of any two strings of data hashing to the same value very, very small 21
Hash Algorithms n MD 5와 SHA의 비교 MD 5 SHA 다이제스트 길이 128 bits 160 bits 처리의 기본 단위 512 bits 단계 수 64(16번의 4라운드) 80 최대 메시지 크기 ∞ 2 64 bits 기약 논리 함수 4 3 덧셈 상수 64 4 22
Signatures (1/6) n 정의 l l n 서명할 사람의 private key를 가지고 암호한 message digest Authentication, Integrity 보장 Java Security API l n java. security. Signature 연산 l Generating a Signature l Verifying a Signature 23
Signatures (2/6) n Generating a Signature 1. Signature 객체 생성 public static Signature get. Instance(String algorithm) throws No. Such. Algorithm. Exception public static Signature get. Instance(String algorithm, String provider) throws No. Such. Algorithm. Exception, No. Such. Provider. Exception 2. Signature 객체 초기화 public final void init. Sign(Private. Key private. Key) throws Invalid. Key. Exception 3. Signature 객체에 message의 데이타 추가 public final void update(byte input) throws Signature. Exception public final void update(byte[] input, int offset, int len) throws Signature. Exception 4. Signature 계산 public final byte[] sign() throws Signature. Exception 24
Signatures (3/6) n Verifying a Signature 1. Signature 객체 생성 2. Signature 객체 초기화 public final void init. Verify(Public. Key public. Key) throws Invalid. Key. Exception 3. Signature 객체에 message의 데이타 추가 4. Signature 검증 public final boolean verify(byte[] signature) throws Signature. Exception n Signature에 명세된 알고리즘 파라메타를 초기화 l public final void set. Parameter(Algorithm. Parameter. Spec params) throws Invalid. Algorithm. Parameter. Exception 25
Signatures (4/6) n Hancock l Signature 생성 및 검증하는 프로그램 l 명령 라인 java Hancock -s|-v keystorepass alias messagefile signaturefile -s : 서명, -v : 검증, keystore : keystore 파일, storepass : keystore에 접근하기 위한 비밀번호 alias : key를 검색하기 위한 별명, messagefile : 데이타 저장 파일 signaturefile : 서명한 signature 저장 화일 l 하나의 key pair 필요 u keytool 사용 (5장) u keystore 클래스 사용 (5장) 26
// Hancock 프로그램 // import java. io. * ; import java. security. * ; public class Hancock { public static void main ( String[ ] args) throws Exception { if (args. length != 6) { System. out. println ( “Usage : Hancock -s|-v keystorepass alias messagefile signaturefile” ) ; return ; } String String options = args[0] ; keystorefile = args[1] ; storepass = args[2] ; alias = args[3] ; messagefile = args[4] ; signaturefile = args[5] ; Signature signature = Signature. get. Instance(“DSA” ) ; Key. Store keystore = Key. Store. get. Instance( ) ; keystore. load(new File. Input. Stream(keystroefile), storepass) ; 27
If (options. index. Of(“s”) != -1) signature. init. Sign(keystore. get. Private. Key(alias, storepass) ) ; else signature. init. Verify(keystore. get. Certificate(alias). get. Public. Key( ) ) ; File. Input. Stream in = new File. Input. Stream(messagefile) ; byte[ ] buffer = new byte[8192] ; int length ; while (( length = in. read(buffer)) != -1 ) signature. update(buffer, 0, length) ; in. close ( ) ; if (options. index. Of(“s”) != -1) { File. Output. Stream out = new File. Output. Stream(signaturefile) ; byte[ ] raw = signature. sign( ) out. write(raw) ; out. close ( ) ; } else { File. Input. Stream sig. In = new File. Input. Stream(signaturef ile) ; byte[ ] raw = new byte[sig. In. available( ) ] ; sig. In. read(raw) ; sig. In. close( ) ; if ( signature. verify(raw) ) System. out. println(“The signature is good. ”) ; else System. out. println(“The signature is bad. ” ) ; } } } 28
Signatures (5/6) n Login, Again l 클라이언트 u Private key를 가지고 Signature 생성 및 전송 u 명령 라인 java Strong. Client localhost c: windows. keystore buendia Jonathan l 서버 u Public key를 가지고 Signature를 검증 u 명령 라인 java Strong. Server c: windows. keystore buendia 29
// 클라이언트 프로그램 // import Protection ; public class Strong. Client { public void send. Authentication(String user, Private. Key key, Output. Stream out. Stream) throws IOException, No. Such. Algorithm. Exception, Invalid. Key. Exception, Signature. Exception { Data. Output. Stream out = new Data. Output. Stream(out. Stream) ; long t = (new Date( ) ). get. Time( ) ; double q = Math. random( ) ; Signature s = Signature. get. Instance(“DSA”) ; s. init. Sign(key) ; s. update(Protection. make. Bytes(t, q) ) ; byte[ ] signature = s. sign( ) ; out. write. UTF(user) ; out. write. Long(t ) ; out. write. Double(q) ; out. write. Int(signature. length) ; out. write(signature) ; out. flush( ) ; } 30
public static void main(String[ ] args) throws Exception { if (args. length != 5 ) { System. out. println ( “Usage : Strong. Client host keystorepass alias keypass”) ; return ; } String host = args[0] ; String keystorefile = args[1] ; String storepass = args[2] ; String alias = args[3] ; String keypass = args[4] ; int port = 7999 ; Socket s = new Socket(host, port) ; Strong. Client client = new Strong. Client( ) ; keystore. load(new File. Input. Stream(keystorefile), storepass) ; Private. Key key = keystore. get. Private. Key(alias, keypass) ; client. send. Authentication(alias, key, s. get. Output. Stream( ) ) ; s. close ( ) ; } } 31
// 서버 프로그램 // import Protection ; public class Strong. Server { protected Key. Store m. Key. Store ; public Strong. Server(Key. Store keystore) {m. Key. Store = keystore ; } public boolean authenticate(Input. Stream in. Stream) throws IOException, No. Such. Algorithm. Exception, Invalid. Key. Exception, Signature. Exception { Data. Input. Stream in = new Data. Input. Stream(in. Stream) ; String user = in. read. UTF( ) ; long t = in. read. Long( ) ; double q = in. read. Double( ) ; int length = in. read. Int( ) ; byte[ ] signature = new byte[length] ; in. read. Fully(signature) ; Signature s = Signature. get. Instacne(“DSA”) ; s. init. Verify(m. Key. Store. get. Certificate(user). get. Public. Key( )) ; s. update(Protection. make. Bytes(t, q ) ) ; return s. verify(signature) ; } 32
public static void main(String[ ] args) throws Exception { if (args. length != 2) { System. out. println(“Usage : Strong. Server keystorepass” ) ; return ; } String keystorefile = args[0] ; String storepass = args[1] ; int port = 7999 ; Server. Socket s = new Server. Socket(port) ; Socket client = s. accept( ) ; Key. Store keystore = Key. Store. get. Instance( ) ; Strong. Server server = new Strong. Server(keystore) ; if (server. authenticate(client. get. Input. Stream ( ) ) ) System. out. println(“Client logged in. ” ) ; else System. out. println(“Client failed to log in. ”) ; s. close( ) ; } } 33
Signatures (6/6) n Signed. Object l JDK 1. 2 u java. security. Signed. Object u Serializable 객체와 매칭하는 signature를 포함 l 생성 u public Signed. Object(Serializable object, Private. Key signing. Key, Signature signing. Engine) throws IOException, Signature. Exception l 검증 u public final boolean verify(Public. Key verification. Key, Signature verification. Engine) throws Invalid. Key. Exception, Signature. Exception l 검색 u public Object get. Object() throws IOException, Class. Not. Found. Exception 34
Certificates (1/9) n 정의 l n 한 사람이 서명한 문장으로 다른 사람의 public key를 가지고 있음 사례 l 정부가 발생한 허가증 u 운전 면허증 u 주민등록증 n Certificate Authority (CA) l Certificate를 발생한 기관 및 사람 35
Certificates (2/9) n Certificate의 내용 l subject 정보 l subject의 public key l issuer 정보 l issuer의 signature 36
Certificates (3/9) n JDK 1. 1 l l n Certificate 지원이 미흡했음 java. security. Certificate interface 소개 JDK 1. 2 l java. security. cert. Certificate abstract class 소개 u public abstract Public. Key get. Public. Key() u public abstract byte[] get. Encoded() throws Certificate. Encoding. Exception l X. 509 v 3 Certificates를 사용할 수 있음 l Certificate Revocation Lists(CRLs) 37
Certificates (4/9) n Generating a Certificate l X 509 Certificate 클래스 u get. Instance() 함수를 사용하여 X. 509 certificate를 로드 함 l n JDK 1. 1, JDK 1. 2 혼동 주의 Verifying a Certificate l public abstract void verify(Public. Key key) throws Certificate. Exception, No. Such. Algorithm. Exception, Invalid. Key. Exception, No. Such. Provider. Exception, Signature. Exception l public abstract void verify(Public. Key key, String sig. Provider) throws Certificate. Exception, No. Such. Algorithm. Exception, Invalid. Key. Exception, No. Such. Provider. Exception, Signature. Exception 38
Certificates (5/9) n X. 509 l International Telecommunications Union(ITU)에서 발표 l java. security. cert. X 509 Certificate 클래스 l 화일로부터 X. 509 certificate 로드 u public static final X 509 Certificate get. Instance(Input. Stream in. Stream) throws Certificate. Exception u public static final X 509 Certificate get. Instance(byte[] cert. Data) throws Certificate. Exception u java. security properties file에 다음 라인이 default로 설정 4 cert. provider. x 509=sun. security. X 509 Cert. Impl 4 DER-encoded certificate로부터 X 509 Cert. Impl 생성 (DER; Distinguished Encoding Rules) 39
Certificates (6/9) l X. 509 Certificate 내용 40
Certificates (7/9) n Spill l RFC 1421 certificate representation u base 64로 변환된 DER representation u header/footer line으로 구분 l 수행 작업 1. header/footer를 제거 => body 부부만 바이트 배열로 변환 (oreilly. jonathan. util. Base 64 클래스 사용, 부록 B) 2. X 509 Certificate를 생성하기 위해 변환한 바이트 배열을 사용 (certificate에 대한 정보를 출력) 3. certificate fingerprints를 계산하여 출력 41
// Spill 프로그램 // import oreilly. jonathan. util. Base 64 ; public class Spill { public static void main(String[ ] args) throws Exception { if (args. length != 1) { System. out. println(“Usage : Spill file” ) ; return ; } Buffered. Reader in = new Buffered. Reader(new File. Reader(args[0] )) ; String begin = in. read. Line( ) ; if (begin. equals(“-----BEGIN CERTIFICATE-----”) == false) throws new IOException(“Couldn’t find certificate beginning”) ; String base 64 = new String( ) ; boolean trucking = true ; while (trucking) { String line = in. read. Line ( ) ; if (line. starts. With(“-----”) ) trucking = false ; else base 64 += line ; } in. close ( ) ; byte[ ] certificate. Data = Base 64. decode(base 64) ; 42
X 509 Certificate c = X 509 Certificate. get. Instance(certificate. Data) ; System. out. println(“Subject: “ + c. get. Subject. DN( ). get. Name( ) ) ; System. out. println(“Issuer : “ + c. get. Issuer. DN( ). get. Name( ) ) ; System. out. println(“Serial number: “ + c. get. Serial. Number( ). to. String(16) ); System. out. println(“Valid from “ + c. get. Not. Before( ) + “ to ” + c. get. Not. After( ) ) ; System. out. println(“Fingerprints: ” ) ; do. Fingerprint(certificate. Data, “MD 5” ) ; do. Fingerprint(certificate. Data, “SHA” ) ; } protected static void do. Fingerprint(byte[ ] certificate. Bytes, String algorithm) throws Exception { System. out. print(“ ” + algorithm + “ : ”) ; Message. Digest md = Message. Digest. get. Instance(algorithm) ; md. update(certificate. Bytes) ; byte[ ] digest = md. digest( ) ; for (int i = 0; i < digest. length; i++) { if ( i != 0 ) System. out. print(“ : ”) ; int b = digest[i] & 0 xff ; String hex = Integer. to. Hex. String(b) ; if (hex. length( ) == 1) System. out. print( “ 0”) ; System. out. print(hex) ; } System. out. println( ) ; } } 43
// Spill 실행 결과 // C: java Spill ca 1. x 509 Subject: T=“+42 38 7747 361”, OID. 1. 2. 840. 113549. 1=dostalek@pvt. net, CN=Libor Dostalek, OU=VCU, O=“PVT, a. s. ”, L=Ceske Budejovice, S=2, C=CZ Issuer : OID. 1. 2. 840. 113549. 1=ca-oper@p 70 x 03. brn. pvt. cz, CN=CA-PVT 1, O=PVT a. s. , C=CZ Serial number: 2 d Valid from Mon Aug 04 01: 04: 56 EDT 1997 to Tue Feb 03 00: 04: 56 EST 1998 Fingerprints: MD 5: d 9: 6 f: 56: 3 e: e 0: ec: 35: 70: 94: bb: df: 05: 75: d 6: 32: 0 e SHA: db: be: df: e 5: ff: ec: f 9: 53: 98: dc: 88: dd: 6 b: ba: cf: 2 e: 2 a: 68: 0 c: 44 C: keytool -printcert -file ca 1. x 509 Owner: T=“+42 38 7747 361”, OID. 1. 2. 840. 113549. 1=dostalek@pvt. net, CN=Libor Dostalek, OU=VCU, O=“PVT, a. s. ”, L=Ceske Budejovice, S=2, C=CZ Issuer : OID. 1. 2. 840. 113549. 1=ca-oper@p 70 x 03. brn. pvt. cz, CN=CA-PVT 1, O=PVT a. s. , C=CZ Serial number: 2 d Valid from: Mon Aug 04 01: 04: 56 EDT 1997 to Tue Feb 03 00: 04: 56 EST 1998 Fingerprints: MD 5: d 9: 6 f: 56: 3 e: e 0: ec: 35: 70: 94: bb: df: 05: 75: d 6: 32: 0 e SHA: db: be: df: e 5: ff: ec: f 9: 53: 98: dc: 88: dd: 6 b: ba: cf: 2 e: 2 a: 68: 0 c: 44 44
Certificates (8/9) n Certificate Revocation Lists (CRL) l 더 이상 효력이 없는 certificate 리스트 l CRL을 발행하는 방법의 표준이 없음 l JDK 1. 2. u X. 509 표준의 CRL을 사용 u java. security. cert. X 509 CRL 클래스 사용 u java. security. cert. Revoked. Certificate 클래스 사용 45
Certificates (9/9) l java. security. cert. X 509 CRL u 생성 4 public static final X 509 CRL get. Instance(Input. Stream in. Stream) throws CRLException, X 509 Extension. Exception 4 public static final X 509 CRL get. Instance(byte[] crl. Data) throws CRLException, X 509 Extension. Exception u X 509 Certificate 클래스와 유사 u certificate의 무효화 여부 확인 4 public abstract boolean is. Revoked(Big. Integer serial. Number) l java. security. cert. Revoked. Certificate u public abstract Revoked. Certificate get. Revoked. Certificate(Big. Integer serial. Number) throws CRLException u public abstract Set get. Revoked. Certificate() 46
cbed7b9ddac5f28840372b86759bf576.ppt