결과 화면

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