1.암호화 유틸 생성
import java.net.URLEncoder;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Base64;
/**
*
* @author ljo
*
*/
public class CryptoUtil {
private static final String KEY = ServiceUtil.getEnvironment().getProperty("SSO.CONFIG.KEY");
private static final String ALGORITHM = "DESede";
private static final String TRANSFORMATION = "DESede/ECB/PKCS5Padding";
public static String getDecodeString(String str) throws Exception{
byte[] key = (KEY).getBytes();
str = new String(Base64.decodeBase64(str));
byte[] str4 = ees3DecodeECB(key, Base64.decodeBase64(str));
return new String(str4, "UTF-8");
}
public static String getEncodeString(String str) throws Exception{
byte[] key = (KEY).getBytes();
byte[] data = str.getBytes("UTF-8");
byte[] str3 = des3EncodeECB(key, data);
return URLEncoder.encode(Base64.encodeBase64String(Base64.encodeBase64String(str3).getBytes()), "UTF-8");
}
/**
* ECB MODE decode
* @param key
* @param data
* @return
* @throws Exception
*/
public static byte[] des3EncodeECB(byte[] key, byte[] data)
throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(ALGORITHM);
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, deskey);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
/**
* ECB MODE decode
* @param key
* @param data
* @return
* @throws Exception
*/
public static byte[] ees3DecodeECB(byte[] key, byte[] data)
throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(ALGORITHM);
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, deskey);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
/**
* CBC MODE encode
* @param key
* @param keyiv
* @param data
* @return
* @throws Exception
*/
public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data)
throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(ALGORITHM);
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
/**
* CBC MODE decode
* @param key
* @param keyiv
* @param data
* @return
* @throws Exception
*/
public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(ALGORITHM);
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
}
2. 캡챠 오브젝트 생성
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class CaptchaObject {
private String imageString;
private String cryptoAnswer;
}
3. 캡챠 생성
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
import com.solution.framework.util.CryptoUtil;
import lombok.Cleanup;
/**
*
* @author ljo
*
*/
public class CaptchaComponent{
private static final Font font = new Font("Verdana", Font.ITALIC | Font.BOLD, 28);
/**
* 캡차 오브젝트 생성
* @return
* @throws Exception
*/
public static CaptchaObject generateCaptcha() throws Exception{
int width = 100;
int height = 50;
//체크 문자 랜덤 생성
Random rnd = new Random();
StringBuffer buf = new StringBuffer();
for(int i = 0 ; i < 4 ; i++){
if(rnd.nextBoolean()){
String tmp = Character.toString((char)((int)(rnd.nextInt(26))+97));
buf.append(tmp.toUpperCase());
}else{
buf.append((rnd.nextInt(10)));
}
}
String randomStr = buf.toString();
char[] strs = randomStr.toCharArray();
//버퍼이미지 생성
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//그래픽 생성
Graphics2D g = (Graphics2D) bi.getGraphics();
AlphaComposite ac3;
Color color;
int len = strs.length;
g.setColor(color(150, 250));
g.fillRect(0, 0, width, height);
for (int i = 0; i < 15; i++) {
color = color(150, 250);
g.setColor(color);
g.drawOval(num(width), num(height), 5 + num(10), 5 + num(10));
}
g.setFont(font);
int h = height - ((height - font.getSize()) >> 1), w = width / len, size = w - font.getSize() + 1;
for (int i = 0; i < len; i++) {
ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);
g.setComposite(ac3);
color = new Color(20 + num(110), 30 + num(110), 30 + num(110));
g.setColor(color);
g.drawString(strs[i] + "", (width - (len - i) * w) + size, h - 4);
}
@Cleanup
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "jpg", baos);
String data = DatatypeConverter.printBase64Binary(baos.toByteArray());
String imageString = "data:image/jpg;base64," + data;
return CaptchaObject.builder().imageString(imageString).cryptoAnswer(CryptoUtil.getEncodeString(randomStr)).build();
}
private static Color color(int fc, int bc) {
if (fc > 255){
fc = 255;
}
if (bc > 255){
bc = 255;
}
int r = fc + num(bc - fc);
int g = fc + num(bc - fc);
int b = fc + num(bc - fc);
return new Color(r, g, b);
}
private static int num(int num) {
return (new Random()).nextInt(num);
}
}
4. 사용
4-1 - 컨트롤러
@RequestMapping("/test")
public String test(ModelMap model) throws Exception{
CaptchaObject captchaObj = CaptchaComponent.generateCaptcha();
model.addAttribute("chptchaKey", captchaObj.getCryptoAnswer());
model.addAttribute("chptchaImgUrl", captchaObj.getImageString());
return "viewpage";
}
4-2 - html
히든 태그에 암호화된 chptchaKey ,
이미지 태그에는 base64로 인코딩된 이미지가 들어간다.
<input type="hidden" name="chptchaKey" id="chptchaKey" value="${chptchaKey}">
<img id="captchaimg" class="img-fluid" src="${chptchaImgUrl}" alt="스팸방지이미지" />
<input type="text" id="chptchaStr" class="form-control input_text w-100" name="chptchaStr" placeholder="스팸방지코드를 입력하세요."/>
5. 체크방법
chptchaKey를 디코딩 한 값과 chptchaStr 값을 비교
if(!StringUtils.equals(vo.getChptchaStr().toUpperCase(), CryptoUtil.getDecodeString(vo.getChptchaKey()))){
errors.reject("chptchaStr", "스팸방지 값이 일치하지 않습니다. 이미지 확인 후 다시 입력해주세요.");
}
'개발 > java&kotlin' 카테고리의 다른 글
spring cloud openfeign 사용하기 (0) | 2020.11.24 |
---|---|
Spring boot - logback 로그처리 (0) | 2020.03.27 |
WebBindingInitializer 활용 (0) | 2018.07.12 |
spring 크로스 도메인 처리 (0) | 2018.07.12 |
POI 엑셀 다운로드 (0) | 2018.07.11 |