-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #254 from Wingle-SMWU/fix/AES256Util-#251
[fix] AES256Util iv, key application.yml 값으로 변경 및 salt 추가
- Loading branch information
Showing
2 changed files
with
148 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 97 additions & 33 deletions
130
wingle/src/main/java/kr/co/wingle/common/util/AES256Util.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,128 @@ | ||
package kr.co.wingle.common.util; | ||
|
||
import java.io.UnsupportedEncodingException; | ||
import java.security.GeneralSecurityException; | ||
import java.security.Key; | ||
|
||
import javax.crypto.Cipher; | ||
import javax.crypto.SecretKey; | ||
import javax.crypto.SecretKeyFactory; | ||
import javax.crypto.spec.IvParameterSpec; | ||
import javax.crypto.spec.PBEKeySpec; | ||
import javax.crypto.spec.SecretKeySpec; | ||
|
||
import org.apache.commons.codec.DecoderException; | ||
import org.apache.commons.codec.binary.Base64; | ||
import org.apache.commons.codec.binary.Hex; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
import kr.co.wingle.common.constants.ErrorCode; | ||
import kr.co.wingle.common.exception.InternalServerErrorException; | ||
|
||
@Component | ||
public class AES256Util { | ||
//initial vector 설정 | ||
private static String iv = "0000000000000001"; | ||
private static Key keySpec; | ||
|
||
public AES256Util() throws UnsupportedEncodingException { | ||
iv = iv.substring(0, 16); | ||
byte[] keyBytes = new byte[16]; | ||
byte[] b = iv.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"); | ||
keySpec = _keySpec; | ||
|
||
private static String KEY; | ||
private static byte[] SALT; | ||
private static String IV; | ||
|
||
@Value("${aes256.key}") | ||
public void setKEY(String KEY) { | ||
AES256Util.KEY = KEY; | ||
} | ||
|
||
@Value("${aes256.salt}") | ||
public void setSALT(String SALT) throws DecoderException { | ||
AES256Util.SALT = Hex.decodeHex(SALT.toCharArray()); | ||
} | ||
|
||
@Value("${aes256.iv}") | ||
public void setIV(String IV) { | ||
AES256Util.IV = IV; | ||
} | ||
|
||
//암호화 | ||
public static String encrypt(String str) { | ||
try { | ||
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 new java.math.BigInteger(encrypted).toString(16); | ||
} catch (GeneralSecurityException | UnsupportedEncodingException e) { | ||
SecretKey key = generateKey(KEY); | ||
byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, IV, str.getBytes("UTF-8")); | ||
return encodeHex(encrypted); | ||
} catch (Exception e) { | ||
throw new InternalServerErrorException(ErrorCode.ENCRYPT_FAIL); | ||
} | ||
} | ||
|
||
public static String encrypt(String str, String salt) { | ||
try { | ||
SecretKey key = generateKey(KEY, salt); | ||
byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, IV, str.getBytes("UTF-8")); | ||
return encodeHex(encrypted); | ||
} catch (Exception e) { | ||
throw new InternalServerErrorException(ErrorCode.ENCRYPT_FAIL); | ||
} | ||
} | ||
|
||
//복호화 | ||
public static String decrypt(String str) { | ||
try { | ||
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); | ||
c.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv.getBytes())); | ||
// byte[] byteStr = Base64.decodeBase64(str.getBytes()); | ||
byte[] byteStr = new java.math.BigInteger(str, 16).toByteArray(); | ||
return new String(c.doFinal(byteStr), "UTF-8"); | ||
} catch (GeneralSecurityException | UnsupportedEncodingException e) { | ||
SecretKey key = generateKey(KEY); | ||
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, IV, decodeBase64(str)); | ||
return new String(decrypted, "UTF-8"); | ||
} catch (Exception e) { | ||
throw new InternalServerErrorException(ErrorCode.DECRYPT_FAIL); | ||
} | ||
} | ||
|
||
public static String decrypt(String str, String salt) { | ||
try { | ||
SecretKey key = generateKey(KEY, salt); | ||
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, IV, decodeBase64(str)); | ||
return new String(decrypted, "UTF-8"); | ||
} catch (Exception e) { | ||
throw new InternalServerErrorException(ErrorCode.DECRYPT_FAIL); | ||
} | ||
} | ||
|
||
public static Long userIdDecrypt(String userId) { | ||
return Long.parseLong(decrypt(userId)); | ||
} | ||
|
||
private static byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) throws Exception { | ||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | ||
cipher.init(encryptMode, key, new IvParameterSpec(decodeHex(iv))); | ||
return cipher.doFinal(bytes); | ||
} | ||
|
||
private static SecretKey generateKey(String passPhrase) throws Exception { | ||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); | ||
|
||
// generate key with salt | ||
PBEKeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), SALT, 3000, 256); | ||
SecretKey key = new SecretKeySpec(factory.generateSecret(keySpec).getEncoded(), "AES"); | ||
|
||
return key; | ||
} | ||
|
||
private static SecretKey generateKey(String passPhrase, String salt) throws Exception { | ||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); | ||
|
||
// generate custom salt | ||
PBEKeySpec saltSpec = new PBEKeySpec(salt.toCharArray(), SALT, 3000, 128); | ||
SecretKey saltKey = new SecretKeySpec(factory.generateSecret(saltSpec).getEncoded(), "AES"); | ||
|
||
// generate key with custom salt | ||
PBEKeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), saltKey.toString().getBytes(), 3000, 256); | ||
SecretKey key = new SecretKeySpec(factory.generateSecret(keySpec).getEncoded(), "AES"); | ||
|
||
return key; | ||
} | ||
|
||
private static String encodeHex(byte[] bytes) { | ||
return Hex.encodeHexString(bytes); | ||
} | ||
|
||
private static byte[] decodeHex(String str) throws Exception { | ||
return Hex.decodeHex(str.toCharArray()); | ||
} | ||
|
||
private static byte[] decodeBase64(String str) { | ||
byte[] decodeByte = Base64.decodeBase64(str); | ||
return Base64.decodeBase64(decodeByte); | ||
} | ||
|
||
} |