Notice
Recent Posts
Recent Comments
Link
«   2025/03   »
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 29
30 31
Archives
Today
Total
관리 메뉴

개발자

[jsp 8일차]암호화 본문

개발자/JSP

[jsp 8일차]암호화

GoGo개발 2022. 9. 10. 17:40
command.properties / Abstractcontrollor 있다

 

<command.properties>

# member Mapping Information

/member/memberRegister.up = member.controller.MemberRegister
/member/idDuplicateCheck.up=member.controller.IdDuplicateCheck

 

1.<MemebrRegister.java>

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package member.controller;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import common.controller.AbstractController;
import member.model.*;
 
 
public class MemberRegister extends AbstractController {
 
    @Override
    public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        
        String method = request.getMethod(); 
        
        if("GET".equalsIgnoreCase(method)) {
        // GET 방식이라면    
        //    super.setRedirect(false);
            super.setViewPage("/WEB-INF/member/memberRegister.jsp");
        }
        
        else {
         // POST 방식이라면(즉, 회원가입 버튼을 클릭한 경우) 
            String name = request.getParameter("name"); 
            String userid = request.getParameter("userid"); 
            String pwd = request.getParameter("pwd"); 
            String email = request.getParameter("email"); 
            String hp1 = request.getParameter("hp1"); 
            String hp2 = request.getParameter("hp2"); 
            String hp3 = request.getParameter("hp3"); 
            String postcode = request.getParameter("postcode");
            String address = request.getParameter("address"); 
            String detailAddress = request.getParameter("detailAddress"); 
            String extraAddress = request.getParameter("extraAddress"); 
            String gender = request.getParameter("gender"); 
            String birthyyyy = request.getParameter("birthyyyy"); 
            String birthmm = request.getParameter("birthmm"); 
            String birthdd = request.getParameter("birthdd");
            
            String mobile = hp1 + hp2 + hp3; // "01023456789"
            String birthday = birthyyyy+"-"+birthmm+"-"+birthdd;  // "1996-10-25"
            
            MemberVO member = new MemberVO(userid, pwd, name, email, mobile, postcode, address, detailAddress, extraAddress, gender, birthday); 
            
            InterMemberDAO mdao = new MemberDAO();
            
            try {
                int n = mdao.registerMember(member); //암호화
                
                if(n==1) {
                    String message = "회원가입 성공"
                    String loc=request.getContextPath()+"/index.up"// 시작페이지로 이동한다. 
                    
                    request.setAttribute("message", message);
                    request.setAttribute("loc", loc);
                    
                    //super.setRedirect(false);
                    super.setViewPage("/WEB-INF/msg.jsp");
                }
                    
            } catch (Exception e) {                
                e.printStackTrace();
                super.setRedirect(true);
                super.setViewPage(request.getContextPath()+"/error.up");
            }
            
        }
        
    }
 
}
 
cs

 

 

2.oracle 생성

 

 

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
29
30
31
32
33
34
35
--- *** 회원테이블 생성 *** ----
 
create table tbl_member
(userid             varchar2(40)   not null  -- 회원아이디
,pwd                varchar2(200)  not null  -- 비밀번호 (SHA-256 암호화 대상)
,name               varchar2(30)   not null  -- 회원명
,email              varchar2(200)  not null  -- 이메일 (AES-256 암호화/복호화 대상)
,mobile             varchar2(200)            -- 연락처 (AES-256 암호화/복호화 대상) 
,postcode           varchar2(5)              -- 우편번호
,address            varchar2(200)            -- 주소
,detailaddress      varchar2(200)            -- 상세주소
,extraaddress       varchar2(200)            -- 참고항목
,gender             varchar2(1)              -- 성별   남자:1  / 여자:2
,birthday           varchar2(10)             -- 생년월일   
,coin               number default 0         -- 코인액
,point              number default 0         -- 포인트 
,registerday        date default sysdate     -- 가입일자 
,lastpwdchangedate  date default sysdate     -- 마지막으로 암호를 변경한 날짜  
,status             number(1default 1 not null     -- 회원탈퇴유무   1: 사용가능(가입중) / 0:사용불능(탈퇴) 
,idle               number(1default 0 not null     -- 휴면유무      0 : 활동중  /  1 : 휴면중 
,constraint PK_tbl_member_userid primary key(userid)
,constraint UQ_tbl_member_email  unique(email)
,constraint CK_tbl_member_gender check( gender in('1','2') )
,constraint CK_tbl_member_status check( status in(0,1) )
,constraint CK_tbl_member_idle check( idle in(0,1) )
);
 
select *
from tbl_member
order by registerday desc;
 
 
 
 
 
cs

 

 

2.memverVO

 

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package member.model;
 
public class MemberVO {
 
    private String userid;             // 회원아이디
    private String pwd;                // 비밀번호 (SHA-256 암호화 대상)
    private String name;               // 회원명
    private String email;              // 이메일 (AES-256 암호화/복호화 대상)
    private String mobile;             // 연락처 (AES-256 암호화/복호화 대상) 
    private String postcode;           // 우편번호
    private String address;            // 주소
    private String detailaddress;      // 상세주소
    private String extraaddress;       // 참고항목
    private String gender;             // 성별   남자:1  / 여자:2
    private String birthday;           // 생년월일   
    private int coin;                  // 코인액
    private int point;                 // 포인트 
    private String registerday;        // 가입일자 
    private String lastpwdchangedate;  // 마지막으로 암호를 변경한 날짜  
    private int status;                // 회원탈퇴유무   1: 사용가능(가입중) / 0:사용불능(탈퇴) 
    private int idle;                  // 휴면유무         0: 활동중  /  1 : 휴면중 
                                       // 마지막으로 로그인 한 날짜시간이 현재시각으로 부터 1년이 지났으면 휴면으로 지정 
    
    /////////////////////////////////////////////////////////////////////////////
    
    public MemberVO() {}
    
    //Source > Generate constructor using fields
    public MemberVO(String userid, String pwd, String name, String email, String mobile, String postcode,
            String address, String detailaddress, String extraaddress, String gender, String birthday) { 
        this.userid = userid;
        this.pwd = pwd;
        this.name = name;
        this.email = email;
        this.mobile = mobile;
        this.postcode = postcode;
        this.address = address;
        this.detailaddress = detailaddress;
        this.extraaddress = extraaddress;
        this.gender = gender;
        this.birthday = birthday;
    }
 
    public String getUserid() {
        return userid;
    }
 
    public void setUserid(String userid) {
        this.userid = userid;
    }
 
    public String getPwd() {
        return pwd;
    }
 
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public String getMobile() {
        return mobile;
    }
 
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
 
    public String getPostcode() {
        return postcode;
    }
 
    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }
 
    public String getAddress() {
        return address;
    }
 
    public void setAddress(String address) {
        this.address = address;
    }
 
    public String getDetailaddress() {
        return detailaddress;
    }
 
    public void setDetailaddress(String detailaddress) {
        this.detailaddress = detailaddress;
    }
 
    public String getExtraaddress() {
        return extraaddress;
    }
 
    public void setExtraaddress(String extraaddress) {
        this.extraaddress = extraaddress;
    }
 
    public String getGender() {
        return gender;
    }
 
    public void setGender(String gender) {
        this.gender = gender;
    }
 
    public String getBirthday() {
        return birthday;
    }
 
    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }
 
    public int getCoin() {
        return coin;
    }
 
    public void setCoin(int coin) {
        this.coin = coin;
    }
 
    public int getPoint() {
        return point;
    }
 
    public void setPoint(int point) {
        this.point = point;
    }
 
    public String getRegisterday() {
        return registerday;
    }
 
    public void setRegisterday(String registerday) {
        this.registerday = registerday;
    }
 
    public String getLastpwdchangedate() {
        return lastpwdchangedate;
    }
 
    public void setLastpwdchangedate(String lastpwdchangedate) {
        this.lastpwdchangedate = lastpwdchangedate;
    }
 
    public int getStatus() {
        return status;
    }
 
    public void setStatus(int status) {
        this.status = status;
    }
 
    public int getIdle() {
        return idle;
    }
 
    public void setIdle(int idle) {
        this.idle = idle;
    }
    
    //////////////////////////////////////////////////////////////////
    
    
    
    
}
 
cs

 

 

3.DAO

 

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package member.model;
 
import java.io.UnsupportedEncodingException;
import java.rmi.UnexpectedException;
import java.security.GeneralSecurityException;
import java.sql.*;
 
import javax.naming.*;
import javax.sql.DataSource;
 
import util.security.AES256;
import util.security.SecretMyKey;
import util.security.Sha256;
 
public class MemberDAO implements InterMemberDAO {
    
    
    
    private DataSource ds; // DataSource ds 는 아파치톰캣이 제공하는 DBCP(DB Connection Pool) 이다.
    private Connection conn;
    private PreparedStatement pstmt;
    private ResultSet rs;
    
    private AES256 aes;
    
    // 생성자 - DB커넥션풀이란.txt 에서 9번 붙여넣은것
    public MemberDAO() {
        
        try {
            Context initContext = new InitialContext(); // javax.naming import
            Context envContext  = (Context)initContext.lookup("java:/comp/env");
            ds = (DataSource)envContext.lookup("jdbc/myoracle"); // "jdbc/myoracle" 은 web.xml 에서 지정해둔 이름, context.xml 을 참조하고 있음
            
            aes = new AES256(SecretMyKey.KEY);
        } catch(NamingException e) {
            e.printStackTrace();
        } catch(UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    
    // 사용한 자원을 반납하는 close() 메소드 생성하기
    private void close() {
        
        try {
            if( rs != null )    { rs.close();    rs=null; }
            if( pstmt != null ) { pstmt.close(); pstmt=null; }
            if( conn != null )  { conn.close();  conn=null; }
            
        } catch(SQLException e) {
            e.printStackTrace();
        }
    }
    
    
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////
 
    
    // 회원가입을 해주는 메소드(tbl_member 테이블에 insert) ----------------------------------------------------------
    @Override
    public int registerMember(MemberVO member) throws SQLException {
        
        int result = 0;
        
        try {
            conn = ds.getConnection();
            
            String sql = "insert into tbl_member(userid, pwd, name, email, mobile, postcode, address, detailaddress, extraaddress, gender, birthday)\n"+
                         "values(?,?,?,?,?,?,?,?,?,?,?)";
            
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, member.getUserid()); // member 안에 다 넣어놨음 MemberRegister.java 에서
            pstmt.setString(2, Sha256.encrypt(member.getPwd()) ); // 암호를 SHA256 알고리즘으로 단방향 암호화 시킨다.(복호화 불가)
            pstmt.setString(3, member.getName());
            pstmt.setString(4, aes.encrypt(member.getEmail()) ); // 암호를 AES256 알고리즘으로 양방향 암호화 시킨다.(복호화 가능)
            pstmt.setString(5, aes.encrypt(member.getMobile()) );
            pstmt.setString(6, member.getPostcode());
            pstmt.setString(7, member.getAddress());
            pstmt.setString(8, member.getDetailaddress());
            pstmt.setString(9, member.getExtraaddress());
            pstmt.setString(10, member.getGender());
            pstmt.setString(11, member.getBirthday());
            
            
            
            /*
                     양방향 암호화
                -----------------------------------------------------------
                  I am a boy   ==> plain text(평문)
                + 1              ==> secret key(암호화키)
                 ----------------------
                   J bn b cpz   ==> encrypted text(암호화된 문장)
                - 1                ==> secret key(암호화키)
                 ----------------------
                  I am a boy   ==> decrypted text(복호화된 문장)
                ------------------------------------------------------------
             */
            
            result = pstmt.executeUpdate();
            
            
        } catch(GeneralSecurityException | UnsupportedEncodingException e) {
            e.printStackTrace();
        } finally {
            close();
        }
        
        
        return result;
        
    } // end of public int registerMember(MemberVO member) throws SQLException {} -------------------------
    
    
    //ID 중복검사 (tbl_member 테이블에서 userid 가 존재하면 true를 리턴해주고, userid 가 존재하지 않으면 false를 리턴한다)
    @Override
    public boolean idDuplicateCheck(String userid) throws SQLException {
        
        boolean isExists = false;
        
        try {
            conn = ds.getConnection();
            
            String sql = " select userid "
                        + " from tbl_member "
                        +" where userid = ? ";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, userid);
            
            rs = pstmt.executeQuery();
            
            isExists = rs.next(); //행이 있으면(중복된 userid) true , 
                                  // 행s이 없으면 (사용가능한 userid) false
            
        }finally {
            close();
        }
        
        return isExists;
    }// end of public boolean idDuplicateCheck(String userid) throws SQLException-----------------------
 
}
 
cs

 

 

 

< pstmt.setString(2, Sha256.encrypt(member.getPwd()) ); // 암호를 SHA256 알고리즘으로 단방향 암호화 시킨다.(복호화 불가) >

 

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package util.security;
 
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+ 0x10016).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();
        }
    }
 
}
 
cs

 

<pstmt.setString(4, aes.encrypt(member.getEmail()) ); // 암호를 AES256 알고리즘으로 양방향 암호화 시킨다.(복호화 가능)>

 

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package util.security;
 
    
    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(016);
            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");
        }
 
    }// end of class AES256///////////////////////////////////////
 
 
 
cs

 

 

<양방향 알고리즘>

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
※ 관련용어 ※
 - 암호(Cryptography) : 해독 불가능한 형태로 변환하거나 또는 암호화된 메시지를 해독 가능한 형태로 변환하는 기술
 - 평문(Plaintext)    : 해독 가능한 형태의 메시지
 - 암호문(Ciphertext) : 해독 불가능한 형태의 메시지
 - 암호화(Encryption) : 평문을 암호문으로 변환하는 과정
 - 복호화(Decryption) : 암호문을 평문으로 변환하는 과정
 - 대칭키 암호(또는 비밀키 암호) : 암호화키와 복호화키가 같은 암호
 - 비대칭키 암호(또는 공개키 암호) : 암호화키와 복호화키가 다른 암호
 
 
※ 양방향 암호화 알고리즘(AES-256 Advanced Encryption Standard) ※
 
  양방향 암호화 알고리즘은 평문에서 암호문으로, 암호문에서 평문으로 변환하는 암호화 및 복호화가 이루어지는 알고리즘 이다. 
  많이 사용하는 알고리즘은 AES-256 입니다. 
  주로 이름, 주소, 연락처 등 복호화 하는데 필요한 정보를 이 알고리즘을 이용해서 암호문으로 관리한다.
 
 ※※※  Java 를 이용한 구현  ※※※
 == 개발전 준비단계 ==
  기본으로 제공하는 JDK를 설치하면 암호 알고리즘을 만들 수 있는 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을 찾는다)
  그런 다음에 WAS(톰캣)를 재구동한다. 
  
 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_112\jre\lib\ext 경로에 붙여둔다.
 해당 프로젝트의 Build Path 에 가서 Libraies 탭에서 Add External JARs.. 를 클릭하여 commons-codec-1.15.jar 파일을 직접 올려둔다.
 또는 다운받은 파일명 commons-codec-1.15.jar을 /MyMVC/src/main/WebContent/WEB-INF/lib 에 넣어둔다.
   
 
 >>> 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 
============================================================================================================
 
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(016);
        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");
    }
 
}// end of class AES256///////////////////////////////////////
 
 
 
cs

 

 

<단방향 알고리즘>

 

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
※ 관련용어 ※
 - 암호(Cryptography) : 해독 불가능한 형태로 변환하거나 또는 암호화된 메시지를 해독 가능한 형태로 변환하는 기술
 - 평문(Plaintext)    : 해독 가능한 형태의 메시지
 - 암호문(Ciphertext) : 해독 불가능한 형태의 메시지
 - 암호화(Encryption) : 평문을 암호문으로 변환하는 과정
 - 복호화(Decryption) : 암호문을 평문으로 변환하는 과정
 - 대칭키 암호(또는 비밀키 암호) : 암호화키와 복호화키가 같은 암호
 - 비대칭키 암호(또는 공개키 암호) : 암호화키와 복호화키가 다른 암호
 
 
※ 단방향(일방향) 암호화 알고리즘(SHA-256 Secure Hash Algorithm) ※
 
  단방향 암호화는 평문을 암호화했을때 다시 평문으로 되돌리는 것(복호화)을 할 수 없는 암호화 이다. 
  많이 사용하고 있는 알고리즘은 SHA-256 암호화이다. 
  이 알고리즘은 주로 사용자의 패스워드 에 사용하는데, 패스워드의 경우 복호화해서 식별할 필요가 없기 때문이다. 
 1과 같은 단순한 값을 SHA-256으로 암호화했을 경우 항상 같은 값이 나오기 때문에 
  비밀번호 입력을 적당한 길이와 복잡성을 가지도록 유도하여 패스워드를 유추하는데 어렵도록 해야 한다.
  해시 함수가 출력하는 압축된 문장을 다이제스트(Digest)라고 하는데, 다이제스트의 출력길이는
 224256384512 bit 로 다양하다. 이때 256bit의 출력 길이를 갖는 것을 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+ 0x10016).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();
        }
    }
}
 
cs