● 암호화 - bit 단위로 문자를 별도의 임의 값으로 변경을 하는 것을 말함
MD5(128bit) : 해시 암호화 코드(default/가장 많이 쓰는 형태) ex) 쇼핑몰
SHA-1(160bit) : MD5에서 보다 높은 bit를 활용하여 사용하는 방식 -내부시스템
SHA-2(128,224,256,384,512bit) : SHA-1에서 개발자가 직접 bit를 선정하도록 update -> AI 에 뚫림
SHA-3(256,384,512bit) : SHA2에서 특수문자 형태의 코드를 추가
RSA (2048bit) : 전자서명을 사용하는 형태로 암호화 (Linux에서 최초 개발) 금융관련 = md5 + RSA
● MD5
암호화 라이브러리 => try~catch 사용
① 받아온 데이터인 mpass 를 md5로 암호화 하기 위해 get.byte로 bit로 변환 후 md5형태로 암호화 함try { //암호화 라이브러리 MessageDigest md5 = MessageDigest.getInstance("MD5"); //암호화는 bit단위로 이루어지기 때문에 getBytes()로 변환 md5.update(mpass.getBytes()); byte[] m = md5.digest(); //System.out.println(m); StringBuilder sb = new StringBuilder(); for(byte w : m) { // % :문자 포맷 - %x(소문자+숫자) %X(대문자+숫자) : 16진수 형태의 구성 //문자 포맷(2진수) : %02x //문자 포맷(8진수) : %08x String word = String.format("%08x", w); sb.append(word); } System.out.println(sb); } catch (Exception e) { e.printStackTrace(); //무조건 string으로 받아야함 (int,long등으로 못받음) System.out.println("올바른 문자가 아니어서 암호화가 정상 작동되지 않습니다."); } } }
② 변환된 'm' 값을 string.format을 이용해 문자포맷
③ 진행 시 주르륵 나오므로 문자열로 받기 위해 StringBuilder 로 문자열로 변환
(2진수, 8진수 등으로도 변환 가능)
e1adc3949ba59abbe56e057f2f883e(16진수)
e10adc3949ba59abbe56e057f20f883e(2진수) 000000e10000000a000000dc0000003900000049000000ba00000059000000ab000000be00000056000000e000000057 000000f20000000f000000880000003e(8진수)
● SHA - 1, SHA - 2, SHA - 3
MD5형태에서 MessageDigest.getInstance("SHA1");부분만 수정해주면 됨
MessageDigest md5 = MessageDigest.getInstance("SHA-256"); : //SHA-2 쓰는 형태 MessageDigest md5 = MessageDigest.getInstance("SHA3-224"); //SHA-3
- 출력 결과 예시 ('123456'을 변환)
e1adc3949ba59abbe56e057f2f883e(16진수) -MD5 기본 7c4a8d9ca3762af61e59520943dc26494f8941b - SHA1 f8cdb04495ded47615258f9dc6a3f4707fd2405434fefc3cbf4ef4e6 - SHA2형태
8d969eef6ecad3c29a3a629280e686cfc3f5d5a86aff3ca122c923adc6c92 6be790258b73da944199c4cb6aeec1fc883152dd74e7581b70a648 -SHA3형태
● DB에 저장시킨 암호화된 값을 입력받은 값과 비교
● 로그인 시 db에 암호화 된 형태로 저장된 패스워드와 비교 (아래 코드에서는 DB에서 불러오지 않고 직접 입력함)
1.비교 시 자료형 맞춰줘야함
2.비교하는 코드 예시
protected void doPost(HttpServletRequest request, HttpServletResponse response) hrows ServletException, IOException { String mpass = request.getParameter("mpass"); //사용자가 입력한 값 String db = "e1adc3949ba59abbe56e057f2f883e"; //DB에 저장된 값 try { //암호화 라이브러리 MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(mpass.getBytes()); byte[] m = md5.digest(); StringBuilder sb = new StringBuilder(); for(byte w : m) { String word = String.format("%x", w); sb.append(word); } System.out.println(sb); //암호화로 생성된 객체 자료형은 stringbuild 이므로 //string으로 형 변환 후 비교해야 정상적으로 핸들링가능 //sb는 stringbuilder 이고 db 는 string이므로 자료형 맞춰야함 if(sb.toString().equals(db)) { System.out.println("로그인 하셨습니다."); }else { System.out.println("패스워드를 확인하세요"); } } catch (Exception e) { e.printStackTrace(); //무조건 string으로 받아야함 (int,long등으로 못받음) System.out.println("올바른 문자가 아니어서 암호화가 정상 작동되지 않습니다."); } } }
● 암호화된 password를 저장시키기 위한 DB table 설계
패스워드 컬럼 크기 설정
' md5 '
: 80~100(16진수) =>md5 (2진수,5진수) : 150~200
' sha '
: text 로 설정
설계 예시)
create table login(
midx int(8) not null auto_increment,
mid varchar(30) not null,
mpass varchar(80) not null,
primary key(midx),
unique key(mid)
);
● properties 활용
● properties 파일 생성
- properties 는 해당 로드값을 메모리에 저장시킨 후 프로세서가 종료되면 자동으로 소멸
=> closing할 필요가 없음
1. WEB-INF 에 classes 폴더생성 (외부로부터의 db접근을 제한하기 위함 : web_inf는 외부접근을 차단)
2. classes 폴더에 db.properties '파일'생성
① properties 를 직접 만들어 놓고 로드하기
② do에서 바로 생성
Properties pp = new Properties(); pp.put(앞단, 뒷단); pp.put(앞단, 뒷단); pp.put(앞단, 뒷단);
● properties 파일 활용해서 db 연결
1. java로 ' dbcon ' 이라는 class 생성 후 라이브러리로 classes에 있는 properties 파일을 사용
코드 예시) database 연결 + properties 활용
public class dbcon { //classes 에 있는 properties 파일을 사용하는 라이브러리 Properties pp = new Properties(); String resource = "db.properties"; //로드 할 properties 파일 명 public Connection db() throws Exception{ //classes 안에 있는 properties 를 로드하여 모든 문자 내용을 저장시킴 this.pp.load(this.getClass().getClassLoader().getResourceAsStream(resource)); Class.forName(this.pp.getProperty("driver")); Connection con = DriverManager.getConnection(this.pp.getProperty("url"),this.pp.getProperty("user"),this.pp.getProperty("password")); return con; } }
- properties 파일 안의 내용도 찍어볼 수 있음
System.out.println(this.pp.getProperty("user")); 이용
getProperty("properties파일 안의 내용")을 이용해서 다 로드 가능함
properties 파일에 sql(ddl) 구문 넣고 사용가능함 - ddl은 module 에 들어가야함 (controll에 넣으면 안됨)
코드) properties 파일의 user 값을 가져옴
public class dbcon { //classes 에 있는 properties 파일을 사용하는 라이브러리 Properties pp = new Properties(); String resource = "db.properties"; //로드 할 properties 파일 명 public Connection db() throws Exception{ //classes 안에 있는 properties 를 로드하여 모든 문자 내용을 저장시킴 this.pp.load(this.getClass().getClassLoader().getResourceAsStream(resource)); System.out.println(this.pp.getProperty("user")); Class.forName(null); Connection con = DriverManager.getConnection(null); return con; } }
하고 loginok2.do 생성 후 db connection 만 해주고 실행하면
@WebServlet("/loginok2.do") public class login extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { dbcon dc = new dbcon(); try { Connection con = dc.db(); } catch (Exception e) { System.out.println("DB 연결 실패!!"); } } }
● MVC형태로 문자를 md5 로 변환하는 Class 생성
사용자가 입력한 패스워드를 md5로 변환 후 return 하는 메소드를 생성
public class passwd_md { private StringBuilder repass = new StringBuilder(); private String ori_pass = null; private MessageDigest md5 = null; public passwd_md(String userpw) { //pw를 받아오는 파트 this.ori_pass = userpw; } //사용자가 입력한 패스워드를 md5로 변환 후 return 하는 메소드 public String md5_passwd() { try { this.md5= MessageDigest.getInstance("md5"); this.md5.update(this.ori_pass.getBytes()); byte[] md = md5.digest(); for(byte ck : md) { String m = String.format("%x", ck); this.repass.append(m); } } catch (Exception e) { System.out.println("앙호화 변환 오류"); } //리턴할 메소드 자료형이 string으로 toString을 이용함 return this.repass.toString(); } }
● properties 에 ddl 구문 넣고 사용시 주의
- properties 를 쓰면 preparedstatement만 사용가능함
다른건 사용하지 못함 (ddl구문안에 다른 변수 활용x)
driver = com.mysql.cj.jdbc.Driver url = jdbc:mysql://localhost:3306/cms user = hana password = hana1234 select_db = select * from login where mid=? order by midx desc
@WebServlet("/loginok2.do") public class login extends HttpServlet { private static final long serialVersionUID = 1L; Properties pp = new Properties(); String ddl = "db.properties"; //ddl 구문 작성한 장소 PreparedStatement ps = null; ResultSet rs = null; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String mid = request.getParameter("mid"); String mpass = request.getParameter("mpass"); dbcon dc = new dbcon(); try { Connection con = dc.db(); this.pp.load(this.getClass().getClassLoader().getResourceAsStream(ddl)); this.ps = con.prepareStatement(this.pp.getProperty("select_db")); this.ps.setString(1, mid); this.rs = this.ps.executeQuery(); this.rs.next(); String db_mid = this.rs.getString("mid"); String db_mpass = this.rs.getString("mpass"); String userpw = new passwd_md(mpass).md5_passwd(); if(userpw.equals(db_mpass)) { System.out.println("로그인 하셨습니다."); }else { System.out.println("올바른 패스워드가 아닙니다."); } this.rs.close(); this.ps.close(); con.close(); } catch (Exception e) { e.printStackTrace(); System.out.println("DB 연결 실패!!"); } } }
'Web' 카테고리의 다른 글
SMTP - IMAP/SMTP (메일서버)사용해서 메일 발송 (0) | 2024.07.05 |
---|---|
[jsp] jsp 에서 split 사용 (0) | 2024.07.05 |
로그인 / 로그아웃 (0) | 2024.07.03 |