일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 파이썬
- flet
- NIO
- 시스템
- Java
- jpa
- 유닉스
- 코틀린
- android
- write by chatGPT
- chatGPT's answer
- oracle
- 고전역학
- GPT-4's answer
- 리눅스
- python
- spring data jpa
- 웹 크롤링
- spring integration
- Database
- JVM
- 역학
- kotlin
- 데이터베이스
- write by GPT-4
- 자바암호
- 인프라
- 소프트웨어공학
- 자바
- 자바네트워크
- Today
- Total
기억을 지배하는 기록
자바을 이용한 암호학 - 8 본문
Chapter 4 Certification
인증에 유요한 세가지 암호화 개념
- 메시지 축약(message digest)은 대용량 데이터 집합을 나타내는 식별자를 생성한다.
- 전자 서명(digital signature)은 데이터의 무결성을 증명하는데 사용한다.
- 인증서(certificate)는 암호적으로 공개키의 안전한 컨테이너로 사용된다.
PLT 4.1 Message Digest
java.security.MessageDigest
인스턴스 생성은 getInstance() 메소드이며 알고리즘으로는 MD5, SHA-1이 주로 쓰인다.
주요 Method :
update() : 데이터를 해쉬한다. 알고리즘에 따라 다르지만 264 비트로 매우 큰 크기의 데이터를 해위할 수 있다.
digest() : 바이트 배열로 해쉬를 반환한다. 만약 모든 데이터를 메시지 다이제스트 객체에 넣었다면, digest() 메서드가 이것을 해쉬를 수행 할 것이다.
1장에서 작성한 샘플 MasherMain 프로그램을 다시 살펴보도록한다.
package com.crypto; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import sun.misc.BASE64Encoder; public class MasherMain { public MasherMain() { } private void exec(String targetFileName) { try { MessageDigest md = MessageDigest.getInstance("SHA-512"); FileInputStream fin = new FileInputStream(targetFileName); byte[] buffer = new byte[8192]; int length; while ( (length = fin.read(buffer)) != -1 ) { md.update(buffer,0,length); } byte[] raw = md.digest(); BASE64Encoder encoder = new BASE64Encoder(); String base64 = encoder.encode(raw); System.out.println(base64); } catch(NoSuchAlgorithmException nalgoe) { System.err.println(nalgoe); } catch(FileNotFoundException fnote) { System.err.println(fnote); } catch(IOException ioe) { System.err.println(ioe); } } public static void main(String[] args) { if(args.length < 1) { System.out.println("USE : java MasherMain [File Full Path]"); System.exit(0); } String targetFileName = args[0]; MasherMain masher = new MasherMain(); masher.exec(targetFileName); } } |
PLT 4.2 Password 인증
클라이언트에서 서버로 평문을 전송하는 것을 피하기 위해서, 클라이언트는 평문 대신에 패스워드 메시지를 축약하여 보내게 되며, 서버는 보유하고 있는 패스워드 사본의 메시지 축약을 비교하여 두 개의 메시지 축약 내용이 같을 경우에 클라이언트를 인증하게 된다.
com.crypto.MasherServer
package com.crypto; import java.io.DataInputStream; import java.net.ServerSocket; import java.net.Socket; import java.security.MessageDigest; public class MasherServer { public MasherServer() { } public void exec(int port) throws Exception { ServerSocket ss = new ServerSocket(port); System.out.println("요청을 기다리고 있습니다.... port : "+port); Socket s = ss.accept(); DataInputStream in = new DataInputStream(s.getInputStream()); // 클라이언트가 보낸 순서로받는다. String user = in.readUTF(); long time = in.readLong(); double randomQ = in.readDouble(); int leng = in.readInt(); byte[] masherBytesIn = new byte[leng]; in.readFully(masherBytesIn); byte[] masherBytesOut = userMasher.makeDigest( user, getPassword(), time, randomQ); if(isUser(masherBytesIn, masherBytesOut)) { System.out.println("Login"); } else { System.out.println("No password"); } in.close(); } private String getPassword() { return "rlarudwls"; } private boolean isUser(byte[] inBytes, byte[] outBytes){ return MessageDigest.isEqual(inBytes, outBytes); } public static void main(String[] args) throws Exception { if(args.length < 1) { System.out.print("포트를 입력하여 주십시요...."); System.exit(0); } MasherServer ms = new MasherServer(); ms.exec(Integer.parseInt(args[0])); } } |
com.crypto.MasherClient
package com.crypto; import java.io.DataOutputStream; import java.net.Socket; import java.util.Date; public class MasherClient { public MasherClient() { } public void exec( String user, String password, String host, int port) throws Exception { Date date = new Date(); long time = date.getTime(); double randomQ = Math.random(); byte[] masherBytes = userMasher.makeDigest(user, password, time, randomQ); Socket s = new Socket(host, port); DataOutputStream out = new DataOutputStream(s.getOutputStream()); out.writeUTF(user); out.writeLong(time); out.writeDouble(randomQ); out.writeInt(masherBytes.length); out.write(masherBytes); out.flush(); out.close(); } public static void main(String[] args) throws Exception { if(args.length < 2) { System.out.print("서버 주소와 포트를 입력하여 주십시요...."); System.exit(0); } String user = "inter999"; String password = "rlarudwls"; MasherClient mc = new MasherClient(); mc.exec(user, password, args[0], Integer.parseInt(args[1])); } } |
com.crypto.userMasher
package com.crypto; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class userMasher { public static byte[] makeDigest( String user, String password, long time, double randomQ) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(user.getBytes()); md.update(password.getBytes()); md.update(makeBytes(time, randomQ)); return md.digest(); } public static byte[] makeBytes( long time, double randomQ) { try { ByteArrayOutputStream byteout = new ByteArrayOutputStream(); DataOutputStream dataout = new DataOutputStream(byteout); dataout.writeLong(time); dataout.writeDouble(randomQ); return byteout.toByteArray(); } catch (IOException ioe) { return new byte[0]; } } } |
이중 암호화 패스워드 로그인
메시지 축약을 사용하여 패스워드 정보를 보호하는 강력한 방법으로 이중 암호화 기법이 있는데, 이의 구성은 “암호화 패스워드 로그인”에 추가적으로 타임스템프와 난수를 포함한다. 즉 두 번째 축약에서 처음 축약메시지와 타임스템프, 난수를 이용하여 축약한다.
'오래된글 > Java' 카테고리의 다른 글
자바을 이용한 암호학 - 10 (0) | 2018.04.07 |
---|---|
자바을 이용한 암호학 - 9 (0) | 2018.04.07 |
자바을 이용한 암호학 - 7 (0) | 2018.04.07 |
자바을 이용한 암호학 - 6 (0) | 2018.04.07 |
자바을 이용한 암호학 - 5 (0) | 2018.04.07 |