본문 바로가기

others

AES, SHA 암호화 1, JAVA

java 언어를 이용해서
블럭암호화는 AES 128/256으로,  해쉬함수는 SHA 256 알고리즘으로 암호화 진행해 보겠습니다.
SHA 128은 보안상 위험함으로 사용안하는것을 추천합니다.
java의 경우 AES 256 암호화를 하기 위해서는 주석에 나와 있는것처럼  http://www.oracle.com/technetwork/java/javase/downloads/index.html에서 파일을 다운받아 JCE관련 패치를 해야됩니다.
base64 인코딩을 위해 commons-codec 라이브러리 추가하였습니다. jdk에 포함되어 있는sun.misc.BASE64Encoder(), sun.misc.BASE64Decoder() 이 클래스들은 http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html를 보면 지원도 보장도 안한다고 나와 있습니다.

pom.xml

1
2
3
4
5
6
<dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.10</version>
</dependency>
 
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
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package com.tistory.aircook;
 
 
import java.security.MessageDigest;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
import org.apache.commons.codec.CharEncoding;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
 
public class Crypto {
 
        public static void main(String[] args) {
 
               String str1 = "암호화되지 않은 문자";
               System.out.println("plain : " + str1);
 
               String str2 = encryptAES128(str1);
               System.out.println("AES128 encrypted : " + str2);
 
               String str3 = decryptAES128(str2);
               System.out.println("AES128 decrypted : " + str3);
               
               String str4 = encryptAES256(str1);
               System.out.println("AES256 encrypted : " + str4);
               
               String str5 = decryptAES256(str4);
               System.out.println("AES256 decrypted : " + str5);
               
               String str6 = encryptSHA256(str1);
               System.out.println("SHA256 encrypted : " + str6);
 
        }
 
        // 키
        private final static String KEY = "01234567890123456789012345678901";
 
        // 128bit (16자리)
        private final static String KEY_128 = KEY.substring(0128 / 8);
        
        // 256bit (32자리)
        private final static String KEY_256 = KEY.substring(0256 / 8);
 
        // AES 128 암호화
        public static String encryptAES128(String string) {
 
               try {
                       byte[] keyData = KEY_128.getBytes(CharEncoding.UTF_8);
 
                       // 운용모드 CBC, 패딩은 PKCS5Padding
                       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 
                       // key 와 iv 같게..
                       // 블록 암호의 운용 모드(Block engine modes of operation)가 CBC/OFB/CFB를 사용할 경우에는
                       // Initialization Vector(IV), IvParameterSpec를 설정해줘야한다. 아니면 InvalidAlgorithmParameterException 발생
                       
                       cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyData, "AES"), new IvParameterSpec(keyData));
 
                       // AES 암호화
                       byte[] encrypted = cipher.doFinal(string.getBytes(CharEncoding.UTF_8));
 
                       // base64 인코딩
                       byte[] base64Encoded = Base64.encodeBase64(encrypted);
 
                       // 결과
                       String result = new String(base64Encoded, CharEncoding.UTF_8);
 
                       return result;
               }
               catch (Exception e) {
                       return null;
               }
        }
 
        // AES 128복호화
        public static String decryptAES128(String string) {
 
               try {
                       byte[] keyData = KEY_128.getBytes(CharEncoding.UTF_8);
 
                       // 운용모드 CBC, 패딩은 PKCS5Padding
                       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 
                       cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyData, "AES"), new IvParameterSpec(keyData));
 
                       // base64 디코딩
                       byte[] base64Decoded = Base64.decodeBase64(string.getBytes(CharEncoding.UTF_8));
 
                       // AES 복화화
                       byte[] decrypted = cipher.doFinal(base64Decoded);
 
                       // 결과
                       String result = new String(decrypted, CharEncoding.UTF_8);
 
                       return result;
               }
               catch (Exception e) {
                       return null;
               }
        }
        
        // AES 256 암호화
        public static String encryptAES256(String string) {
 
               try {
                       byte[] key256Data = KEY_256.getBytes(CharEncoding.UTF_8);
                       byte[] key128Data = KEY_128.getBytes(CharEncoding.UTF_8);
 
                       // 운용모드 CBC, 패딩은 PKCS5Padding
                       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 
                       // key 와 iv 같게..
                       // 블록 암호의 운용 모드(Block engine modes of operation)가 CBC/OFB/CFB를 사용할 경우에는
                       // Initialization Vector(IV), IvParameterSpec를 설정해줘야한다. 아니면 InvalidAlgorithmParameterException 발생
                       
                       // AES 256은 미국만 되는거라. JDK/JRE 패치를 해야된다.
                       // http://www.oracle.com/technetwork/java/javase/downloads/index.html 에서 
                       // Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8 이런 링크 찾아서 다운
                       // $JAVA_HOME\jre\lib\security 아래에 local_policy.jar, US_export_policy.jar 파일 overwrite!
                       
                       // iv값이 16자리가 아니면..
                       // java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long 발생
                       
                       cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key256Data, "AES"), new IvParameterSpec(key128Data));
 
                       // AES 암호화
                       byte[] encrypted = cipher.doFinal(string.getBytes(CharEncoding.UTF_8));
 
                       // base64 인코딩
                       byte[] base64Encoded = Base64.encodeBase64(encrypted);
 
                       // 결과
                       String result = new String(base64Encoded, CharEncoding.UTF_8);
 
                       return result;
               }
               catch (Exception e) {
                       return null;
               }
        }       
        
        // AES 256복호화
        public static String decryptAES256(String string) {
 
               try {
                       byte[] key256Data = KEY_256.getBytes(CharEncoding.UTF_8);
                       byte[] key128Data = KEY_128.getBytes(CharEncoding.UTF_8);
 
                       // 운용모드 CBC, 패딩은 PKCS5Padding
                       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 
                       cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key256Data, "AES"), new IvParameterSpec(key128Data));
 
                       // base64 디코딩
                       byte[] base64Decoded = Base64.decodeBase64(string.getBytes(CharEncoding.UTF_8));
 
                       // AES 복화화
                       byte[] decrypted = cipher.doFinal(base64Decoded);
 
                       // 결과
                       String result = new String(decrypted, CharEncoding.UTF_8);
 
                       return result;
               }
               catch (Exception e) {
                       return null;
               }
        }       
        
 
        public static String encryptSHA256(String string) {
               
               try {
                       MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
 
                       byte[] stringBytes = string.getBytes();
                       int stringBytesLength = stringBytes.length;
 
                       byte[] dataBytes = new byte[1024];
                       for (int i = 0; i < stringBytesLength; i++) {
                              dataBytes[i] = stringBytes[i];
                       }
 
                       messageDigest.update(dataBytes, 0, stringBytesLength);
 
                       byte[] encrypted = messageDigest.digest();
 
                       // hex, 16진수
                       // StringBuffer sb = new StringBuffer();
                       // for (int i = 0; i < encrypted.length; i++) {
                       //      sb.append(Integer.toString((encrypted[i] & 0xff) + 0x100, 16).substring(1));
                       // }
                       // 결과
                       // String result = sb.toString();
                       
                       // commons codec lib 사용하면 아래처럼 간단하게..
                       // String result = Hex.encodeHexString(encrypted);
                       
                       
                       // base64 인코딩
                       byte[] base64Encoded = Base64.encodeBase64(encrypted);
                       // 결과
                       String result = new String(base64Encoded, CharEncoding.UTF_8);
 
                       return result;
               }
               catch (Exception e) {
 
                       return null;
               }
        }
}
cs


결과


'others' 카테고리의 다른 글

AES, SHA 암호화 3, C#  (6) 2015.08.26
AES, SHA 암호화 2, PL/SQL  (0) 2015.08.26
facebook note에 있던 잡다한것들..  (0) 2013.06.03
JSON Object 정렬하기  (0) 2012.01.30
checkbyte jQuery plugin  (0) 2011.11.11