프로필사진
spring security 사용하여 암호화하기

2021. 7. 9. 18:47🔴 Spring

300x250

<pom.xml>

<!--스프링시큐리티 web 라이브러리 -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>5.1.2.RELEASE</version>
		</dependency>
		<!--스프링시큐리티 core 라이브러리 -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-core</artifactId>
			<version>5.1.2.RELEASE</version>
		</dependency>
		<!--스프링시큐리티 config 라이브러리 -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>5.1.2.RELEASE</version>
		</dependency>

<servlet-context.xml>

<beans:bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

<SecurityController.java>

package com.bitcamp.mvc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SecurityController {
	
	@Autowired
	private BCryptPasswordEncoder encoder; // Bean으로 추가했음
	
	@ResponseBody
	@RequestMapping("/encodepassword")
	public String bcript() {
		
		String str = "password"; // -> DB에 있는 비밀번호
		
		String encodingStr = encoder.encode(str); // 암호화 처리되어있는 문자열 리턴 -> 로그인할 때 비밀번호
		boolean result = encoder.matches(str, encodingStr); // 비밀번호 비교
		
		return str + " : " + encodingStr + "<br>" + "str=encodingStr -->" + result;		
	}
}

결과창 :


단방향 알고리즘

<Sha256.java>

package com.bitcamp.mvc;

import java.security.MessageDigest;

public class Sha256 {
	public static String encrypt(String planText) {
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-256");
			md.update(planText.getBytes());
			byte byteData[] = md.digest();
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < byteData.length; i++) {
				sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
			}
			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();
		}
	}
}

<SecurityController.java>

@ResponseBody
	@RequestMapping("/encodepassword1")
	public String bcript1() {
		
		String str = "password";
		
		String encodingStr = Sha256.encrypt(str); // 암호화 처리
		String pw = "pass"; // 사용자가 새롭게 입력한 pw
		boolean result = encodingStr.equals(Sha256.encrypt(pw)); // 새롭게 받은 pw도 암호화 처리
		
		return str + " : " + encodingStr + "<br>"
				+ "encodingStr=pw -->"+result;		
	}

결과창:


양방향 알고리즘

JCE다운 → lib 추가

https://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

WEB-INF → lib폴더에 추가 (local_policy.jar & US_export_policy.jar)

  • buildpath에 webapplibaray추가해줘야함!!

org.apache.commons.codec → lib 추가

<pom.xml>

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.10</version>
		</dependency>

<AES256Util.java>

package com.bitcamp.mvc;

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;

public class AES256Util {
	private String iv;
	private Key keySpec;

	/**
	 * 16자리의 키값을 입력하여 객체를 생성한다.
	 * 
	 * @param key 암/복호화를 위한 키값
	 * @throws UnsupportedEncodingException 키값의 길이가 16이하일 경우 발생
	 */
	public AES256Util(String key) throws UnsupportedEncodingException {
		this.iv = key.substring(0, 16);
		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");
	}
}

→ bean으로 등록하기 <servlet-context.xml>

<beans:bean id="AES256Util" class="com.bitcamp.mvc.AES256Util">
		<beans:constructor-arg>
			<beans:value>1111111111111111</beans:value> <!-- 16자리로 제한 -->
		</beans:constructor-arg>
	</beans:bean>

<SecurityController.java>

@Autowired
	private AES256Util aesutil;

@ResponseBody
	@RequestMapping("/encodepassword2")
	public String bcript2() throws NoSuchAlgorithmException, UnsupportedEncodingException, GeneralSecurityException {
		
		String str = "password";
		
		String encodingStr = aesutil.encrypt(str); // 암호화
		String decodingStr = aesutil.decrypt(encodingStr); // 복호화
		
		return str + " : " + encodingStr + " : " + decodingStr;		
	}

결과창:

300x250