From 206f475b58cb14cabdbc6235612cceda5b353bbe Mon Sep 17 00:00:00 2001 From: KNKIM Date: Thu, 2 Sep 2021 18:33:21 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=ED=9C=B4=EB=A9=B4=EA=B3=84=EC=A2=8C?= =?UTF-8?q?=EC=B2=98=EB=A6=AC,=20=EC=8B=A0=EA=B7=9C=20=EB=AC=B8=ED=99=94?= =?UTF-8?q?=EC=9B=90=20=EA=B0=80=EC=9E=85=20=EB=8F=99=EC=9D=98=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nlib/user/service/LoginService.java | 3 + .../java/nlib/user/service/NlibLoginVO.java | 2 + .../java/nlib/user/service/impl/LoginDAO.java | 5 + .../user/service/impl/LoginServiceImpl.java | 18 +- .../java/nlib/user/web/LoginController.java | 170 ++++++++++++------ .../mapper/nlib/user/LoginDAO_SQL.xml | 19 ++ .../jsp/nlib/login/activateDormantAcc.jsp | 74 ++++++++ .../WEB-INF/jsp/nlib/login/agreeProvInfo.jsp | 77 ++++++++ .../jsp/nlib/login/agreeProvInfoForm.jsp | 32 ++-- 9 files changed, 326 insertions(+), 74 deletions(-) create mode 100644 src/main/webapp/WEB-INF/jsp/nlib/login/activateDormantAcc.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfo.jsp diff --git a/src/main/java/nlib/user/service/LoginService.java b/src/main/java/nlib/user/service/LoginService.java index 208669c9..825d1362 100644 --- a/src/main/java/nlib/user/service/LoginService.java +++ b/src/main/java/nlib/user/service/LoginService.java @@ -35,4 +35,7 @@ public interface LoginService public HashMap selectCouncilInfoByDnsHost(String councilDnsHost); public int activateDormantAcc(NlibLoginVO loginVO); + + public int agreeProvInfo(NlibLoginVO loginVO); + } \ No newline at end of file diff --git a/src/main/java/nlib/user/service/NlibLoginVO.java b/src/main/java/nlib/user/service/NlibLoginVO.java index dc566fbe..86e63a8c 100644 --- a/src/main/java/nlib/user/service/NlibLoginVO.java +++ b/src/main/java/nlib/user/service/NlibLoginVO.java @@ -77,6 +77,8 @@ public class NlibLoginVO implements Serializable { private String mobileVrfctNo = null; /* 본인확인 인증번호 */ private String mobileVrfctDd = null; /* 본인확인 인증번호 발송일자 */ + + /** * 로그인인증키값을 리턴한다. 만일 존재하지 않을 경우, userId를 기반으로 인증키를 생성하여 리턴한다. * 로그인되지 않은 자(userId값이 존재하지 않는경우)에 대해서는 null을 리턴한다. diff --git a/src/main/java/nlib/user/service/impl/LoginDAO.java b/src/main/java/nlib/user/service/impl/LoginDAO.java index 72167348..b504392a 100644 --- a/src/main/java/nlib/user/service/impl/LoginDAO.java +++ b/src/main/java/nlib/user/service/impl/LoginDAO.java @@ -36,4 +36,9 @@ public class LoginDAO extends EgovComAbstractDAO { public int activateDormantAcc(NlibLoginVO loginVO) { return update("LoginDAO.activateDormantAcc", loginVO); } + + public int agreeProvInfo(NlibLoginVO loginVO) { + return insert("LoginDAO.agreeProvInfo", loginVO); + } + } \ No newline at end of file diff --git a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java index 52230c3d..269dca02 100644 --- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java +++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java @@ -120,18 +120,20 @@ public class LoginServiceImpl implements LoginService if(nLoginVO == null) { return ERR_CODE_REQ_MEMBERSHIP; } - - // 해당 지방문화원에 미등록된 경우, 정보제공 동의로 이동 처리 필요 - if(StringUtil.isEmpty(nLoginVO.getJoinCouncilCd())) { - return ERR_CODE_REQ_AGREE; - } - + // 휴면계좌 확인 if("P".equals(nLoginVO.getStatus())) { oUser.setNlibVO(nLoginVO); return WRN_CODE_DORMANT; } + // 해당 지방문화원에 미등록된 경우, 정보제공 동의로 이동 처리 필요 + if(StringUtil.isEmpty(nLoginVO.getJoinCouncilCd())) { + oUser.setNlibVO(nLoginVO); + return ERR_CODE_REQ_AGREE; + } + + // Spring Security 로그인처리위한 token 생성하여 로그인 처리 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getUsername(), nLoginVO.getPassword()); NlibLoginVO nlibLoginedVO = loginProcSecurity(req, token); @@ -210,7 +212,9 @@ public class LoginServiceImpl implements LoginService return loginDAO.activateDormantAcc(loginVO); } - + public int agreeProvInfo(NlibLoginVO loginVO) { + return loginDAO.agreeProvInfo(loginVO); + } /* SNS 연동 SSO를 통한 로그인 처리한다. * diff --git a/src/main/java/nlib/user/web/LoginController.java b/src/main/java/nlib/user/web/LoginController.java index b96fe62f..6c9d4ddc 100644 --- a/src/main/java/nlib/user/web/LoginController.java +++ b/src/main/java/nlib/user/web/LoginController.java @@ -402,8 +402,6 @@ public class LoginController { HttpSession session, ModelMap model) throws Exception { - String redirectUrl = "/index.do"; - String jsessionId = session.getId(); String councilCd = (String)session.getAttribute("councilCd"); String councilReturnUrl = (String)session.getAttribute("councilReturnUrl"); @@ -414,27 +412,38 @@ public class LoginController { } //----------------------------------------------- - // 등록된 사용자 여부 확인 + // 로그인 처리 //----------------------------------------------- + String redirectUrl = loginProc(req, councilCd, oauthUser, councilReturnUrl, model); + + // 정상 SNS 연동 로그인 + if(StringUtil.isNotEmpty(redirectUrl)) { + return redirectUrl; + } + + return "redirect:" + councilReturnUrl; + } + + public String loginProc(HttpServletRequest req, String councilCd, OAuthUniversalUser oauthUser, String councilReturnUrl, ModelMap model) { + + String jsessionId = req.getSession().getId(); String loginResult = loginService.loginCouncilSSO(req, councilCd, oauthUser); // 정상 SNS 연동 로그인 if(loginResult == null) { SessionConfig.removeLoginInfo(jsessionId); // 세션에 설정된 redirect 주소 확인 - return "redirect:" + councilReturnUrl; + return null; } // 휴면계좌 if(StringUtil.equalsIgnoreCase(loginResult, loginService.WRN_CODE_DORMANT)) { - redirectUrl = NlibProperty.getString("login.dormant.url"); - return "redirect:" + redirectUrl; + return "redirect:" + NlibProperty.getString("login.dormant.url"); } // 신규 지방문화원 정보 제공 동의 필요 if(StringUtil.equalsIgnoreCase(loginResult, loginService.ERR_CODE_REQ_AGREE)) { - redirectUrl = NlibProperty.getString("login.newcouncil.url"); - return "redirect:" + redirectUrl; + return "redirect:" + NlibProperty.getString("login.newcouncil.url"); } // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 @@ -443,18 +452,19 @@ public class LoginController { SessionConfig.setNewMemberInfo(jsessionId, oauthUser); SessionConfig.removeLoginInfo(jsessionId); model.addAttribute("message", "회원가입하신 후, 이용 가능합니다."); - redirectUrl = NlibProperty.getString("member.new.url"); - return "redirect:" + redirectUrl; + return "redirect:" + NlibProperty.getString("member.new.url"); } else if(StringUtil.equalsIgnoreCase(loginResult, loginService.ERR_CODE_REQ_SNSLOGIN)) { SessionConfig.removeLoginInfo(jsessionId); model.addAttribute("message", "먼저 로그인할 SNS를 선택하여 로그인 바랍니다."); - redirectUrl = NlibProperty.getString("login.back.url"); - return "redirect:" + redirectUrl; + return "redirect:" + NlibProperty.getString("login.back.url"); } - - return "redirect:" + redirectUrl; - } + // 잘못된 접근 또는 기타 오류 + SessionConfig.removeLoginInfo(jsessionId); + model.addAttribute("message", "기타 문제로 인하여 로그인에 실패하였습니다. : " + loginResult); + return "redirect:" + NlibProperty.getString("login.back.url"); + } + /** * 로그아웃 후의 처리를 담당한다. 스프링 시큐리티에서 로그아웃이 수행된 후, 호출된다. * @@ -510,40 +520,6 @@ public class LoginController { return "nlib/login/activateDormantAccForm"; } - @RequestMapping("/login/agreeProvInfoForm.do") - public String agreeProvInfo( - HttpServletRequest req, - RedirectAttributes redirectAttrs, - @RequestParam Map paramMap, - Model model, - HttpSession session) { - - //---------------------------------------------- - // 지방문화원 사이트에서 접속한 경우, 지방문화원 정보 확인 - //---------------------------------------------- - String councilJsessionId = (String)session.getAttribute("councilJsessionId"); - String councilDnsHost = (String)session.getAttribute("councilDnsHost"); - String councilReturnUrl = (String)session.getAttribute("councilReturnUrl"); - String councilHomeUrl = (String)session.getAttribute("councilHomeUrl"); - String councilCd = (String)session.getAttribute("councilCd"); - String councilNm = (String)session.getAttribute("councilNm"); - - log.debug("activateDormantAccForm > sessionid=" + session.getId()); - log.debug("activateDormantAccForm > councilJsessionId = " + councilJsessionId); - log.debug("activateDormantAccForm > councilDnsHost = " + councilDnsHost); - log.debug("activateDormantAccForm > councilReturnUrl = " + councilReturnUrl); - log.debug("activateDormantAccForm > councilHomeUrl = " + councilHomeUrl); - log.debug("activateDormantAccForm > councilCd = " + councilCd); - log.debug("activateDormantAccForm > councilNm = " + councilNm); - - OAuthUniversalUser oauthUser = SessionConfig.getLoginInfo(session.getId()); - model.addAttribute("oauthUser", oauthUser); - model.addAttribute("councilCd", councilCd); - model.addAttribute("councilNm", councilNm); - - return "nlib/login/agreeProvInfoForm"; - } - /** * 휴면계좌 안내 및 해지 선택 화면을 표출한다. * @@ -599,10 +575,102 @@ public class LoginController { return "nlib/login/activateDormantAccForm"; } - // 로그인 처리 - return "redirect:/login/loginCouncilSSO.do"; + model.addAttribute("oauthUser", oauthUser); + + return "nlib/login/activateDormantAcc"; } + @RequestMapping("/login/agreeProvInfoForm.do") + public String agreeProvInfoForm( + HttpServletRequest req, + RedirectAttributes redirectAttrs, + @RequestParam Map paramMap, + Model model, + HttpSession session) { + + //---------------------------------------------- + // 지방문화원 사이트에서 접속한 경우, 지방문화원 정보 확인 + //---------------------------------------------- + String councilJsessionId = (String)session.getAttribute("councilJsessionId"); + String councilDnsHost = (String)session.getAttribute("councilDnsHost"); + String councilReturnUrl = (String)session.getAttribute("councilReturnUrl"); + String councilHomeUrl = (String)session.getAttribute("councilHomeUrl"); + String councilCd = (String)session.getAttribute("councilCd"); + String councilNm = (String)session.getAttribute("councilNm"); + + log.debug("activateDormantAccForm > sessionid=" + session.getId()); + log.debug("activateDormantAccForm > councilDnsHost = " + councilDnsHost); + log.debug("activateDormantAccForm > councilReturnUrl = " + councilReturnUrl); + log.debug("activateDormantAccForm > councilHomeUrl = " + councilHomeUrl); + log.debug("activateDormantAccForm > councilCd = " + councilCd); + log.debug("activateDormantAccForm > councilNm = " + councilNm); + + OAuthUniversalUser oauthUser = SessionConfig.getLoginInfo(session.getId()); + model.addAttribute("oauthUser", oauthUser); + model.addAttribute("councilCd", councilCd); + model.addAttribute("councilNm", councilNm); + + return "nlib/login/agreeProvInfoForm"; + } + + + @RequestMapping("/login/agreeProvInfo.do") + public String agreeProvInfo( + HttpServletRequest req, + RedirectAttributes redirectAttrs, + @RequestParam Map paramMap, + ModelMap model, + HttpSession session) throws Exception { + + //---------------------------------------------- + // 지방문화원 사이트에서 접속한 경우, 지방문화원 정보 확인 + //---------------------------------------------- + String councilJsessionId = (String)session.getAttribute("councilJsessionId"); + String councilDnsHost = (String)session.getAttribute("councilDnsHost"); + String councilReturnUrl = (String)session.getAttribute("councilReturnUrl"); + String councilHomeUrl = (String)session.getAttribute("councilHomeUrl"); + String councilCd = (String)session.getAttribute("councilCd"); + String councilNm = (String)session.getAttribute("councilNm"); + + String pCouncilCd = paramMap.get("councilCd"); + + if(StringUtil.isEmpty(pCouncilCd) || StringUtil.isEmpty(councilCd) || !StringUtil.equalsIgnoreCase(councilCd, pCouncilCd)) { + throw new Exception("잘못된 접근입니다."); + } + + log.debug("agreeProvInfo > sessionid=" + session.getId()); + log.debug("agreeProvInfo > councilDnsHost = " + councilDnsHost); + log.debug("agreeProvInfo > councilReturnUrl = " + councilReturnUrl); + log.debug("agreeProvInfo > councilHomeUrl = " + councilHomeUrl); + log.debug("agreeProvInfo > councilCd = " + councilCd); + log.debug("agreeProvInfo > councilNm = " + councilNm); + + // 지방문화원 추가 + OAuthUniversalUser oauthUser = SessionConfig.getLoginInfo(session.getId()); + NlibLoginVO nlibLoginVO = oauthUser.getNlibVO(); + nlibLoginVO.setJoinCouncilCd(pCouncilCd); + nlibLoginVO.setJoinType(oauthUser.getSnsType()); + int resultCount = loginService.agreeProvInfo(nlibLoginVO); + + //----------------------------------------------- + // 로그인 처리 + //----------------------------------------------- + String redirectUrl = loginProc(req, pCouncilCd, oauthUser, councilReturnUrl, model); + + // 정상 SNS 연동 로그인 + if(StringUtil.isNotEmpty(redirectUrl)) { + return redirectUrl; + } + + model.addAttribute("resultCount", resultCount); + model.addAttribute("oauthUser", oauthUser); + model.addAttribute("councilCd", councilCd); + model.addAttribute("councilNm", councilNm); + + return "nlib/login/agreeProvInfo"; + } + + // // 구글 로그인 콜백 // @RequestMapping(value = "/login/googleCallback.do") // public String googleCallback(@RequestParam(value = "code") String authCode, HttpSession session, Model model, diff --git a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml index d74b6ddd..e1e6f3f0 100644 --- a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml +++ b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml @@ -81,4 +81,23 @@ ) + + + INSERT INTO MB_SITE /* 가입문화원정보 */ + ( MB_INFO_ID + ,JOIN_TYPE + ,JOIN_AGREE_DD + ,JOIN_COUNCIL_CD + ,MASTER_YN + ) VALUES ( + #{mbInfoId} + ,#{joinType} + ,NOW() + ,#{joinCouncilCd} + ,'N' + ) + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/nlib/login/activateDormantAcc.jsp b/src/main/webapp/WEB-INF/jsp/nlib/login/activateDormantAcc.jsp new file mode 100644 index 00000000..977d6e5b --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/nlib/login/activateDormantAcc.jsp @@ -0,0 +1,74 @@ +<% +/** + *
+ * @Class Name : activateDormantAccForm.jsp
+ * 
+ * @Description : 휴면계좌 해지안내 및 확인 화면 
+ * 
+ * 
+ * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
+ *
+ * 
+ * + * @ ------------ -------- --------------------------- + * @ 수정일 수정자 수정내용 + * @ ------------ -------- --------------------------- + * @ 2021. 9. 1. KNKIM 최초 생성 + * + * + * @author 이씨플라자 * DIGITALSHIP KNKIM + * @since 2021. 9. 1. + * @version 1.0 + * + */ + %> +<%@ page language="java" contentType="text/html; charset=UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> +휴면계좌 해제 처리결과 + + + + +LoginTest + + + + + + + +
+ +

${pageTitle }

+ + +
+
+ +
+ +정상적으로 휴면 해제되었습니다.
+
+- 이름 : ${oauthUser.nlibVO.name}
+- 로그인ID : ${oauthUser.nlibVO.loginUserId}
+- 이메일 : ${oauthUser.nlibVO.email}
+
+ +
+ + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfo.jsp b/src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfo.jsp new file mode 100644 index 00000000..1c90ad58 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfo.jsp @@ -0,0 +1,77 @@ +<% +/** + *
+ * @Class Name : agreeProvInfoForm.jsp
+ * 
+ * @Description : 신규 지방문화원 정보제공 동의 화면 
+ * 
+ * 
+ * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
+ *
+ * 
+ * + * @ ------------ -------- --------------------------- + * @ 수정일 수정자 수정내용 + * @ ------------ -------- --------------------------- + * @ 2021. 9. 1. KNKIM 최초 생성 + * + * + * @author 이씨플라자 * DIGITALSHIP KNKIM + * @since 2021. 9. 1. + * @version 1.0 + * + */ + %> +<%@ page language="java" contentType="text/html; charset=UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> +지방문화원 정보제공 동의 + + + + +LoginTest + + + + + + + +
+ +

${pageTitle }

+ + +
+
+ + +
+ 정상적으로 처리되었습니다.
+
+ - 이름 : ${oauthUser.nlibVO.name}
+ - 로그인ID : ${oauthUser.nlibVO.loginUserId}
+ - 이메일 : ${oauthUser.nlibVO.email}
+ - 동의대상 지방문화원 : ${councilCd } ${councilNm }
+ - 처리결과 : ${resultCount }
+
+ + +
+ + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfoForm.jsp b/src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfoForm.jsp index f163962c..f560ae92 100644 --- a/src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfoForm.jsp +++ b/src/main/webapp/WEB-INF/jsp/nlib/login/agreeProvInfoForm.jsp @@ -57,23 +57,23 @@
-
- -
+
+ + +
+ 접속하신 지방문화원 서비스를 이용하려면 회원 정보 제공동의가 필요합니다.
+
+ - 이름 : ${oauthUser.nlibVO.name}
+ - 로그인ID : ${oauthUser.nlibVO.loginUserId}
+ - 이메일 : ${oauthUser.nlibVO.email}
+ - 동의대상 지방문화원 : ${councilCd } ${councilNm } -사용자 계정이 아래와 같이 휴면된 상태입니다.
-
-- 이름 : ${oauthUser.nlibVO.name}
-- 로그인ID : ${oauthUser.nlibVO.loginUserId}
-- 이메일 : ${oauthUser.nlibVO.email}
-- 동의대상 지방문화원 : ${councilCd } ${councilNm } - -
- "${councilNm }" 서비스를 이용하시려면 해당 문화원에 사용자 정보제공에 동의가 필요합니다.
- 동의하시겠습니까? -
- - +
+ "${councilNm }" 서비스를 이용하시려면 해당 문화원에 사용자 정보제공에 동의가 필요합니다.
+ 동의하시겠습니까? +
+ +
From 61b2b7717f8da5e278b2048f1d853ff766669ef8 Mon Sep 17 00:00:00 2001 From: KNKIM Date: Fri, 3 Sep 2021 10:08:38 +0900 Subject: [PATCH 2/4] =?UTF-8?q?DB=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nlib/user/web/LoginController.java | 25 +------------------ .../mapper/nlib/info/InformDAO_SQL.xml | 4 +-- .../WEB-INF/jsp/nlib/login/agreeProvInfo.jsp | 3 +-- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/main/java/nlib/user/web/LoginController.java b/src/main/java/nlib/user/web/LoginController.java index 6c9d4ddc..0e9068f2 100644 --- a/src/main/java/nlib/user/web/LoginController.java +++ b/src/main/java/nlib/user/web/LoginController.java @@ -414,26 +414,13 @@ public class LoginController { //----------------------------------------------- // 로그인 처리 //----------------------------------------------- - String redirectUrl = loginProc(req, councilCd, oauthUser, councilReturnUrl, model); - - // 정상 SNS 연동 로그인 - if(StringUtil.isNotEmpty(redirectUrl)) { - return redirectUrl; - } - - return "redirect:" + councilReturnUrl; - } - - public String loginProc(HttpServletRequest req, String councilCd, OAuthUniversalUser oauthUser, String councilReturnUrl, ModelMap model) { - - String jsessionId = req.getSession().getId(); String loginResult = loginService.loginCouncilSSO(req, councilCd, oauthUser); // 정상 SNS 연동 로그인 if(loginResult == null) { SessionConfig.removeLoginInfo(jsessionId); // 세션에 설정된 redirect 주소 확인 - return null; + return "redirect:" + councilReturnUrl; } // 휴면계좌 @@ -652,16 +639,6 @@ public class LoginController { nlibLoginVO.setJoinType(oauthUser.getSnsType()); int resultCount = loginService.agreeProvInfo(nlibLoginVO); - //----------------------------------------------- - // 로그인 처리 - //----------------------------------------------- - String redirectUrl = loginProc(req, pCouncilCd, oauthUser, councilReturnUrl, model); - - // 정상 SNS 연동 로그인 - if(StringUtil.isNotEmpty(redirectUrl)) { - return redirectUrl; - } - model.addAttribute("resultCount", resultCount); model.addAttribute("oauthUser", oauthUser); model.addAttribute("councilCd", councilCd); diff --git a/src/main/resources/egovframework/mapper/nlib/info/InformDAO_SQL.xml b/src/main/resources/egovframework/mapper/nlib/info/InformDAO_SQL.xml index dd9efa58..08a10c5d 100644 --- a/src/main/resources/egovframework/mapper/nlib/info/InformDAO_SQL.xml +++ b/src/main/resources/egovframework/mapper/nlib/info/InformDAO_SQL.xml @@ -7,13 +7,13 @@ SELECT CONTENT_ID , CONTENT_TYPE - , MNG_COUNCIL_CD + , MNG_ORG_CD , TITLE , CONTENT , BD_ATTACH_FILE_ATTACH_FILE_ID FROM BD_NLIB_CONTENT_PAGE A WHERE A.CONTENT_TYPE = SUBSTRING(#{conDivAndCounCd}, 1, INSTR(#{conDivAndCounCd}, '@') - 1) - AND A.MNG_COUNCIL_CD = SUBSTRING(#{conDivAndCounCd}, INSTR(#{conDivAndCounCd}, '@') + 1) + AND A.MNG_ORG_CD = SUBSTRING(#{conDivAndCounCd}, INSTR(#{conDivAndCounCd}, '@') + 1) + From 303302c99226fc8c3949e5f35dae01b204600b68 Mon Sep 17 00:00:00 2001 From: KNKIM Date: Fri, 3 Sep 2021 16:06:42 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=EC=95=94=ED=98=B8=ED=99=94=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EB=B3=80=EA=B2=BD=20(=EC=A0=84=EC=9E=90=EC=A0=95?= =?UTF-8?q?=EB=B6=80=ED=94=84=EB=A0=88=EC=9E=84=EC=9B=8C=ED=81=AC=20->=20?= =?UTF-8?q?=EC=9D=B4=EC=94=A8=ED=94=8C=EB=9D=BC=EC=9E=90=20=EC=A0=9C?= =?UTF-8?q?=EA=B3=B5=20=EC=86=8C=EC=8A=A4=20Aria=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 77 +-- pom.xml | 35 +- .../ext/oauth/web/EgovSignupController.java | 171 ----- .../java/nlib/bbs/web/BoardController.java | 4 +- src/main/java/nlib/cmm/crypto/AriaCrypto.java | 59 +- src/main/java/nlib/cmm/crypto/AriaEngine.java | 590 ++++++++++++++++++ src/main/java/nlib/cmm/crypto/AriaUtil.java | 355 +++++++++++ .../java/nlib/cmm/snslogin/NaverLoginBO.java | 102 --- .../sample/web/SampleEncoderController.java | 32 +- .../java/nlib/user/service/impl/LoginDAO.java | 15 +- .../java/nlib/user/web/MemberController.java | 10 - .../egovframework/spring/context-common.xml | 2 - src/main/resources/log4j2.xml | 2 +- .../jsp/nlib/sample/getSampleEncoder.jsp | 7 +- src/main/webapp/WEB-INF/web.xml | 10 +- 15 files changed, 1105 insertions(+), 366 deletions(-) delete mode 100644 src/main/java/egovframework/com/ext/oauth/web/EgovSignupController.java create mode 100644 src/main/java/nlib/cmm/crypto/AriaEngine.java create mode 100644 src/main/java/nlib/cmm/crypto/AriaUtil.java delete mode 100644 src/main/java/nlib/cmm/snslogin/NaverLoginBO.java diff --git a/.classpath b/.classpath index 17b99a85..3715aab0 100644 --- a/.classpath +++ b/.classpath @@ -1,38 +1,39 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 77ee104c..f8dfd8f7 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,8 @@ 4.3.16.RELEASE 3.8.0 4.2.5.RELEASE + 1.7.2 + 2.11.0 @@ -153,7 +155,31 @@ spring-expression ${spring.maven.artifact.version} - + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + runtime + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + runtime + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + commons-fileupload @@ -368,13 +394,6 @@ commons-lang3 3.3.2 - - - javax.servlet - javax.servlet-api - 3.1.0 - provided - diff --git a/src/main/java/egovframework/com/ext/oauth/web/EgovSignupController.java b/src/main/java/egovframework/com/ext/oauth/web/EgovSignupController.java deleted file mode 100644 index d6fd4127..00000000 --- a/src/main/java/egovframework/com/ext/oauth/web/EgovSignupController.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * eGovFrame OAuth - * Copyright The eGovFrame Open Community (http://open.egovframe.go.kr)). - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @author 이기하(슈퍼개발자K3) - */ -package egovframework.com.ext.oauth.web; - -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.servlet.http.HttpSession; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.social.connect.Connection; -import org.springframework.social.connect.ConnectionFactoryLocator; -import org.springframework.social.connect.UserProfile; -import org.springframework.social.connect.UsersConnectionRepository; -import org.springframework.social.connect.web.ProviderSignInUtils; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.context.request.WebRequest; - -//import egovframework.com.ext.oauth.service.EgovSignupService; -import egovframework.com.ext.oauth.service.OAuthConfig; -import egovframework.com.ext.oauth.service.OAuthLogin; -import egovframework.com.ext.oauth.service.OAuthUniversalUser; -import egovframework.com.ext.oauth.service.OAuthVO; -import egovframework.com.utl.fcc.service.EgovStringUtil; - -/** - * 소셜 계정으로 일반회원 가입을 처리하는 컨트롤러 클래스 - * @author 이기하 - * @since 2014.10.08 - * @version 1.0 - * @see - * - *
- * << 개정이력(Modification Information) >>
- *
- *   수정일     	수정자          수정내용
- *  -----------    --------    ---------------------------
- *  2014.10.08		이기하          최초 생성
- *  2018.10.02		신용호          Facebook 관련 ProviderSignInUtils 초기화 수정
- *  
- */ - -@Controller -public class EgovSignupController { - - private static final Logger LOGGER = LoggerFactory.getLogger(EgovSignupController.class); - - -// TODO 필요여부 확인할 것 DDDDDDDDDDDDDDDDDDDDDDDDD -// @Resource(name="signupService") -// private EgovSignupService signupService; - - //private ConnectionRepository connectionRepository; - //private final ProviderSignInUtils providerSignInUtils; - // TODO 필요여부 확인할 것 DDDDDDDDDDDDDDDDDDDDD - - @Inject - private OAuthVO naverAuthVO; - - @Inject - private OAuthVO googleAuthVO; - - @Inject - private OAuthVO kakaoAuthVO; - - -// TODO : 필요여부 확인할 것 DDDDDDDDDDDDDDDDDD -// @Inject -// public EgovSignupController(ConnectionFactoryLocator connectionFactoryLocator,UsersConnectionRepository connectionRepository) { -// //this.providerSignInUtils = new ProviderSignInUtils(); -// this.providerSignInUtils = new ProviderSignInUtils(connectionFactoryLocator, connectionRepository); -// } -// -// @RequestMapping(value="/signup", method=RequestMethod.GET) -// public String signupForm(WebRequest request) throws Exception { -// Connection connection = providerSignInUtils.getConnectionFromSession(request); -// if (connection != null) { -// UserProfile profile = connection.fetchUserProfile(); -// -// String key = EgovStringUtil.remove(connection.getKey().toString(), ':'); -// String account = signupService.signup(profile, request, key); -// if (account != null) { -// providerSignInUtils.doPostSignUp(key, request); -// return "redirect:/"; -// } -// } -// return "redirect:/"; -// } - - @RequestMapping(value = "/uat/uia/oauthLoginUsr", method = RequestMethod.GET) - public String login(Model model) throws Exception { - LOGGER.debug("===>>> OAuth Login ....."); - - OAuthLogin naverLogin = new OAuthLogin(naverAuthVO); - LOGGER.debug("naverLogin.getOAuthURL() = "+naverLogin.getOAuthURL()); - model.addAttribute("naver_url", naverLogin.getOAuthURL()); - - OAuthLogin googleLogin = new OAuthLogin(googleAuthVO); - LOGGER.debug("googleLogin.getOAuthURL() = "+googleLogin.getOAuthURL()); - model.addAttribute("google_url", googleLogin.getOAuthURL()); - - OAuthLogin kakaoLogin = new OAuthLogin(kakaoAuthVO); - LOGGER.debug("kakaoLogin.getOAuthURL() = "+kakaoLogin.getOAuthURL()); - model.addAttribute("kakao_url", kakaoLogin.getOAuthURL()); - - return "egovframework/com/uat/uia/EgovLoginUsrOauth"; - } - - @RequestMapping(value = "/auth/{oauthService}/callback", - method = { RequestMethod.GET, RequestMethod.POST}) - public String oauthLoginCallback(@PathVariable String oauthService, - Model model, @RequestParam String code, HttpSession session) throws Exception { - - LOGGER.debug("oauthLoginCallback: service={}", oauthService); - LOGGER.debug("===>>> code = "+ code); - OAuthVO oauthVO = null; - if (StringUtils.equals(OAuthConfig.GOOGLE_SERVICE_NAME, oauthService)) - oauthVO = googleAuthVO; - else if (StringUtils.equals(OAuthConfig.NAVER_SERVICE_NAME, oauthService)) - oauthVO = naverAuthVO; - else - oauthVO = kakaoAuthVO; - - // 1. code를 이용해서 Access Token 받기 - // 2. Access Token을 이용해서 사용자 제공정보 가져오기 - OAuthLogin oauthLogin = new OAuthLogin(oauthVO); - - OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시 - LOGGER.debug("Profile ===>>" + oauthUser); - - // ======================================================================== - // 다음 부분은 업무의 목적에 맞게 커스텀 코드를 작성한다. - // 3. 해당 유저가 DB에 존재하는지 체크 (google, naver, kakao에서 전달받은 ID가 존재하는지 체크) - String resultDBInfo = ""; // DB 체크 결과 - - if ( oauthUser == null || resultDBInfo == null) { - // 미존재시 가입페이지로!! - model.addAttribute("message", "This user does not exist. Please sign up."); - - } else { - // 존재시 로그인 처리 - model.addAttribute("message", "OAuth Sign-in succeeded."); - - } - - return "egovframework/com/uat/uia/EgovLoginUsrOauthResult"; - } - -} diff --git a/src/main/java/nlib/bbs/web/BoardController.java b/src/main/java/nlib/bbs/web/BoardController.java index 5855d1ad..b22375f6 100644 --- a/src/main/java/nlib/bbs/web/BoardController.java +++ b/src/main/java/nlib/bbs/web/BoardController.java @@ -634,7 +634,7 @@ public class BoardController extends NlibCommonController //------------------------------- // 비밀번호 : SHA-256 암호화 처리되어 DB에 저장되며, // 웹 화면에 표출될 때는 Aria로 articleNo를 Salt값으로 하여 재암호화처리하고 BASE64로 다시 한번 인코딩하여 표출함 - String encArticlePassword = StringUtil.encodeBase64(ariaCrypto.encode(shaArticlePassword, articleNo)); + String encArticlePassword = StringUtil.encodeBase64(ariaCrypto.encode(shaArticlePassword)); model.addAttribute("encArticlePassword", encArticlePassword); // 검색 정보 @@ -680,7 +680,7 @@ public class BoardController extends NlibCommonController // 비밀번호 : SHA-256 암호화 처리되어 DB에 저장되며, // 웹 화면에 표출될 때는 Aria로 articleNo를 Salt값으로 하여 재암호화처리하고 BASE64로 다시 한번 인코딩하여 표출함 String encArticlePassword = paramMap.get("encArticlePassword"); - String checkArticlePassword = ariaCrypto.decode(StringUtil.decodeBase64(encArticlePassword), articleNo); + String checkArticlePassword = ariaCrypto.decode(StringUtil.decodeBase64(encArticlePassword)); String articlePassword = paramMap.get("articlePassword"); //------------------------------- diff --git a/src/main/java/nlib/cmm/crypto/AriaCrypto.java b/src/main/java/nlib/cmm/crypto/AriaCrypto.java index f31d8b19..2f2a3479 100644 --- a/src/main/java/nlib/cmm/crypto/AriaCrypto.java +++ b/src/main/java/nlib/cmm/crypto/AriaCrypto.java @@ -3,13 +3,11 @@ package nlib.cmm.crypto; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import egovframework.rte.fdl.cryptography.EgovPasswordEncoder; import egovframework.rte.fdl.cryptography.impl.EgovARIACryptoServiceImpl; import nlib.cmm.service.NlibProperty; -import nlib.sample.web.SampleEncoderController; import nlib.util.StringUtil; /** @@ -51,18 +49,40 @@ public class AriaCrypto { * @return */ public static String encode(String value) { - log.info("encode : 암호화에 사용할 키 정보가 없으므로 기본키 정보를 사용합니다 : " + ARIA_DEFAULT_KEY); - return encode(value, ARIA_DEFAULT_KEY); + + String ret = null; + + try { + ret = AriaUtil.ariaEncrypt(value); + } catch(Exception e) { + log.error("ERROR at AriaCrypto.encode : " + e.toString()); + e.printStackTrace(); + ret = null; + } + + return ret; } + /** + * 기본키를 가지고 Egov 모듈을 사용하여 암호화한다. + * + * @param value + * @return + */ + public static String encodeEgov(String value) { + log.info("encode : 암호화에 사용할 키 정보가 없으므로 기본키 정보를 사용합니다 : " + ARIA_DEFAULT_KEY); + return encodeEgov(value, ARIA_DEFAULT_KEY); + } + + /** - * 전달받은 key(사용자고유번호 혹은 메일주소 등 salt값)로 암호화한다. + * 전달받은 key(사용자고유번호 혹은 메일주소 등 salt값)로 Egov 모듈을 사용하여 암호화한다. * * @param value * @param key * @return */ - public static String encode(String value, String key) { + public static String encodeEgov(String value, String key) { if(StringUtil.isEmpty(value)) { log.error("encode : 암호화할 문자열 정보가 없습니다."); @@ -94,17 +114,38 @@ public class AriaCrypto { * @return */ public static String decode(String value) { + + String ret = null; + + try { + ret = AriaUtil.ariaDecrypt(value); + } catch(Exception e) { + log.error("ERROR at AriaCrypto.decode : " + e.toString()); + e.printStackTrace(); + ret = null; + } + + return ret; + } + + /** + * 기본키를 가지고 Egov 모듈을 사용하여 복호화한다. + * + * @param value + * @return + */ + public static String decodeEgov(String value) { log.info("decode : 복호화에 사용할 키 정보가 없으므로 기본키 정보를 사용합니다 : " + ARIA_DEFAULT_KEY); - return decode(value, ARIA_DEFAULT_KEY); + return decodeEgov(value, ARIA_DEFAULT_KEY); } /** - * 전달받은 key(사용자고유번호 혹은 메일주소 등 salt값)로 복호화한다. + * 전달받은 key(사용자고유번호 혹은 메일주소 등 salt값)로 Egov 모듈을 사용하여 복호화한다. * @param value * @param key * @return */ - public static String decode(String value, String key) { + public static String decodeEgov(String value, String key) { if(StringUtil.isEmpty(value)) { log.error("decode : 복호화할 암호문자열 정보가 없습니다."); diff --git a/src/main/java/nlib/cmm/crypto/AriaEngine.java b/src/main/java/nlib/cmm/crypto/AriaEngine.java new file mode 100644 index 00000000..78bff06f --- /dev/null +++ b/src/main/java/nlib/cmm/crypto/AriaEngine.java @@ -0,0 +1,590 @@ +// +// ARIA.java +// +// A pure Java implementation of ARIA +// following the official ARIA specification at +// + +package nlib.cmm.crypto; + +import java.io.PrintStream; +import java.security.InvalidKeyException; + +public class AriaEngine { + + private static final char[] HEX_DIGITS = { + '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' + }; + + private static final int[][] KRK = { + {0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0}, + {0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0}, + {0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e} + }; + + private static final byte[] S1 = new byte[256]; + private static final byte[] S2 = new byte[256]; + private static final byte[] X1 = new byte[256]; + private static final byte[] X2 = new byte[256]; + + private static final int[] TS1 = new int[256]; + private static final int[] TS2 = new int[256]; + private static final int[] TX1 = new int[256]; + private static final int[] TX2 = new int[256]; + + private String publicKey = "CREDIF_MASTERKEY"; + + private String privateKey = ""; + + + // Static initializer. For setting up the tables + static { + int[] exp = new int[256]; + int[] log = new int[256]; + exp[0] = 1; + for (int i=1; i < 256; i++) { + int j = (exp[i-1] << 1) ^ exp[i-1]; + if ((j & 0x100) != 0) j ^= 0x11b; + exp[i] = j; + } + for (int i=1; i < 255; i++) + log[exp[i]] = i; + + int[][] A = { + {1, 0, 0, 0, 1, 1, 1, 1}, + {1, 1, 0, 0, 0, 1, 1, 1}, + {1, 1, 1, 0, 0, 0, 1, 1}, + {1, 1, 1, 1, 0, 0, 0, 1}, + {1, 1, 1, 1, 1, 0, 0, 0}, + {0, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 0}, + {0, 0, 0, 1, 1, 1, 1, 1} + }; + int[][] B = { + {0, 1, 0, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 0, 1}, + {1, 1, 0, 1, 0, 1, 1, 1}, + {1, 0, 0, 1, 1, 1, 0, 1}, + {0, 0, 1, 0, 1, 1, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 1}, + {0, 1, 0, 1, 1, 1, 0, 1}, + {1, 1, 0, 1, 0, 0, 1, 1} + }; + + for (int i=0; i<256; i++) { + int t=0, p; + if (i==0) + p=0; + else + p=exp[255-log[i]]; + for (int j=0; j<8; j++) { + int s=0; + for (int k=0; k<8; k++) { + if (((p>>>(7-k))&0x01)!=0) + s^=A[k][j]; + } + t=(t<<1)^s; + } + t^=0x63; + S1[i]=(byte)t; + X1[t]=(byte)i; + } + for (int i = 0; i < 256; i++) { + int t = 0, p; + if (i==0) + p=0; + else + p=exp[(247*log[i])%255]; + for (int j = 0; j < 8; j++) { + int s = 0; + for (int k = 0; k < 8; k++) { + if (((p >>> k) & 0x01) != 0) + s ^= B[7-j][k]; + } + t = (t << 1) ^ s; + } + t^=0xe2; + S2[i] = (byte) t; + X2[t] = (byte) i; + } + + for (int i = 0; i < 256; i++) { + TS1[i]=0x00010101*(S1[i]&0xff); + TS2[i]=0x01000101*(S2[i]&0xff); + TX1[i]=0x01010001*(X1[i]&0xff); + TX2[i]=0x01010100*(X2[i]&0xff); + } + } + + private int keySize=0; + private int numberOfRounds=0; + private byte[] masterKey=null; + private int[] encRoundKeys=null, decRoundKeys=null; + + public AriaEngine(int keySize) throws InvalidKeyException { + setKeySize(keySize); + } + + /** + * Resets the class so that it can be reused for another master key. + */ + void reset() { + this.keySize=0; + this.numberOfRounds=0; + this.masterKey=null; + this.encRoundKeys=null; + this.decRoundKeys=null; + } + + int getKeySize() { + return this.keySize; + } + + void setKeySize(int keySize) throws InvalidKeyException { + this.reset(); + if (keySize!=128 && keySize!=192 && keySize!=256) + throw new InvalidKeyException("keySize="+keySize); + this.keySize = keySize; + switch (keySize) { + case 128: + this.numberOfRounds = 12; + break; + case 192: + this.numberOfRounds = 14; + break; + case 256: + this.numberOfRounds = 16; + } + } + + void setKey(byte[] masterKey) throws InvalidKeyException { + if (masterKey.length*8>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff]; + t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff]; + t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff]; + t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff]; + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + t1=badc(t1); t2=cdab(t2); t3=dcba(t3); + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + + t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++]; + t0=TX1[(t0>>>24)&0xff]^TX2[(t0>>>16)&0xff]^TS1[(t0>>>8)&0xff]^TS2[t0&0xff]; + t1=TX1[(t1>>>24)&0xff]^TX2[(t1>>>16)&0xff]^TS1[(t1>>>8)&0xff]^TS2[t1&0xff]; + t2=TX1[(t2>>>24)&0xff]^TX2[(t2>>>16)&0xff]^TS1[(t2>>>8)&0xff]^TS2[t2&0xff]; + t3=TX1[(t3>>>24)&0xff]^TX2[(t3>>>16)&0xff]^TS1[(t3>>>8)&0xff]^TS2[t3&0xff]; + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + t3=badc(t3); t0=cdab(t0); t1=dcba(t1); + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + } + t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++]; + t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff]; + t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff]; + t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff]; + t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff]; + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + t1=badc(t1); t2=cdab(t2); t3=dcba(t3); + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + + t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++]; + o[ 0+ooffset] = (byte)(X1[0xff&(t0>>>24)] ^ (rk[j ]>>>24)); + o[ 1+ooffset] = (byte)(X2[0xff&(t0>>>16)] ^ (rk[j ]>>>16)); + o[ 2+ooffset] = (byte)(S1[0xff&(t0>>> 8)] ^ (rk[j ]>>> 8)); + o[ 3+ooffset] = (byte)(S2[0xff&(t0 )] ^ (rk[j ] )); + o[ 4+ooffset] = (byte)(X1[0xff&(t1>>>24)] ^ (rk[j+1]>>>24)); + o[ 5+ooffset] = (byte)(X2[0xff&(t1>>>16)] ^ (rk[j+1]>>>16)); + o[ 6+ooffset] = (byte)(S1[0xff&(t1>>> 8)] ^ (rk[j+1]>>> 8)); + o[ 7+ooffset] = (byte)(S2[0xff&(t1 )] ^ (rk[j+1] )); + o[ 8+ooffset] = (byte)(X1[0xff&(t2>>>24)] ^ (rk[j+2]>>>24)); + o[ 9+ooffset] = (byte)(X2[0xff&(t2>>>16)] ^ (rk[j+2]>>>16)); + o[10+ooffset] = (byte)(S1[0xff&(t2>>> 8)] ^ (rk[j+2]>>> 8)); + o[11+ooffset] = (byte)(S2[0xff&(t2 )] ^ (rk[j+2] )); + o[12+ooffset] = (byte)(X1[0xff&(t3>>>24)] ^ (rk[j+3]>>>24)); + o[13+ooffset] = (byte)(X2[0xff&(t3>>>16)] ^ (rk[j+3]>>>16)); + o[14+ooffset] = (byte)(S1[0xff&(t3>>> 8)] ^ (rk[j+3]>>> 8)); + o[15+ooffset] = (byte)(S2[0xff&(t3 )] ^ (rk[j+3] )); + } + + void encrypt(byte[] i, int ioffset, byte[] o, int ooffset) throws InvalidKeyException { + if (this.keySize==0) + throw new InvalidKeyException("keySize"); + if (this.encRoundKeys==null) + if (this.masterKey==null) + throw new InvalidKeyException("masterKey"); + else + setupEncRoundKeys(); + doCrypt(i, ioffset, this.encRoundKeys, this.numberOfRounds, o, ooffset); + } + + byte[] encrypt(byte[] i, int ioffset) throws InvalidKeyException { + byte[] o = new byte[16]; + this.encrypt(i, ioffset, o, 0); + return o; + } + + + public void decrypt(byte cipher[], byte plain[], int size) + throws InvalidKeyException { + int iLoop = size / 16; + int offset = 0; + for (int i = 0; i < iLoop; i++) { + decrypt(cipher, offset, plain, offset); + offset += 16; + } + + } + + void decrypt(byte[] i, int ioffset, byte[] o, int ooffset) throws InvalidKeyException { + if (this.keySize==0) + throw new InvalidKeyException("keySize"); + if (this.decRoundKeys==null) + if (this.masterKey==null) + throw new InvalidKeyException("masterKey"); + else + setupDecRoundKeys(); + doCrypt(i, ioffset, this.decRoundKeys, this.numberOfRounds, o, ooffset); + } + + byte[] decrypt(byte[] i, int ioffset) throws InvalidKeyException { + byte[] o = new byte[16]; + this.decrypt(i, ioffset, o, 0); + return o; + } + + private static void doEncKeySetup(byte[] mk, int[] rk, int keyBits) { + int t0, t1, t2, t3, q, j=0; + int[] w0 = new int[4]; + int[] w1 = new int[4]; + int[] w2 = new int[4]; + int[] w3 = new int[4]; + + w0[0] = toInt(mk[ 0], mk[ 1], mk[ 2], mk[ 3]); + w0[1] = toInt(mk[ 4], mk[ 5], mk[ 6], mk[ 7]); + w0[2] = toInt(mk[ 8], mk[ 9], mk[10], mk[11]); + w0[3] = toInt(mk[12], mk[13], mk[14], mk[15]); + + q = (keyBits - 128) / 64; + t0=w0[0]^KRK[q][0]; t1=w0[1]^KRK[q][1]; + t2=w0[2]^KRK[q][2]; t3=w0[3]^KRK[q][3]; + t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff]; + t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff]; + t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff]; + t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff]; + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + t1=badc(t1); t2=cdab(t2); t3=dcba(t3); + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + + if (keyBits > 128) { + w1[0] = toInt(mk[16], mk[17], mk[18], mk[19]); + w1[1] = toInt(mk[20], mk[21], mk[22], mk[23]); + if (keyBits > 192) { + w1[2] = toInt(mk[24], mk[25], mk[26], mk[27]); + w1[3] = toInt(mk[28], mk[29], mk[30], mk[31]); + } else { + w1[2]=w1[3]=0; + } + } else { + w1[0]=w1[1]=w1[2]=w1[3]=0; + } + w1[0]^=t0; w1[1]^=t1; w1[2]^=t2; w1[3]^=t3; + t0=w1[0]; t1=w1[1]; t2=w1[2]; t3=w1[3]; + + q = (q==2)? 0 : (q+1); + t0^=KRK[q][0]; t1^=KRK[q][1]; t2^=KRK[q][2]; t3^=KRK[q][3]; + t0=TX1[(t0>>>24)&0xff]^TX2[(t0>>>16)&0xff]^TS1[(t0>>>8)&0xff]^TS2[t0&0xff]; + t1=TX1[(t1>>>24)&0xff]^TX2[(t1>>>16)&0xff]^TS1[(t1>>>8)&0xff]^TS2[t1&0xff]; + t2=TX1[(t2>>>24)&0xff]^TX2[(t2>>>16)&0xff]^TS1[(t2>>>8)&0xff]^TS2[t2&0xff]; + t3=TX1[(t3>>>24)&0xff]^TX2[(t3>>>16)&0xff]^TS1[(t3>>>8)&0xff]^TS2[t3&0xff]; + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + t3=badc(t3); t0=cdab(t0); t1=dcba(t1); + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + t0^=w0[0]; t1^=w0[1]; t2^=w0[2]; t3^=w0[3]; + w2[0]=t0; w2[1]=t1; w2[2]=t2; w2[3]=t3; + + q = (q==2)? 0 : (q+1); + t0^=KRK[q][0]; t1^=KRK[q][1]; t2^=KRK[q][2]; t3^=KRK[q][3]; + t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff]; + t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff]; + t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff]; + t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff]; + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + t1=badc(t1); t2=cdab(t2); t3=dcba(t3); + t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2; + w3[0]=t0^w1[0]; w3[1]=t1^w1[1]; w3[2]=t2^w1[2]; w3[3]=t3^w1[3]; + + gsrk(w0, w1, 19, rk, j); j+=4; + gsrk(w1, w2, 19, rk, j); j+=4; + gsrk(w2, w3, 19, rk, j); j+=4; + gsrk(w3, w0, 19, rk, j); j+=4; + gsrk(w0, w1, 31, rk, j); j+=4; + gsrk(w1, w2, 31, rk, j); j+=4; + gsrk(w2, w3, 31, rk, j); j+=4; + gsrk(w3, w0, 31, rk, j); j+=4; + gsrk(w0, w1, 67, rk, j); j+=4; + gsrk(w1, w2, 67, rk, j); j+=4; + gsrk(w2, w3, 67, rk, j); j+=4; + gsrk(w3, w0, 67, rk, j); j+=4; + gsrk(w0, w1, 97, rk, j); j+=4; + if (keyBits > 128) { + gsrk(w1, w2, 97, rk, j); j+=4; + gsrk(w2, w3, 97, rk, j); j+=4; + } + if (keyBits > 192) { + gsrk(w3, w0, 97, rk, j); j+=4; + gsrk(w0, w1, 109, rk, j); + } + } + + /** + * Main bulk of the decryption key setup method. Here we assume that + * the int array rk already contains the encryption round keys. + * @param mk the master key + * @param rk the array which contains the encryption round keys at the + * beginning of the method execution. At the end of method execution + * this will hold the decryption round keys. + * @param keyBits the length of the master key + * @return + */ + private static void doDecKeySetup(byte[] mk, int[] rk, int keyBits) { + int a=0, z; + int[] t = new int[4]; + + z=32+keyBits/8; + swapBlocks(rk, 0, z); + a+=4; z-=4; + + for (; a>>24); + b[offset+1] = (byte)(i>>>16); + b[offset+2] = (byte)(i>>> 8); + b[offset+3] = (byte)(i ); + } + + private static int m(int t) { + return 0x00010101*((t>>>24)&0xff) ^ 0x01000101*((t>>>16)&0xff) ^ + 0x01010001*((t>>>8)&0xff) ^ 0x01010100*(t&0xff); + } + + private static final int badc(int t) { + return ((t<<8)&0xff00ff00) ^ ((t>>>8)&0x00ff00ff); + } + + private static final int cdab(int t) { + return ((t<<16)&0xffff0000) ^ ((t>>>16)&0x0000ffff); + } + + private static final int dcba(int t) { + return (t&0x000000ff)<<24 ^ (t&0x0000ff00)<<8 ^ (t&0x00ff0000)>>>8 ^ (t&0xff000000)>>>24; + } + + private static final void gsrk(int[] x, int[] y, int rot, int[] rk, int offset) { + int q=4-(rot/32), r=rot%32, s=32-r; + + rk[offset] = x[0] ^ y[(q )%4]>>>r ^ y[(q+3)%4]<>>r ^ y[(q )%4]<>>r ^ y[(q+1)%4]<>>r ^ y[(q+2)%4]<>> 4) & 0x0F], + HEX_DIGITS[ b & 0x0F] + }; + out.print(new String(buf)); + } + + private static void intToHex(PrintStream out, int i) { + byte[] b = new byte[4]; + toByteArray(i, b, 0); + byteToHex(out, b[0]); + byteToHex(out, b[1]); + byteToHex(out, b[2]); + byteToHex(out, b[3]); + } + + private static void printRoundKeys(PrintStream out, int[] roundKeys) { + for (int i=0; i= iLoop - 1) + if (iMod == 0) + iCopySize = 16; + else + iCopySize = iMod; + for (int j = 0; j < 16; j++) + in[j] = 0; + + System.arraycopy(plain, offset, in, 0, iCopySize); + encrypt(in, 0, cipher, offset); + offset += iCopySize; + } + + } + /* hex to byte[] convert */ + public static byte[] hexToByteArray(String hex) { + if (hex == null || hex.length() == 0) { + return null; + } + + byte[] ba = new byte[hex.length() / 2]; + for (int i = 0; i < ba.length; i++) { + ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); + } + return ba; + } + + + + /* byte to hexa convert */ + public static String byteArrayToHex(byte[] ba) { + if (ba == null || ba.length == 0) { + return null; + } + + StringBuffer sb = new StringBuffer(ba.length * 2); + String hexNumber; + for (int x = 0; x < ba.length; x++) { + hexNumber = "0" + Integer.toHexString(0xff & ba[x]); + + sb.append(hexNumber.substring(hexNumber.length() - 2)); + } + return sb.toString(); + } + + public AriaEngine(int keySize, String privateKey)throws InvalidKeyException { + + this.keySize = 0; + numberOfRounds = 0; + masterKey = null; + encRoundKeys = null; + decRoundKeys = null; + setKeySize(keySize); + + byte[] mk = new byte[32]; + this.privateKey = privateKey; + byte[] p1Key = this.publicKey.getBytes(); + System.arraycopy(p1Key, 0, mk, 0, p1Key.length); + this.setKey(mk); + this.setupRoundKeys(); + + byte[] p2Key = new byte[32]; + byte[] mk2 = new byte[32]; + byte[] privateKeyByte = privateKey.getBytes(); + if (privateKeyByte.length > 32) { + System.arraycopy(privateKeyByte, 0, mk2, 0, 32); + } else { + System.arraycopy(privateKeyByte, 0, mk2, 0, privateKeyByte.length); + } + byte[] makeKey = new byte[32]; + this.encrypt(mk2, makeKey, mk2.length); + this.setKey(makeKey); + this.setupRoundKeys(); + + + } + public static void main(String[] args) throws InvalidKeyException { + + } +} diff --git a/src/main/java/nlib/cmm/crypto/AriaUtil.java b/src/main/java/nlib/cmm/crypto/AriaUtil.java new file mode 100644 index 00000000..01783094 --- /dev/null +++ b/src/main/java/nlib/cmm/crypto/AriaUtil.java @@ -0,0 +1,355 @@ +/** + * 전자정부 제공 ARIAUTIL + * ARIAUtil + */ + +package nlib.cmm.crypto; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; + +import nlib.cmm.service.NlibProperty; + +public class AriaUtil { + + public static final String PRIVATE_KEY = NlibProperty.getProperty("crypto.aria.defaultKey"); + + public static String ariaEncrypt(String str, String privateKey) + throws InvalidKeyException, UnsupportedEncodingException { + if (str==null || str.equals("")) return ""; + + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + p = new byte[str.getBytes().length]; + p = str.getBytes(); + + int len = str.getBytes().length; + if ((len % 16) != 0) { + len = (len / 16 + 1) * 16; + } + c = new byte[len]; + System.arraycopy(p, 0, c, 0, p.length); + instance.encrypt(p, c, p.length); + + return AriaEngine.byteArrayToHex(c).toUpperCase(); + } + + /** + * @param privateKey + * @param src + * @param dest + * @throws IOException + * @throws InvalidKeyException + * @throws UnsupportedEncodingException + */ + public static void ariaFileEncrypt(String privateKey, String src, String dest) + throws IOException, InvalidKeyException, UnsupportedEncodingException { + File f = new File(src); + FileInputStream fis = new FileInputStream(src); + + long length = f.length(); + byte[] b = new byte[(int)length]; + + try { + int offset = 0; + int numRead = 0; + while (offset < b.length && (numRead=fis.read(b, offset, b.length-offset)) >= 0) { + offset += numRead; + } + if (offset < b.length) { + throw new IOException(f.getName()); + } + } finally{ + fis.close(); + } + + AriaEngine instance = new AriaEngine(256, privateKey); + int len = b.length; + if ((len % 16) != 0) { + len = (len / 16 + 1) * 16; + } + byte[] c = new byte[len]; + System.arraycopy(b, 0, c, 0, b.length); + instance.encrypt(b, c, b.length); + FileOutputStream fos = new FileOutputStream(dest); + try { + fos.write(c); + } catch (IOException e) { + + } finally { + try { + fos.close(); + } catch (IOException e) {} + } + } + + /* + *Aria 복호화 + */ + public static String ariaDecrypt(String strHex, String privateKey) + throws InvalidKeyException, UnsupportedEncodingException { + if (strHex==null || strHex.equals("")) return ""; + + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + + c = AriaEngine.hexToByteArray(strHex); + p = new byte[c.length]; + instance.decrypt(c, p, p.length); + + StringBuffer buf = new StringBuffer(); + buf.append(new String(p)); + + return buf.toString().trim(); + } + + + public static void ariaFileDecrypt(String privateKey, String src, String dest) + throws IOException, InvalidKeyException, UnsupportedEncodingException { + File f = new File(src); + FileInputStream fis = new FileInputStream(src); + + long length = f.length(); + byte[] b = new byte[(int)length]; + + try { + int offset = 0; + int numRead = 0; + while (offset < b.length && (numRead=fis.read(b, offset, b.length-offset)) >= 0) { + offset += numRead; + } + if (offset < b.length) { + throw new IOException(f.getName()); + } + } finally{ + fis.close(); + } + + AriaEngine instance = new AriaEngine(256, privateKey); + int len = b.length; + if ((len % 16) != 0) { + len = (len / 16 + 1) * 16; + } + byte[] c = new byte[len]; + System.arraycopy(b, 0, c, 0, b.length); + instance.decrypt(b, c, b.length); + + FileOutputStream fos = new FileOutputStream(dest); + try { + fos.write(c); + } catch (IOException e) { + + } finally { + try { + fos.close(); + } catch (IOException e) {} + } + } + + private static String makeMasterKey(String str) { + String appendStr = "Naravision KebiPortal Solution"; + StringBuffer buf = new StringBuffer(); + buf.append(str).append(appendStr); + + return buf.substring(0,32); + } + + + /* + *Aria 기본 복호화 + */ + public static String ariaDecrypt(String strHex) + throws InvalidKeyException, UnsupportedEncodingException { + String originalData = strHex; + if (strHex==null || strHex.equals("")) return ""; + StringBuffer buf = null; + try { + String privateKey = PRIVATE_KEY; + + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + + c = hexToByteArray(strHex); + p = new byte[c.length]; + instance.decrypt(c, p, p.length); + + buf = new StringBuffer(); + buf.append(new String(p)); + return buf.toString().trim(); + } catch (Exception e) { + e.printStackTrace(); + return originalData; + } + } + /* + *aria 기본 암호화 + */ + public static String ariaEncrypt(String str) + throws InvalidKeyException, UnsupportedEncodingException { + if (str==null || str.equals("")) return ""; + String privateKey = PRIVATE_KEY; + + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + p = new byte[str.getBytes().length]; + p = str.getBytes(); + + int len = str.getBytes().length; + if ((len % 16) != 0) { + len = (len / 16 + 1) * 16; + } + c = new byte[len]; + System.arraycopy(p, 0, c, 0, p.length); + instance.encrypt(p, c, p.length); + + return byteArrayToHex(c).toUpperCase(); + } + + /* + *캐릭터셋 변경 암호화 + */ + public static String ariaCharEncrypt(String str, String charset) + throws InvalidKeyException, UnsupportedEncodingException { + if (str==null || str.equals("")) return ""; + String privateKey = PRIVATE_KEY; + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + p = new byte[str.getBytes(charset).length]; + p = str.getBytes(charset); + int len = str.getBytes(charset).length; + if ((len % 16) != 0) { + len = (len / 16 + 1) * 16; + } + c = new byte[len]; + System.arraycopy(p, 0, c, 0, p.length); + instance.encrypt(p, c, p.length); + + return byteArrayToHex(c).toUpperCase(); + } + + /* + *캐릭터셋 변경 암호화 + *(서버타입설정 열람서버 : read, 등록관리서버 : regi) + */ + public static String ariaCharEncrypt(String str, String charset, String server) + throws InvalidKeyException, UnsupportedEncodingException { + if (str==null || str.equals("")) return ""; + String privateKey = ""; + if(server.equals("regi")) privateKey = PRIVATE_KEY; + else privateKey = PRIVATE_KEY; + + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + p = new byte[str.getBytes(charset).length]; + p = str.getBytes(charset); + int len = str.getBytes(charset).length; + if ((len % 16) != 0) { + len = (len / 16 + 1) * 16; + } + c = new byte[len]; + System.arraycopy(p, 0, c, 0, p.length); + instance.encrypt(p, c, p.length); + + return byteArrayToHex(c).toUpperCase(); + } + + + + /* + *Aria 캐릭터셋 변경 복호화 + */ + public static String ariaCharDecrypt(String strHex, String charset) + throws InvalidKeyException, UnsupportedEncodingException { + if (strHex==null || strHex.equals("")) return ""; + String privateKey = PRIVATE_KEY; + + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + + c = hexToByteArray(strHex); + p = new byte[c.length]; + instance.decrypt(c, p, p.length); + + StringBuffer buf = new StringBuffer(); + buf.append(new String(p,charset)); + + return buf.toString().trim(); + } + + /* + *Aria 캐릭터셋 변경 복호화 + *(서버타입설정 열람서버 : read, 등록관리서버 : regi) + */ + public static String ariaCharDecrypt(String strHex, String charset, String server) + throws InvalidKeyException, UnsupportedEncodingException { + if (strHex==null || strHex.equals("")) return ""; + String privateKey = ""; + if(server.equals("regi")) privateKey = PRIVATE_KEY; + else privateKey = PRIVATE_KEY; + + byte[] p; + byte[] c; + AriaEngine instance = new AriaEngine(256, privateKey); + + c = hexToByteArray(strHex); + p = new byte[c.length]; + instance.decrypt(c, p, p.length); + + StringBuffer buf = new StringBuffer(); + buf.append(new String(p,charset)); + + return buf.toString().trim(); + } + + // hex to byte[] + public static byte[] hexToByteArray(String hex) { + if (hex == null || hex.length() == 0) { + return null; + } + + byte[] ba = new byte[hex.length() / 2]; + + try { + + for (int i = 0; i < ba.length; i++) { + ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); + } + + }catch(NumberFormatException e){ + // + }catch(Exception e) { + // + } + + + return ba; + } + + // byte[] to hex + public static String byteArrayToHex(byte[] ba) { + if (ba == null || ba.length == 0) { + return null; + } + + StringBuffer sb = new StringBuffer(ba.length * 2); + String hexNumber; + for (int x = 0; x < ba.length; x++) { + hexNumber = "0" + Integer.toHexString(0xff & ba[x]); + + sb.append(hexNumber.substring(hexNumber.length() - 2)); + } + return sb.toString(); + + } +} diff --git a/src/main/java/nlib/cmm/snslogin/NaverLoginBO.java b/src/main/java/nlib/cmm/snslogin/NaverLoginBO.java deleted file mode 100644 index 126ab0d9..00000000 --- a/src/main/java/nlib/cmm/snslogin/NaverLoginBO.java +++ /dev/null @@ -1,102 +0,0 @@ -package nlib.cmm.snslogin; - -import java.io.IOException; -import java.util.UUID; - -import javax.servlet.http.HttpSession; - -import org.springframework.util.StringUtils; - -import com.github.scribejava.core.builder.ServiceBuilder; -import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthRequest; -import com.github.scribejava.core.model.Response; -import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; - -public class NaverLoginBO { - - /* 인증 요청문을 구성하는 파라미터 */ - //client_id: 애플리케이션 등록 후 발급받은 클라이언트 아이디 - //response_type: 인증 과정에 대한 구분값. code로 값이 고정돼 있습니다. - //redirect_uri: 네이버 로그인 인증의 결과를 전달받을 콜백 URL(URL 인코딩). 애플리케이션을 등록할 때 Callback URL에 설정한 정보입니다. - //state: 애플리케이션이 생성한 상태 토큰 - private final static String CLIENT_ID = "jefkoYhSfrQ3TtZz5mTp"; - private final static String CLIENT_SECRET = "E2qAGaLEaG"; - private static String REDIRECT_URI = ""; - private final static String SESSION_STATE = "oauth_state"; - /* 프로필 조회 API URL */ - private final static String PROFILE_API_URL = "https://openapi.naver.com/v1/nid/me"; - - public void setRedirect_url(String REDIRECT_URI) { - this.REDIRECT_URI = REDIRECT_URI; - } - /* 네이버 아이디로 인증 URL 생성 Method */ - public String getAuthorizationUrl(HttpSession session) { - - /* 세션 유효성 검증을 위하여 난수를 생성 */ - String state = generateRandomString(); - /* 생성한 난수 값을 session에 저장 */ - setSession(session,state); - System.out.println(getSession(session)); - - /* Scribe에서 제공하는 인증 URL 생성 기능을 이용하여 네아로 인증 URL 생성 */ - OAuth20Service oauthService = new ServiceBuilder() - .apiKey(CLIENT_ID) - .apiSecret(CLIENT_SECRET) - .callback(REDIRECT_URI) - .state(state) //앞서 생성한 난수값을 인증 URL생성시 사용함 - .build(NaverLoginApi.instance()); - - return oauthService.getAuthorizationUrl(); - } - /* 네이버아이디로 Callback 처리 및 AccessToken 획득 Method */ - public OAuth2AccessToken getAccessToken(HttpSession session, String code, String state) throws IOException{ - - /* Callback으로 전달받은 세선검증용 난수값과 세션에 저장되어있는 값이 일치하는지 확인 */ - String sessionState = getSession(session); - if(StringUtils.pathEquals(sessionState, state)){ - - OAuth20Service oauthService = new ServiceBuilder() - .apiKey(CLIENT_ID) - .apiSecret(CLIENT_SECRET) - .callback(REDIRECT_URI) - .state(state) - .build(NaverLoginApi.instance()); - - /* Scribe에서 제공하는 AccessToken 획득 기능으로 네아로 Access Token을 획득 */ - OAuth2AccessToken accessToken = oauthService.getAccessToken(code); - return accessToken; - } - return null; - } - - /* 세션 유효성 검증을 위한 난수 생성기 */ - private String generateRandomString() { - return UUID.randomUUID().toString(); - } - - /* http session에 데이터 저장 */ - private void setSession(HttpSession session,String state){ - session.setAttribute(SESSION_STATE, state); - } - - /* http session에서 데이터 가져오기 */ - private String getSession(HttpSession session){ - return (String) session.getAttribute(SESSION_STATE); - } - /* Access Token을 이용하여 네이버 사용자 프로필 API를 호출 */ - public String getUserProfile(OAuth2AccessToken oauthToken) throws IOException{ - - OAuth20Service oauthService =new ServiceBuilder() - .apiKey(CLIENT_ID) - .apiSecret(CLIENT_SECRET) - .callback(REDIRECT_URI).build(NaverLoginApi.instance()); - - OAuthRequest request = new OAuthRequest(Verb.GET, PROFILE_API_URL, oauthService); - oauthService.signRequest(oauthToken, request); - Response response = request.send(); - return response.getBody(); - } - -} diff --git a/src/main/java/nlib/sample/web/SampleEncoderController.java b/src/main/java/nlib/sample/web/SampleEncoderController.java index fcfee737..1cb41074 100644 --- a/src/main/java/nlib/sample/web/SampleEncoderController.java +++ b/src/main/java/nlib/sample/web/SampleEncoderController.java @@ -14,6 +14,7 @@ import egovframework.rte.fdl.cryptography.EgovEnvCryptoService; import egovframework.rte.fdl.cryptography.EgovPasswordEncoder; import egovframework.rte.fdl.cryptography.impl.EgovARIACryptoServiceImpl; import nlib.cmm.crypto.AriaCrypto; +import nlib.cmm.service.NlibProperty; import nlib.util.StringUtil; /** @@ -61,46 +62,49 @@ public class SampleEncoderController { public String getSampleInfoForm(ModelMap model , @RequestParam(required=false) String hash , @RequestParam(required=false) String plainText - , @RequestParam(required=false) String key + , @RequestParam(required=false) String encodedText ) throws Exception { String msg = null; - String encodedText = null; String decodedText = null; if(StringUtil.isEmpty(hash)) { msg = "암호화 알고리즘을 선택하여 주시기 바랍니다."; - } else if(StringUtil.isEmpty(plainText)) { - msg = "암호화할 문자열을 입력하여 주시기 바랍니다."; - } else { - + } else if(StringUtil.isNotEmpty(plainText)) { + // 암호처리 log.debug("암호화 처리 시작 =" + plainText + "="); - if("sha-256".equals(hash)) { + if("sha-256".equalsIgnoreCase(hash)) { encodedText = egovPasswordEncoder.encryptPassword(plainText); } else if("aria".equals(hash)) { - if(StringUtil.isEmpty(key)) encodedText = ariaCrypto.encode(plainText); - else encodedText = ariaCrypto.encode(plainText, key); + encodedText = ariaCrypto.encode(plainText); log.debug(" Aria plainText=" + plainText); log.debug(" Aria encodedText=" + encodedText); - if(StringUtil.isEmpty(key)) decodedText = ariaCrypto.decode(encodedText); - else decodedText = ariaCrypto.decode(encodedText, key); - + decodedText = ariaCrypto.decode(encodedText); log.debug(" Aria after decoding, decodedText=" + decodedText); + } else { msg = "암호화 알고리즘이 적합하지 않습니다."; } + } else if("aria".equalsIgnoreCase(hash) && StringUtil.isNotEmpty(encodedText)) { + // 복호처리 + decodedText = ariaCrypto.decode(encodedText); + log.debug(" Aria after decoding, decodedText=" + decodedText); + + } else { + msg = "암호화할 문자열을 입력하여 주시기 바랍니다."; } + model.addAttribute("msg", msg); - model.addAttribute("hash", hash); + model.addAttribute("hash", StringUtil.getString(hash, "aria")); model.addAttribute("plainText", plainText); model.addAttribute("encodedText", encodedText); model.addAttribute("decodedText", decodedText); - model.addAttribute("key", key); + model.addAttribute("key", NlibProperty.getProperty("crypto.aria.defaultKey")); return "nlib/sample/getSampleEncoder"; } diff --git a/src/main/java/nlib/user/service/impl/LoginDAO.java b/src/main/java/nlib/user/service/impl/LoginDAO.java index b504392a..6cd71b34 100644 --- a/src/main/java/nlib/user/service/impl/LoginDAO.java +++ b/src/main/java/nlib/user/service/impl/LoginDAO.java @@ -6,6 +6,7 @@ import java.util.HashMap; import org.springframework.stereotype.Repository; import egovframework.com.cmm.service.impl.EgovComAbstractDAO; +import nlib.cmm.crypto.AriaCrypto; import nlib.restful.service.DataApiReqVO; import nlib.restful.service.DataApiResVO; import nlib.user.service.NlibLoginVO; @@ -22,7 +23,19 @@ public class LoginDAO extends EgovComAbstractDAO { } public NlibLoginVO selectLoginUserInfo(NlibLoginVO nLoginParamVO) { - return (NlibLoginVO) selectOne("LoginDAO.selectLoginUserInfo", nLoginParamVO); + + NlibLoginVO nlibLoginVO = selectOne("LoginDAO.selectLoginUserInfo", nLoginParamVO); + + // 개인정보 암호화 내용 복호화 처리 + if(nlibLoginVO != null) { + nlibLoginVO.setMobileNo(AriaCrypto.decode(nlibLoginVO.getMobileNo())); + nlibLoginVO.setEmail(AriaCrypto.decode(nlibLoginVO.getEmail())); + nlibLoginVO.setZipCode(AriaCrypto.decode(nlibLoginVO.getZipCode())); + nlibLoginVO.setAddress(AriaCrypto.decode(nlibLoginVO.getAddress())); + nlibLoginVO.setAddressDetail(AriaCrypto.decode(nlibLoginVO.getAddressDetail())); + nlibLoginVO.setBirthday(AriaCrypto.decode(nlibLoginVO.getBirthday())); + } + return (NlibLoginVO) nlibLoginVO; } public void insertLoginLog(NlibLoginVO userVO) { diff --git a/src/main/java/nlib/user/web/MemberController.java b/src/main/java/nlib/user/web/MemberController.java index 5f14cb52..8b76635c 100644 --- a/src/main/java/nlib/user/web/MemberController.java +++ b/src/main/java/nlib/user/web/MemberController.java @@ -63,7 +63,6 @@ import nlib.cmm.service.NlibProperty; import nlib.cmm.session.SessionConfig; import nlib.cmm.snslogin.GoogleOAuthResponse; import nlib.cmm.snslogin.KakaoController; -import nlib.cmm.snslogin.NaverLoginBO; import nlib.info.service.InformService; import nlib.mail.EmailSender; import nlib.mail.service.EmailVO; @@ -126,15 +125,6 @@ public class MemberController { @Resource(name = "egovEnvPasswordEncoderService") EgovPasswordEncoder egovPasswordEncoder; - /* NaverLoginBO */ - private NaverLoginBO naverLoginBO; - private String apiResult = null; - - @Autowired - private void setNaverLoginBO(NaverLoginBO naverLoginBO) { - this.naverLoginBO = naverLoginBO; - } - @Autowired private EmailSender emailSender; diff --git a/src/main/resources/egovframework/spring/context-common.xml b/src/main/resources/egovframework/spring/context-common.xml index a20eb93d..cc683c40 100644 --- a/src/main/resources/egovframework/spring/context-common.xml +++ b/src/main/resources/egovframework/spring/context-common.xml @@ -65,8 +65,6 @@ - - diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 0c391df1..ecee2104 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -29,7 +29,7 @@ - + diff --git a/src/main/webapp/WEB-INF/jsp/nlib/sample/getSampleEncoder.jsp b/src/main/webapp/WEB-INF/jsp/nlib/sample/getSampleEncoder.jsp index abaecdd9..86fa916f 100644 --- a/src/main/webapp/WEB-INF/jsp/nlib/sample/getSampleEncoder.jsp +++ b/src/main/webapp/WEB-INF/jsp/nlib/sample/getSampleEncoder.jsp @@ -55,16 +55,15 @@

${pageTitle}

msg : ${msg}
hash : ("sha-256" 또는 "aria" 입력)
+ key : ${key} (hash 알고리즘이 aria인 경우)
plainText :
encodedText :
- decodedText :
- key : (hash 알고리즘이 aria인 경우 입력 필수)
- + decodedText : ${decodedText}
 
- +
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 29244d90..a2bb363e 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -1,8 +1,10 @@ - + + nlib From 4a61cc54e184151ac5f43d3416abee26d0cffd40 Mon Sep 17 00:00:00 2001 From: KNKIM Date: Fri, 3 Sep 2021 16:52:05 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EC=B5=9C=EC=A2=85=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=9D=BC=EC=8B=9C=20=EA=B8=B0=EB=A1=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nlib/user/service/impl/LoginDAO.java | 7 ++++++- .../user/service/impl/LoginServiceImpl.java | 1 + .../mapper/nlib/user/LoginDAO_SQL.xml | 21 +++++++++++++++++-- src/main/resources/log4j2.xml | 2 +- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/nlib/user/service/impl/LoginDAO.java b/src/main/java/nlib/user/service/impl/LoginDAO.java index 6cd71b34..eca61393 100644 --- a/src/main/java/nlib/user/service/impl/LoginDAO.java +++ b/src/main/java/nlib/user/service/impl/LoginDAO.java @@ -39,7 +39,12 @@ public class LoginDAO extends EgovComAbstractDAO { } public void insertLoginLog(NlibLoginVO userVO) { - insert("LoginDAO.insertLoginLog", userVO); + + // 사용자 최종 접속정보 업데이트 + update("LoginDAO.updateLoginTimeStamp", userVO); + + // 사용자 접속 로그 등록 + insert("LoginDAO.insertLoginLog", userVO); } public HashMap selectCouncilInfoByDnsHost(String councilDnsHost) { diff --git a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java index 269dca02..14d27e92 100644 --- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java +++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java @@ -143,6 +143,7 @@ public class LoginServiceImpl implements LoginService } // 로그인 로그 정보 저장 + nlibLoginedVO.setIp(req.getRemoteAddr()); loginDAO.insertLoginLog(nlibLoginedVO); return null; diff --git a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml index e1e6f3f0..5c7a4b1b 100644 --- a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml +++ b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml @@ -61,6 +61,15 @@ AND A.STATUS = 'P' /* 휴면 */ + + UPDATE UAC_CLTR_DB.MB_INFO A /* 사용자정보 */ + SET A.IP = #{ip} + , A.LAST_ACCESS_DD = NOW() + , A.MOD_ID = #{mbInfoId} + , A.MOD_DD = NOW() + WHERE MB_INFO_ID = #{mbInfoId} + + INSERT INTO SM_ACC_LOG /* 접속로그 */ ( USER_ID @@ -89,13 +98,21 @@ ,JOIN_AGREE_DD ,JOIN_COUNCIL_CD ,MASTER_YN - ) VALUES ( + ) + SELECT #{mbInfoId} ,#{joinType} ,NOW() ,#{joinCouncilCd} ,'N' - ) + FROM UAC_CLTR_DB.TMP_MB_SITE_INFO + WHERE JOIN_COUNCIL_CD = #{joinCouncilCd} + AND NOT EXISTS ( + SELECT MB_SITE_ID + FROM MB_SITE S + WHERE S.MB_INFO_ID = #{mbInfoId} + AND S.JOIN_COUNCIL_CD = #{joinCouncilCd} + ) diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index ecee2104..0c391df1 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -29,7 +29,7 @@
- +