2011년 6월 13일 월요일

자바을 이용한 암호학(자바보안 개정판:인증) - 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];
}
}
}

이중 암호화 패스워드 로그인
메시지 축약을 사용하여 패스워드 정보를 보호하는 강력한 방법으로 이중 암호화 기법이 있는데, 이의 구성은 “암호화 패스워드 로그인”에 추가적으로 타임스템프와 난수를 포함한다. 번째 축약에서 처음 축약메시지와 타임스템프, 난수를 이용하여 축약한다.

댓글 없음:

댓글 쓰기

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...