우리가 시스템에서 관리하는 많은 데이터에서 중요한 데이터는 많이 있습니다. 그중 기본이 되는 가장 중요한 데이터는 패스워드가 되겠죠? 우리가 만드는 사이트가 이익을 창출하기 위한 목적을 갖고 있다면 데이터가 유출되지 않도록 많은 신경을 써야 할 것이고 특히 이 패스워드를 암호화하는 작업은 반드시 해야 하는 작업이 되어야 할 것입니다.

 

통신 내용이 공격되는 것을 막기 위해 알아볼 수 없는 문자열로 만드는 것을 암호화라 합니다. 암호화된 데이터를 암호화 이전으로 되돌리는 것을 복호화라 합니다.

암호화한 것을 복호화할 수 없도록 단방향으로 암호화를 적용해야 합니다.

암호화된 고객들의 데이터는 시스템 내부에서 어떤 권한을 갖고 있다고 하더라도 접근할 수 없도록 설계되어야 합니다.

또한 공격자가 예측하여 작업을 진행할 수 없도록 salt처리를 해야 합니다. salt란 그냥 중복되지 않는 특정 문자열을 의미하며 암호화하는 작업에 추가하여 동일한 암호가 있다고 하더라도 동일한 문자열이 되지 않도록 처리하는 것을 의미합니다.

 

이외에도 암호화 작업에 알아야할 중요한 것들은 많이 있겠죠? 

DBMS에서도 암호화를 지원하고 있지만 암호화 작업은 소프트웨어에서 즉, 스프링에서 적용하는 것이 맞습니다. DBMS에서 암호화를 하여 운영하고 있는 상황에서 DBMS를 완전히 변경하거나 일부를 다른 DBMS로 변경한다면 암호화된 데이터는 어떤 데이터인지 알 수가 없기 때문에 곤란한 상황에 부딪치게 됩니다. DBMS마다 지원하는 암호화 방식이 다를 수 있기 때문입니다.

위에서 우리는 복호화 할 수 없는 암호화 알고리즘을 써서 암호화해야 한다고 했습니다. 복호화를 할 수 없다는 것은 한 번 암호화되면 다시 변환할 수 없다는 것이고 그럼 패스워드를 잃어버린 경우에 찾을 방법이 없다는 것입니다. 그러나 사용해 보신 경험이 있는 사이트를 생각해보세요. 요즘은 비밀번호를 잊어버렸을 때 비밀번호를 찾기 위해 아이디, 생년월일, 보물 1호, 이메일 등등을 입력해도 내가 잊어버린 비밀번호를 직접 알려주는 것이 아니라 대부분 임시 비밀번호를 문자나 메일로 전송한 후 사용자가 직접 변경할 수 있도록 하고 있습니다.

 

스프링 시큐리티에서는 어떻게 하고 있을까요? 여러가지 방법을 지원하고 있지만 역시 우리는 가장 간단한 것부터 살펴보도록 하겠습니다.

앞 강좌에서 UserDetailsService를 커스트마이징 하는 방법에 대해서 살펴보았습니다. 우리가 커스트마이징한 UserDetailsService클래스 내부에서 db에서 조회한 사용자의 정보를 리턴하면 포함된 암호화된 패스워드와 사용자가 입력한 패스워드를 다시 암호화하여 비교하는 방식으로 패스워드 인증을 진행하도록 하겠습니다.

 

암호화를 진행하기 위해 우리는 spring security내부에서 제공하는 API를 써야 합니다. spring security가 버전업 되면서 정책이 조금씩 바뀌고 최신 버전을 사용하기 위해서는 조금 다른 방법을 이용해서 작업해야 하지만 일단 기본부터 그리고 쉬운 거부터 살펴보도록 하겠습니다.

 

spring security에서 지원하는 암호화 알고리즘은 여러 가지가 있지만 sha256방식을 이용해 보도록 하겠습니다. 

spring security에서(우리가 사용하는 버전에서 나중에 버전이 바뀌는 경우 다른 API를 사용해야 할 수도 있습니다.)  지원하는 API 중 sha256을 지원하는 클래스는 ShaPasswordEncoder입니다.

 

ShaPasswordEncoder의 API 중 기본 메소드로 암호화하고 암호화된 문자열과 일반 문자열을 비교하는 반드시 알아야 하는 메서드는 encodePassword(...)와 isPasswordValid(....)입니다.

encodePassword(String rawPass, Object salt)
encodePassword는 지정한 문자열을 salt를 추가하여 암호화하고 암호화한 문자열을 리턴하는 메서드

rawPass : 암호화할 문자열
salt : salt로 추가할 값을 담고 있는 객체

 

 

isPasswordValid(String encPass, String rawPass, Object salt)
isPasswordVaild는 암호화된 문자열과 일반 문자열을 비교하여 같은지 다른지를 true/false로 리턴하는 메서드로 salt가 추가되어 암호화되어 있는 경우 salt를 추가하여 비교해야 합니다.

 

encPass : db에서 조회한 암호이며 암호화된 문자열

rawPass : 사용자가 입력한 암호 문자열

salt : salt를 추가하여 암호화한 경우 지정

 

우선 회원 가입할 때 입력한 패스워드를 암호화해야 하므로 가입 코드를 변경해야 합니다.

 

spring-security_ver5.xml

 

 

EmpServiceImpl

ShaPasswordEncoder를 autowired 하고 입력받은 패스워드를 암호화합니다. id를 salt로 추가합니다.

@Service
public class EmpServiceImpl implements EmpService {
	@Autowired
	EmpDAO dao;
	@Autowired
	FileUploadLogic upload;
	@Autowired
	private ShaPasswordEncoder passencoder;
	
	@Override
	public int insert(MemberDTO user,MultipartFile file,String realpath,String filename) {
		//사용자가 입력한 패스워드를 sha256알고리즘을 적용하여 암호화시킴
		String securitypass = 
				passencoder.encodePassword(user.getPass(), user.getId());
		System.out.println(securitypass);
		user.setPass(securitypass);//암호화된 패스워드를 다시 패스워드로 셋팅
		upload.upload(file, realpath, filename);
		return dao.insert(user);
	}

 

데이터를 입력하고 회원가입을 실행한 후 id와 pass만 조회해보겠습니다.

conn erp/erp
select id,pass from member

 

기존의 아이디와 패스워드는 암호화되지 않은 상태로 남고 새로 추가된 것만 암호화되어 insert 된 것을 알 수 있습니다.

 

 

+ Recent posts