쌍용 강북 교육센터 국비학원 Day 66일차
암호화 / 복호화
※ 관련용어 ※
암호 (Cryptography) : 해독 불가능한 형태로 변환하거나 또는 암호화된 메시지를 해독 가능한 형태로 변환하는 기술
평문 (Plain text) : 해독 가능한 형태의 메시지
암호문 (Ciphertext) : 해독 불가능한 형태의 메시지
암호화 (Encryption) : 평문을 암호문으로 변환하는 과정
복호화 (Decryption) : 암호문을 평문으로 변환하는 과정
대칭키 암호 (또는 비밀키 암호) : 암호화키와 복호화키가 같은 암호
비대칭키 암호 (또는 공개키 암호) : 암호화키와 복호화키가 다른 암호
단방향 (일방향) 암호화 알고리즘 (SHA-256 Secure Hash Algorithm)
단방향 암호화는 평문을 암호화했을때 다시 평문으로 되돌리는 것 (복호화)을 할 수 없는 암호문으로, 많이 사용하고 있는 알고리즘은 SHA-256 암호화이다. 이 알고리즘은 주로 사용자의 패스워드에 사용하는데, 패스워드의 경우 복호화해서 식별할 필요가 없기 때문이다.
1과 같은 단순한 값을 SHA-256으로 암호화했을 경우 항상 같은 값이 나오기 때문에 비밀번호 입력을 적당한 길이와 복잡성을 가지도록 유도하여 패스워드를 유추하는데 어렵도록 해야 한다. 해시 함수가 출력하는 압축된 문장을 다이제스트(Digest)라고 하는데, 다이제스트의 출력길이는 224, 256, 384, 512 bit 로 다양하다. 이때 256bit의 출력 길이를 갖는 것을 SHA-256 이라고 부른다.
암호화 SHA-256 알고리즘 클래스 생성
import java.security.MessageDigest;
public class Sha256 {
public static String encrypt(String plainText) {
try{
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(plainText.getBytes());
byte byteData[] = md.digest();
/*
1. SHA-256으로 해시
- MessageDigest객체 생성시 알고리즘을 "SHA-256"으로 해서 만든다.
해시된 데이터는 바이트 배열타입의 바이너리 데이터 (이진 데이터)이다.
*/
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
/*
해시된 데이터는 바이트 배열타입의 바이너리 데이터(이진 데이터)이므로
이것을 16진수 문자열(String)타입으로 변환해준다.
*/
StringBuffer hexString = new StringBuffer();
for (int i=0;i<byteData.length;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1){
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException();
}
}
}
양방향 암호화 알고리즘 (AES-256 Advanced Encryption Standard)
양방향 암호화 알고리즘은 평문에서 암호문으로, 암호문에서 평문으로 변환하는 암호화 및 복호화가 이루어지는 알고리즘 이다. 많이 사용하는 알고리즘은 AES-256 입니다. 주로 이름, 주소, 연락처 등 복호화 하는데 필요한 정보를 이 알고리즘을 이용해서 암호문으로 관리한다.
Java 를 이용한 구현
기본적으로 API가 제공되지만, AES-128 보다 한단계 더 높은 단계인 AES-256을 구현하기 위해서는 별도의 라이브러리 확장 파일이 필요하다.
- 오라클사 홈페이지의 JDK 다운로드 페이지에 가면 아래처럼 JCE 를 다운받는다.
- 자신의 JRE 버전에 맞는 해당 파일을 다운로드 받아서 압축을 푼 후 local_policy.jar 파일과 US_export_policy.jar 파일을 JDK설치경로\jre\lib\security 와 JRE설치경로\lib\security 에 local_policy.jar 파일과 US_export_policy.jar 두개 파일을 모두 붙여넣기를 하여 덮어쓴다. (Linux 계열에는 JDK설치경로에만 넣어주면 해결됨)
(JDK 설치 경로를 모르면 내컴퓨터 우클릭 > 속성 > 고급 시스템 설정 > 환경변수 > JAVA_HOME을 찾는다) - https://mvnrepository.com/artifact/commons-codec/commons-codec 에 가서 여러가지 버전이 있는데 1.15 에 들어가서 jar(345 KB)를 클릭하여 다운을 받는다.
- 다운받은 파일명은 commons-codec-1.15.jar 인데 이 파일을 C:\Program Files\Java\jdk1.8.0_333\jre\lib\ext 경로에 붙여둔다.
- 해당 프로젝트의 Build Path 에 가서 Libraies 탭에서 Add External JARs.. 를 클릭하여 commons-codec-1.15.jar 파일을 직접 올려둔다. or 다운받은 파일명 commons-codec-1.15.jar을 /MyMVC/src/main/webapp/WEB-INF/lib 에 넣어둔다.
- WAS(톰캣)을 재구동한다.
- JDK 버전별 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 다운로드 경로 -
jdk8 (Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8)
https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
jdk7 (Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7)
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
jdk6 (Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6)
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
암호화 SHA-256 알고리즘 클래스 생성
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
//양방향 암호화 알고리즘인 AES256 암호화를 지원하는 클래스
public class AES256 {
private String iv;
private Key keySpec;
16자리의 키값을 입력하여 객체를 생성한다.
@param key 암호화/복호화를 위한 키값
@throws UnsupportedEncodingException 키값의 길이가 16이하일 경우 발생
public AES256(String key) throws UnsupportedEncodingException {
this.iv = key.substring(0, 16);
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if(len > keyBytes.length){
len = keyBytes.length;
}
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
this.keySpec = keySpec;
}
/**
* AES256 으로 암호화 한다.
* @param str 암호화할 문자열
* @return
* @throws NoSuchAlgorithmException
* @throws GeneralSecurityException
* @throws UnsupportedEncodingException
*/
public String encrypt(String str) throws NoSuchAlgorithmException, GeneralSecurityException, UnsupportedEncodingException{
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv.getBytes()));
byte[] encrypted = c.doFinal(str.getBytes("UTF-8"));
String enStr = new String(Base64.encodeBase64(encrypted));
return enStr;
}
/**
* AES256으로 암호화된 txt 를 복호화한다.
* @param str 복호화할 문자열
* @return
* @throws NoSuchAlgorithmException
* @throws GeneralSecurityException
* @throws UnsupportedEncodingException
*/
public String decrypt(String str) throws NoSuchAlgorithmException, GeneralSecurityException, UnsupportedEncodingException {
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv.getBytes()));
byte[] byteStr = Base64.decodeBase64(str.getBytes());
return new String(c.doFinal(byteStr), "UTF-8");
}
}
※ 한국 인터넷 진흥원에서 제공하는 해시함수에 대한 소스코드 활용 파일
Ajax (Asynchronous JavaScript and XML)
Ajax 란 Client 와 Server 간에 XML 데이터를 JavaScript 를 사용하여 비동기 통신으로 주고 받는 기술이다.
'비동기 방식의 자바스크립트와 XML' 로 데이터를 주고받는 기술이다. 요즘에는 데이터 전송을 위한 데이터 포맷방법으로 XML 을 사용하기 보다는 JSON 을 더 많이 사용한다. (참고로 HTML은 데이터 표현을 위한 포맷방법이다) 또한 이는 자바스크립트의 라이브러리 중 하나이며, 브라우저가 가지고 있는 XMLHttpRequest 객체를 이용해서 전체 페이지를 새로 고치지 않고 페이지의 일부만을 로드하는 기법이다.
※ 비동기 방식이란
- 어떤 하나의 웹페이지에서 여러가지 서로 다른 다양한 일처리가 개별적으로 발생한다는 뜻으로서, 어떤 하나의 웹페이지에서 서버와 통신하는 그 일처리가 발생하는 동안 일처리가 마무리 되기전에 또 다른 작업을 할 수 있다는 의미이다.
- 웹페이지를 리로드하지 않고 데이터를 불러오므로 Ajax를 통해 서버에 요청을 하더라도, 멈춰있지 않고 해당 프로그램은 계속 구동할 수 있다.
- 이러한 방식은 시간도 빠르고, 화면을 리로드하는 경우 전체 리소스를 다 가져올 필요없이 일부 필요한 부분만 가져오기 때문에 장점이 있다.
Ajax를 사용하는 이유
- 단순하게 웹에서 무언가를 부르거나 데이터를 조회하고 싶은 경우, 페이지 전체를 새로고침하지 않기 위해 사용한다.
- 일반적으로 HTTP 프로토콜은 단방향 통신이다. 그렇기 때문에 클라이언트에서 요청을 보내고, 서버쪽에서 응답을 받으면 연결이 끊어진다. 그래서 화면의 내용을 갱신하기 위해서는 다시 요청을 보내고 응답을 받으며 페이지 전체를 갱신 해야한다. 다만, 이러한 방식은 엄청난 자원낭비와 시간낭비를 겪게 된다.
- Ajax는 Http 페이지 전체가 아닌 일부만 갱신가능하도록, XMLHttpRequest 객체를 통해서 서버에 요청한다. 이 경우에는 Json이나 XML형태로 필요한 데이터만 받아 갱신하기 때문에 그만큼의 자원과 시간을 절약할 수 있다.
Ajax의 장점
- 웹페이지의 속도 향상
- 서버의 처리가 완료 될때까지 기다리지 않고 처리가 가능하다.
- 서버에서 Data만 전송하면 되므로 전체적인 코드의 양이 줄일 수 있다.
- 기존 웹에서는 불가능했던 다양한 UI를 사용할 수 있다.
Ajax의 단점
- 히스토리 관리가 안된다.
- 페이지가 이동하지 않는 통신이므로 보안에 신경을 써야한다.
- 연속으로 데이터를 요청하면 서버 부하가 증가할 수 있다.
- XMLHttpRequest를 통해 통신을 하는 경우, 사용자에게 아무런 진행정보를 주지 않기 때문에 사용자가 알 수 없다.
- HTTP 클라이언트의 기능이 한정되어 있다.
- 지원하는 Charset이 한정적이다.
- Script로 작성되므로 디버깅이 어렵다.
- Cross-Domain 문제가 발생한다. (다른 도메인과 통신이 불가능하다.)
※ dataType:"json"을 생략하면 파라미터에 json에 값이 "value" 인 String 타입의 결과물이 들어오게 된다.
※ dataType:"json"을 넣어주면 파라미터에 json에 값이 value 인 Object 타입의 결과물이 들어오게 된다.
-> XMLHttpRequest 객체에 관한 더 자세한 설명은 다음 포스팅에서 다루겠다.
ajax 에서의 form 태그의 모든 값들을 자동적으로 name값을 키값으로 만들어서 보내주는 serialize() 메소드
- ajax data의 보내줄 값들을 하나하나 선언할 수도 있지만 queryString을 이용하여 한번에 지정할 수 있다.
JSON (JavaScript Object Notation)
Ajax 를 사용한 웹어플리케이션 개발시 서버와 통신하며 데이터를 보내기도 하고 데이터를 받을때도 있다. 이때 데이터 전송을 위한 포맷방법은 특정 프로그래밍 언어에 국한되지 않고 독립적으로 사용되도록 만들어야 좋을 것이다. 이러한 포맷방법으로 XML 을 많이 사용하였다. 하지만 XML은 다소 복잡하고 어렵고 XML에 에러가 있으면 페이지 전체가 멈추게 되는 단점이 있다. 그래서 데이터 전송을 위한 포맷방법으로 XML 보다 좀 더 쉽게 나타내고 조작할 수 있도록 만든것이 JSON 이다.
- JSON 형태의 객체 생성은 JSONObject 클래스를 사용하여 객체를 만든다.
- JSONArray 는 JSONObject 형태의 객체들을 받아들이는 List 계열의 타입 이다.
JSON (자바스크립트 객체 표기법) 을 서버와 주고 받을 수 있는 데이터형은 숫자, 문자열, boolean, 배열, 객체이다. { 으로 시작하여 } 으로 끝나며 그 속에 데이터를 표기하는데 key : value 쌍으로 구성된다. key 는 문자열로 표현하므로 반드시 쌍따옴표를 해야하고, 값은 기본자료형이나 문자열, 배열, 객체가 되어진다. 순서는 의미가 없고 오로지 key : value 형태가 올바르게 매핑만 되어있으면 된다.
JSON 사용방법
자바, JSP, 서블릿, 스프링에서 JSON을 사용한 데이터 전송을 하려면 먼저 JSON 데이터 포맷을 위한 라이브러리가 존재해야 한다.
JSON 관련 라이브러리 다운 - https://mvnrepository.com
- 위의 JSON 관련 라이브러리를 다운 받는 URL주소에서 JSON을 검색을 한다.
- JSON.simple 또는 JSON In Java를 파일을 다운받는다. (두가지 모두 JSON 기능을 하지만 약소하게 기능이 다른부분이 있다. 필요한 부분을 참고해서 다운)
- 다운받은 .jar 파일을 /해당프로젝트 Contextpath/src/main/webapp/WEB-INF/lib/ 에 저장한다.
관련 출처 - https://azderica.github.io/00-javascript-ajax/
'Web > JSP' 카테고리의 다른 글
쌍용강북교육센터 국비 학원 Day 69일차 JSP (Modal 값 초기화, reload, 이메일 인증코드 구현) (0) | 2023.04.11 |
---|---|
쌍용강북교육센터 국비 학원 Day 67일차 JSP (session 세션) (0) | 2023.04.09 |
쌍용강북교육센터 국비 학원 Day 64일차 JSP (DBCP, Connection Pool) (0) | 2023.04.04 |
쌍용강북교육센터 국비 학원 Day 63일차 JSP (MVC 패턴) (0) | 2023.04.03 |
쌍용강북교육센터 국비 학원 Day 62일차 JSP 구현 (0) | 2023.03.31 |