diff --git a/pom.xml b/pom.xml index fd1e0201..c7ddbe01 100644 --- a/pom.xml +++ b/pom.xml @@ -477,12 +477,19 @@ - + + + + + kmc + ICERTSecu + JDK18_v2 diff --git a/src/main/java/itn/let/cert/phone/web/CertPhoneWebController.java b/src/main/java/itn/let/cert/phone/web/CertPhoneWebController.java index 3aeccb1f..b35fa156 100644 --- a/src/main/java/itn/let/cert/phone/web/CertPhoneWebController.java +++ b/src/main/java/itn/let/cert/phone/web/CertPhoneWebController.java @@ -34,12 +34,11 @@ public class CertPhoneWebController { @RequestMapping(value = {"/web/cert/log/insertCertLog.do"}) public ResponseEntity insertCertLog(HttpServletRequest request) throws Exception { - - - - - - return ResponseEntity.ok().body(new StatusResponse(HttpStatus.OK, certPhoneService.insertCertLog(request), LocalDateTime.now())); - } + } + + @RequestMapping(value = {"/web/cert/log/kmcErrorPage.do"}) + public String kmcErrorPage() throws Exception { + return "web/cop/kmc/certResultError"; + } } \ No newline at end of file diff --git a/src/main/java/itn/let/mjo/pay/service/KmcVO.java b/src/main/java/itn/let/mjo/pay/service/KmcVO.java index 2eecca4e..3a662cd2 100644 --- a/src/main/java/itn/let/mjo/pay/service/KmcVO.java +++ b/src/main/java/itn/let/mjo/pay/service/KmcVO.java @@ -226,6 +226,4 @@ public class KmcVO extends ComDefaultVO{ this.certType = certType; } - - } diff --git a/src/main/java/itn/let/mjo/pay/web/MjonPayController.java b/src/main/java/itn/let/mjo/pay/web/MjonPayController.java index e4a4e305..b65e7b3c 100644 --- a/src/main/java/itn/let/mjo/pay/web/MjonPayController.java +++ b/src/main/java/itn/let/mjo/pay/web/MjonPayController.java @@ -91,6 +91,7 @@ import itn.let.sym.grd.service.MberGrdVO; import itn.let.sym.site.service.EgovSiteManagerService; import itn.let.sym.site.service.JoinSettingVO; import itn.let.uat.uia.service.AuthCertVO; +import itn.let.uat.uia.web.KmcCertChecker; import itn.let.uss.umt.service.EgovMberManageService; import itn.let.uss.umt.service.EgovUserManageService; import itn.let.uss.umt.service.MberManageVO; @@ -165,7 +166,10 @@ public class MjonPayController { EgovSiteManagerService egovSiteManagerService; @Resource(name = "mberGrdService") - MberGrdService mberGrdService; + MberGrdService mberGrdService; + + @Resource(name = "KmcCertChecker") + KmcCertChecker kmcCertChecker; //배열 정의{"컬럼순차번호, 컬럼이름, 컬럼내용, 컬럼이름에 붙여야할 내용(엑셀코드양식다운로드시 필요)"} private String[][] sendPayExcelValue ={ @@ -930,7 +934,7 @@ public class MjonPayController { } /** - * 나이스페이(PG사 전송화면) + * 회원가입 본인인증 * * @param * @return @@ -941,253 +945,7 @@ public class MjonPayController { ModelMap model , @RequestParam Map commandMap, @ModelAttribute("searchVO") KmcVO kmcVO) throws Exception { - //크롬 SameSite정책 방지 - 도메인이 다른 타사로 이동 시 크롬 정책에 의해 세션 유실이 일어나는 경우가 있는데, 이를 방지하기 위해 samesite 보안을 none처리 - response.setHeader("Set-Cookie", "mberSession=mberSession; Secure; SameSite=None"); - - System.out.println("++++++++++++ 세션체크 ::: "+ session.getAttribute("mberSession")); - - String errMessage = ""; //에러메세지 - - String rec_cert = ""; // 결과값(암호화) - String certNum = ""; // certNum - - rec_cert = request.getParameter("rec_cert").trim(); - certNum = request.getParameter("certNum").trim(); - - kmcVO.setRecCert(rec_cert); - kmcVO.setCertNum(certNum); - // 파라미터 유효성 검증 - if( rec_cert.length() == 0 || certNum.length() == 0 ){ - errMessage = "비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - - - // 변수선언 -------------------------------------------------------------------------------------------------------- - String k_certNum = ""; // 파라미터로 수신한 요청번호 - k_certNum = certNum; - String date = ""; // 요청일시 - String CI = ""; // 연계정보(CI) - String DI = ""; // 중복가입확인정보(DI) - String phoneNo = ""; // 휴대폰번호 - String phoneCorp = ""; // 이동통신사 - String birthDay = ""; // 생년월일 - String gender = ""; // 성별 - String nation = ""; // 내국인 - String name = ""; // 성명 - String M_name = ""; // 미성년자 성명 - String M_birthDay = ""; // 미성년자 생년월일 - String M_Gender = ""; // 미성년자 성별 - String M_nation = ""; // 미성년자 내외국인 - String result = ""; // 결과값 - - String certMet = ""; // 인증방법 - String ip = ""; // ip주소 - String plusInfo = ""; - - String encPara = ""; - String encMsg1 = ""; - String encMsg2 = ""; - String msgChk = ""; - - com.icert.comm.secu.IcertSecuManager seed = new com.icert.comm.secu.IcertSecuManager(); - - //02. 1차 복호화 - //수신된 certNum를 이용하여 복호화 - rec_cert = seed.getDec(rec_cert, k_certNum); - - //03. 1차 파싱 - int inf1 = rec_cert.indexOf("/",0); - int inf2 = rec_cert.indexOf("/",inf1+1); - - encPara = rec_cert.substring(0,inf1); //암호화된 통합 파라미터 - encMsg1 = rec_cert.substring(inf1+1,inf2); //암호화된 통합 파라미터의 Hash값 - - //04. 위변조 검증 - encMsg2 = seed.getMsg(encPara); - kmcVO.setEncMsg2(encMsg2); - if(encMsg2.equals(encMsg1)){ - msgChk="Y"; - } - - if(!"Y".equals(msgChk)) { - errMessage = "비정상접근입니다."; - return returnPage(model , errMessage , kmcVO) ; - } - - //05. 2차 복호화 - rec_cert = seed.getDec(encPara, k_certNum); - kmcVO.setRecCert(rec_cert); - //06. 2차 파싱 - int info1 = rec_cert.indexOf("/",0); - int info2 = rec_cert.indexOf("/",info1+1); - int info3 = rec_cert.indexOf("/",info2+1); - int info4 = rec_cert.indexOf("/",info3+1); - int info5 = rec_cert.indexOf("/",info4+1); - int info6 = rec_cert.indexOf("/",info5+1); - int info7 = rec_cert.indexOf("/",info6+1); - int info8 = rec_cert.indexOf("/",info7+1); - int info9 = rec_cert.indexOf("/",info8+1); - int info10 = rec_cert.indexOf("/",info9+1); - int info11 = rec_cert.indexOf("/",info10+1); - int info12 = rec_cert.indexOf("/",info11+1); - int info13 = rec_cert.indexOf("/",info12+1); - int info14 = rec_cert.indexOf("/",info13+1); - int info15 = rec_cert.indexOf("/",info14+1); - int info16 = rec_cert.indexOf("/",info15+1); - int info17 = rec_cert.indexOf("/",info16+1); - int info18 = rec_cert.indexOf("/",info17+1); - - certNum = rec_cert.substring(0,info1); kmcVO.setCertNum(certNum); - date = rec_cert.substring(info1+1,info2); kmcVO.setDate(date); - CI = rec_cert.substring(info2+1,info3); kmcVO.setCI(CI); - phoneNo = rec_cert.substring(info3+1,info4); kmcVO.setPhoneNo(phoneNo); - phoneCorp = rec_cert.substring(info4+1,info5); kmcVO.setPhoneCorp(phoneCorp); - birthDay = rec_cert.substring(info5+1,info6); kmcVO.setBirthDay(birthDay); - gender = rec_cert.substring(info6+1,info7); kmcVO.setGender(gender); - nation = rec_cert.substring(info7+1,info8); kmcVO.setNation(nation); - name = rec_cert.substring(info8+1,info9); kmcVO.setName(name); - result = rec_cert.substring(info9+1,info10); kmcVO.setResult(result); - certMet = rec_cert.substring(info10+1,info11); kmcVO.setCertMet(certMet); - ip = rec_cert.substring(info11+1,info12); kmcVO.setIp(ip); - M_name = rec_cert.substring(info12+1,info13); kmcVO.setMName(M_name); - M_birthDay = rec_cert.substring(info13+1,info14); kmcVO.setMBirthDay(M_birthDay); - M_Gender = rec_cert.substring(info14+1,info15); kmcVO.setMGender(M_Gender); - M_nation = rec_cert.substring(info15+1,info16); kmcVO.setMNation(M_nation); - plusInfo = rec_cert.substring(info16+1,info17); kmcVO.setPlusInfo(plusInfo); - DI = rec_cert.substring(info17+1,info18); kmcVO.setDI(DI); - - //07. CI, DI 복호화 - CI = seed.getDec(CI, k_certNum); kmcVO.setCI(CI); - DI = seed.getDec(DI, k_certNum); kmcVO.setDI(DI); - - if("Y".equals(result)) { - - } - - //-------------------------------------------------------------- - String regex = ""; - if( certNum.length() == 0 || certNum.length() > 40){ - errMessage = "요청번호 비정상."; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[0-9]*"; - if( date.length() != 14 || !paramChk(regex, date) ){ - errMessage = "요청일시"; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[A-Z]*"; - if( certMet.length() != 1 || !paramChk(regex, certMet) ){ - errMessage = "본인인증방법 비정상" + certMet; - return returnPage(model , errMessage , kmcVO) ; - } - - - regex = "[0-9]*"; - if( (phoneNo.length() != 10 && phoneNo.length() != 11) || !paramChk(regex, phoneNo) ){ - errMessage = "휴대폰번호 비정상" ; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[A-Z]*"; - if( phoneCorp.length() != 3 || !paramChk(regex, phoneCorp) ){ - errMessage = "이동통신사 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[0-9]*"; - if( birthDay.length() != 8 || !paramChk(regex, birthDay) ){ - errMessage = "생년월일 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[0-9]*"; - if( gender.length() != 1 || !paramChk(regex, gender) ){ - errMessage = "성별 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[0-9]*"; - if( nation.length() != 1 || !paramChk(regex, nation) ){ - errMessage = "내/외국인 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[\\sA-Za-z가-�R.,-]*"; - if( name.length() > 60 || !paramChk(regex, name) ){ - errMessage = "성명 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[A-Z]*"; - if( result.length() != 1 || !paramChk(regex, result) ){ - errMessage = "결과값 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - - regex = "[\\sA-Za-z가-?.,-]*"; - if( M_name.length() != 0 ){ - if( M_name.length() > 60 || !paramChk(regex, M_name) ){ - errMessage = "미성년자 성명 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - } - - regex = "[0-9]*"; - if( M_birthDay.length() != 0 ){ - if( M_birthDay.length() != 8 || !paramChk(regex, M_birthDay) ){ - errMessage = "미성년자 생년월일 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - } - - regex = "[0-9]*"; - if( M_Gender.length() != 0 ){ - if( M_Gender.length() != 1 || !paramChk(regex, M_Gender) ){ - errMessage = "미성년자 성별 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - } - - regex = "[0-9]*"; - if( M_nation.length() != 0 ){ - if( M_nation.length() != 1 || !paramChk(regex, M_nation) ){ - errMessage = "미성년자 내/외국인 비정상"; - return returnPage(model , errMessage , kmcVO) ; - } - } - - //본인인증 결과 내용 저장하기. - /*System.out.println("+++++++++++++ getCertNum ::: "+kmcVO.getCertNum()); - System.out.println("+++++++++++++ getDate ::: "+kmcVO.getDate()); - System.out.println("+++++++++++++ getDI ::: "+kmcVO.getDI()); - System.out.println("+++++++++++++ getPhoneNo ::: "+kmcVO.getPhoneNo()); - System.out.println("+++++++++++++ getNation ::: "+kmcVO.getNation()); - System.out.println("+++++++++++++ getName ::: "+kmcVO.getName()); - System.out.println("+++++++++++++ getResult ::: "+kmcVO.getResult()); - System.out.println("+++++++++++++ getCertMet ::: "+kmcVO.getCertMet()); - System.out.println("+++++++++++++ getIp ::: "+kmcVO.getIp());*/ - - //KMC 본인인증 정보를 세션에 담아준다. - /*AuthCertVO certVO = new AuthCertVO(); - certVO.setCertNum(kmcVO.getCertNum()); - certVO.setCertDate(kmcVO.getDate()); - certVO.setCertDi(kmcVO.getDI()); - certVO.setCertPhone(kmcVO.getPhoneNo()); - certVO.setCertNation(kmcVO.getNation()); - certVO.setCertName(kmcVO.getName()); - certVO.setCertResult(kmcVO.getResult()); - certVO.setCertType("KMC문자인증"); - certVO.setCertIpaddr(kmcVO.getIp()); - certVO.setBirthDay(kmcVO.getBirthDay()); - certVO.setSexdstnCode(kmcVO.getGender());*/ - - /*request.getSession().setAttribute("AuthKmcCertVO", certVO);*/ - - /*System.out.println("++++++++++++ 세션체크22 ::: "+(MberManageVO) session.getAttribute("mberSession"));*/ - + kmcVO = kmcCertChecker.authCertResult(request, response, model); //KMC 본인인증 로그 insert AuthCertVO certVO = new AuthCertVO(); certVO.setMberId(kmcVO.getPlusInfo()); @@ -6178,5 +5936,298 @@ public class MjonPayController { return p_response; } + + + + + /** + * 회원가입 본인인증 + * + * @param + * @return + * @throws Exception + */ + @RequestMapping("/web/cop/kmc/authRequestAjax_back.do") + public String authRequestAjax_back(HttpServletRequest request, HttpSession session, HttpServletResponse response, + ModelMap model , @RequestParam Map commandMap, + @ModelAttribute("searchVO") KmcVO kmcVO) throws Exception { + + //크롬 SameSite정책 방지 - 도메인이 다른 타사로 이동 시 크롬 정책에 의해 세션 유실이 일어나는 경우가 있는데, 이를 방지하기 위해 samesite 보안을 none처리 + response.setHeader("Set-Cookie", "mberSession=mberSession; Secure; SameSite=None"); + + System.out.println("++++++++++++ 세션체크 ::: "+ session.getAttribute("mberSession")); + + String errMessage = ""; //에러메세지 + + String rec_cert = ""; // 결과값(암호화) + String certNum = ""; // certNum + + rec_cert = request.getParameter("rec_cert").trim(); + certNum = request.getParameter("certNum").trim(); + + kmcVO.setRecCert(rec_cert); + kmcVO.setCertNum(certNum); + // 파라미터 유효성 검증 + if( rec_cert.length() == 0 || certNum.length() == 0 ){ + errMessage = "비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + + + // 변수선언 -------------------------------------------------------------------------------------------------------- + String k_certNum = ""; // 파라미터로 수신한 요청번호 + k_certNum = certNum; + String date = ""; // 요청일시 + String CI = ""; // 연계정보(CI) + String DI = ""; // 중복가입확인정보(DI) + String phoneNo = ""; // 휴대폰번호 + String phoneCorp = ""; // 이동통신사 + String birthDay = ""; // 생년월일 + String gender = ""; // 성별 + String nation = ""; // 내국인 + String name = ""; // 성명 + String M_name = ""; // 미성년자 성명 + String M_birthDay = ""; // 미성년자 생년월일 + String M_Gender = ""; // 미성년자 성별 + String M_nation = ""; // 미성년자 내외국인 + String result = ""; // 결과값 + + String certMet = ""; // 인증방법 + String ip = ""; // ip주소 + String plusInfo = ""; + + String encPara = ""; + String encMsg1 = ""; + String encMsg2 = ""; + String msgChk = ""; + + com.icert.comm.secu.IcertSecuManager seed = new com.icert.comm.secu.IcertSecuManager(); + + //02. 1차 복호화 + //수신된 certNum를 이용하여 복호화 + rec_cert = seed.getDec(rec_cert, k_certNum); + + //03. 1차 파싱 + int inf1 = rec_cert.indexOf("/",0); + int inf2 = rec_cert.indexOf("/",inf1+1); + + encPara = rec_cert.substring(0,inf1); //암호화된 통합 파라미터 + encMsg1 = rec_cert.substring(inf1+1,inf2); //암호화된 통합 파라미터의 Hash값 + + //04. 위변조 검증 + encMsg2 = seed.getMsg(encPara); + kmcVO.setEncMsg2(encMsg2); + if(encMsg2.equals(encMsg1)){ + msgChk="Y"; + } + + if(!"Y".equals(msgChk)) { + errMessage = "비정상접근입니다."; + return returnPage(model , errMessage , kmcVO) ; + } + + //05. 2차 복호화 + rec_cert = seed.getDec(encPara, k_certNum); + kmcVO.setRecCert(rec_cert); + //06. 2차 파싱 + int info1 = rec_cert.indexOf("/",0); + int info2 = rec_cert.indexOf("/",info1+1); + int info3 = rec_cert.indexOf("/",info2+1); + int info4 = rec_cert.indexOf("/",info3+1); + int info5 = rec_cert.indexOf("/",info4+1); + int info6 = rec_cert.indexOf("/",info5+1); + int info7 = rec_cert.indexOf("/",info6+1); + int info8 = rec_cert.indexOf("/",info7+1); + int info9 = rec_cert.indexOf("/",info8+1); + int info10 = rec_cert.indexOf("/",info9+1); + int info11 = rec_cert.indexOf("/",info10+1); + int info12 = rec_cert.indexOf("/",info11+1); + int info13 = rec_cert.indexOf("/",info12+1); + int info14 = rec_cert.indexOf("/",info13+1); + int info15 = rec_cert.indexOf("/",info14+1); + int info16 = rec_cert.indexOf("/",info15+1); + int info17 = rec_cert.indexOf("/",info16+1); + int info18 = rec_cert.indexOf("/",info17+1); + + certNum = rec_cert.substring(0,info1); kmcVO.setCertNum(certNum); + date = rec_cert.substring(info1+1,info2); kmcVO.setDate(date); + CI = rec_cert.substring(info2+1,info3); kmcVO.setCI(CI); + phoneNo = rec_cert.substring(info3+1,info4); kmcVO.setPhoneNo(phoneNo); + phoneCorp = rec_cert.substring(info4+1,info5); kmcVO.setPhoneCorp(phoneCorp); + birthDay = rec_cert.substring(info5+1,info6); kmcVO.setBirthDay(birthDay); + gender = rec_cert.substring(info6+1,info7); kmcVO.setGender(gender); + nation = rec_cert.substring(info7+1,info8); kmcVO.setNation(nation); + name = rec_cert.substring(info8+1,info9); kmcVO.setName(name); + result = rec_cert.substring(info9+1,info10); kmcVO.setResult(result); + certMet = rec_cert.substring(info10+1,info11); kmcVO.setCertMet(certMet); + ip = rec_cert.substring(info11+1,info12); kmcVO.setIp(ip); + M_name = rec_cert.substring(info12+1,info13); kmcVO.setMName(M_name); + M_birthDay = rec_cert.substring(info13+1,info14); kmcVO.setMBirthDay(M_birthDay); + M_Gender = rec_cert.substring(info14+1,info15); kmcVO.setMGender(M_Gender); + M_nation = rec_cert.substring(info15+1,info16); kmcVO.setMNation(M_nation); + plusInfo = rec_cert.substring(info16+1,info17); kmcVO.setPlusInfo(plusInfo); + DI = rec_cert.substring(info17+1,info18); kmcVO.setDI(DI); + + //07. CI, DI 복호화 + CI = seed.getDec(CI, k_certNum); kmcVO.setCI(CI); + DI = seed.getDec(DI, k_certNum); kmcVO.setDI(DI); + + if("Y".equals(result)) { + + } + + //-------------------------------------------------------------- + String regex = ""; + if( certNum.length() == 0 || certNum.length() > 40){ + errMessage = "요청번호 비정상."; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[0-9]*"; + if( date.length() != 14 || !paramChk(regex, date) ){ + errMessage = "요청일시"; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[A-Z]*"; + if( certMet.length() != 1 || !paramChk(regex, certMet) ){ + errMessage = "본인인증방법 비정상" + certMet; + return returnPage(model , errMessage , kmcVO) ; + } + + + regex = "[0-9]*"; + if( (phoneNo.length() != 10 && phoneNo.length() != 11) || !paramChk(regex, phoneNo) ){ + errMessage = "휴대폰번호 비정상" ; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[A-Z]*"; + if( phoneCorp.length() != 3 || !paramChk(regex, phoneCorp) ){ + errMessage = "이동통신사 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[0-9]*"; + if( birthDay.length() != 8 || !paramChk(regex, birthDay) ){ + errMessage = "생년월일 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[0-9]*"; + if( gender.length() != 1 || !paramChk(regex, gender) ){ + errMessage = "성별 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[0-9]*"; + if( nation.length() != 1 || !paramChk(regex, nation) ){ + errMessage = "내/외국인 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[\\sA-Za-z가-�R.,-]*"; + if( name.length() > 60 || !paramChk(regex, name) ){ + errMessage = "성명 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[A-Z]*"; + if( result.length() != 1 || !paramChk(regex, result) ){ + errMessage = "결과값 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + + regex = "[\\sA-Za-z가-?.,-]*"; + if( M_name.length() != 0 ){ + if( M_name.length() > 60 || !paramChk(regex, M_name) ){ + errMessage = "미성년자 성명 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + } + + regex = "[0-9]*"; + if( M_birthDay.length() != 0 ){ + if( M_birthDay.length() != 8 || !paramChk(regex, M_birthDay) ){ + errMessage = "미성년자 생년월일 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + } + + regex = "[0-9]*"; + if( M_Gender.length() != 0 ){ + if( M_Gender.length() != 1 || !paramChk(regex, M_Gender) ){ + errMessage = "미성년자 성별 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + } + + regex = "[0-9]*"; + if( M_nation.length() != 0 ){ + if( M_nation.length() != 1 || !paramChk(regex, M_nation) ){ + errMessage = "미성년자 내/외국인 비정상"; + return returnPage(model , errMessage , kmcVO) ; + } + } + + //본인인증 결과 내용 저장하기. + /*System.out.println("+++++++++++++ getCertNum ::: "+kmcVO.getCertNum()); + System.out.println("+++++++++++++ getDate ::: "+kmcVO.getDate()); + System.out.println("+++++++++++++ getDI ::: "+kmcVO.getDI()); + System.out.println("+++++++++++++ getPhoneNo ::: "+kmcVO.getPhoneNo()); + System.out.println("+++++++++++++ getNation ::: "+kmcVO.getNation()); + System.out.println("+++++++++++++ getName ::: "+kmcVO.getName()); + System.out.println("+++++++++++++ getResult ::: "+kmcVO.getResult()); + System.out.println("+++++++++++++ getCertMet ::: "+kmcVO.getCertMet()); + System.out.println("+++++++++++++ getIp ::: "+kmcVO.getIp());*/ + + //KMC 본인인증 정보를 세션에 담아준다. + /*AuthCertVO certVO = new AuthCertVO(); + certVO.setCertNum(kmcVO.getCertNum()); + certVO.setCertDate(kmcVO.getDate()); + certVO.setCertDi(kmcVO.getDI()); + certVO.setCertPhone(kmcVO.getPhoneNo()); + certVO.setCertNation(kmcVO.getNation()); + certVO.setCertName(kmcVO.getName()); + certVO.setCertResult(kmcVO.getResult()); + certVO.setCertType("KMC문자인증"); + certVO.setCertIpaddr(kmcVO.getIp()); + certVO.setBirthDay(kmcVO.getBirthDay()); + certVO.setSexdstnCode(kmcVO.getGender());*/ + + /*request.getSession().setAttribute("AuthKmcCertVO", certVO);*/ + + /*System.out.println("++++++++++++ 세션체크22 ::: "+(MberManageVO) session.getAttribute("mberSession"));*/ + + //KMC 본인인증 로그 insert + AuthCertVO certVO = new AuthCertVO(); + certVO.setMberId(kmcVO.getPlusInfo()); + certVO.setCertNum(kmcVO.getCertNum()); + certVO.setCertDate(kmcVO.getDate()); + certVO.setCertDi(kmcVO.getDI()); + certVO.setCertPhone(kmcVO.getPhoneNo()); + certVO.setCertNation(kmcVO.getNation()); + certVO.setCertName(kmcVO.getName()); + certVO.setCertResult(kmcVO.getResult()); + certVO.setCertType("KMC_회원가입 인증"); + certVO.setCertIpaddr(kmcVO.getIp()); + certVO.setBirthDay(kmcVO.getBirthDay()); + certVO.setSexdstnCode(kmcVO.getGender()); + + //디비 테이블에 저장하기 + mberManageService.insertCertInfoLog(certVO); + + kmcVO.setIdx(certVO.getIdx()); //본인인증 로그 Idx - 로그 insert 후 idx selectKey + model.addAttribute("kmcVO", kmcVO); + return "web/cop/kmc/authRequestAjax"; + } + + + + + + + + } diff --git a/src/main/java/itn/let/uat/uia/web/KmcCertChecker.java b/src/main/java/itn/let/uat/uia/web/KmcCertChecker.java index 16c2aace..b2c56693 100644 --- a/src/main/java/itn/let/uat/uia/web/KmcCertChecker.java +++ b/src/main/java/itn/let/uat/uia/web/KmcCertChecker.java @@ -1,23 +1,34 @@ package itn.let.uat.uia.web; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; import java.text.SimpleDateFormat; import java.util.Calendar; -import java.util.Map; import java.util.Random; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; import org.springframework.stereotype.Component; import org.springframework.ui.ModelMap; +import org.springframework.web.servlet.FlashMap; +import org.springframework.web.servlet.FlashMapManager; +import org.springframework.web.servlet.support.RequestContextUtils; import com.icert.comm.secu.IcertSecuManager; import itn.let.cert.phone.service.CertPhoneService; import itn.let.cert.phone.service.MberCertPhoneVO; +import itn.let.mjo.pay.service.KmcVO; import itn.let.uat.uia.service.AuthCertVO; -import itn.let.uss.umt.service.MberManageVO; @Component("KmcCertChecker") public class KmcCertChecker { @@ -64,11 +75,13 @@ public class KmcCertChecker { String tr_add = "N"; // IFrame사용여부 //01. 한국모바일인증(주) 암호화 모듈 선언 - IcertSecuManager seed = new IcertSecuManager(); +// IcertSecuManager seed = new IcertSecuManager(); + com.icert.comm.secu.IcertSecuManager seed = new com.icert.comm.secu.IcertSecuManager(); //02. 1차 암호화 (tr_cert 데이터변수 조합 후 암호화) String enc_tr_cert = ""; - tr_cert = cpId +"/"+ urlCode +"/"+ certNum +"/"+ date +"/"+ certMet +"/"+ birthDay +"/"+ gender +"/"+ name +"/"+ phoneNo +"/"+ phoneCorp +"/"+ nation +"/"+ plusInfo +"/"+ extendVar; +// tr_cert = cpId +"/"+ urlCode +"/"+ certNum +"/"+ date +"/"+ certMet +"/"+ birthDay +"/"+ gender +"/"+ name +"/"+ phoneNo +"/"+ phoneCorp +"/"+ nation +"/"+ plusInfo +"/"+ extendVar; + tr_cert = cpId +"/"+ urlCode +"/"+ certNum +"/"+ date +"/"+ certMet +"///////"+ plusInfo +"/"+ extendVar; enc_tr_cert = seed.getEnc(tr_cert, ""); //03. 1차 암호화 데이터에 대한 위변조 검증값 생성 (HMAC) @@ -87,6 +100,292 @@ public class KmcCertChecker { return authCertVO; } + public KmcVO authCertResult( + HttpServletRequest request + , HttpServletResponse response + , ModelMap model + ) throws IOException { + + //크롬 SameSite정책 방지 - 도메인이 다른 타사로 이동 시 크롬 정책에 의해 세션 유실이 일어나는 경우가 있는데, 이를 방지하기 위해 samesite 보안을 none처리 + response.setHeader("Set-Cookie", "mberSession=mberSession; Secure; SameSite=None"); + + KmcVO kmcVO = new KmcVO(); //return VO + + // 변수 ------------------------------------------------------------------------------------------------------------- + String api_token = ""; // 토큰값(암호화) + String api_certNum = ""; // 요청번호(암호화) + + String message = ""; // JSON 전문 + String result_cd = ""; // JSON 결과코드 + String result_msg = ""; // JSON 결과-상세 + String strResult = ""; // JSON 결과 + String apiRecCert = ""; // JSON 전송 데이터 + String apiCertNum = ""; // JSON 전송 데이터 + + String rec_cert = ""; // 결과수신DATA + String k_certNum = ""; // 파라미터로 수신한 요청번호 + String certNum = ""; // 요청번호 + String date = ""; // 요청일시 + String CI = ""; // 연계정보(CI) + String DI = ""; // 중복가입확인정보(DI) + String phoneNo = ""; // 휴대폰번호 + String phoneCorp = ""; // 이동통신사 + String birth = ""; // 생년월일 + String gender = ""; // 성별 + String nation = ""; // 내국인 + String name = ""; // 성명 + String reserve1 = ""; // 예비필드 + String reserve2 = ""; // 예비필드 + String reserve3 = ""; // 예비필드 + String reserve4 = ""; // 예비필드 + String result = ""; // 결과값 + + String certMet = ""; // 인증방법 + String ip = ""; // ip주소 + String plusInfo = ""; + + String encPara = ""; + String encMsg1 = ""; + String encMsg2 = ""; + String msgChk = ""; + //----------------------------------------------------------------------------------------------------------------- + try{ + // Parameter 수신 -------------------------------------------------------------------- + api_token = request.getParameter("apiToken").trim(); + api_certNum = request.getParameter("certNum"); + + // 파라미터 유효성 검증 + if( api_token.length() == 0 ){ + goErrorPage("토큰값 비정상", request, response); + return kmcVO; + } + if( api_certNum.length() == 0 ){ + goErrorPage("요청번호 비정상", request, response); + return kmcVO; + } + + //현재시각 세팅(YYYYMMDDHI24MISS) + Calendar today = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + String api_date = sdf.format(today.getTime()); + + //01. 암호화 모듈 (jar) Loading + com.icert.comm.secu.IcertSecuManager seed = new com.icert.comm.secu.IcertSecuManager(); + + //api_token, api_certNum 복호화 + api_token = seed.getDec(api_token, ""); + api_certNum = seed.getDec(api_certNum, ""); + + // 파라미터 유효성 검증 + if( api_token.length() == 0 ){ + goErrorPage("토큰값 비정상(복호화 후)", request, response); + return kmcVO; + } + if( api_certNum.length() == 0 ){ + goErrorPage("요청번호 비정상(복호화 후)", request, response); + return kmcVO; + } + + // 1. URL 설정 + String serverURL = "https://www.kmcert.com/kmcis/api/kmcisToken_api.jsp"; + + // 2. 연결 생성 + URL url = new URL(serverURL); + + // 3. HttpURLConnection 객체 생성. + HttpURLConnection con = null; + OutputStream wr = null; + BufferedReader bufferedReader = null; + + // 4. URL 연결 (웹페이지 URL 연결.) + con = (HttpURLConnection)url.openConnection(); + + con.setConnectTimeout(20000); // TimeOut 시간 (서버 접속시 연결 시간 - 20초) + con.setReadTimeout(20000); // TimeOut 시간 (Read시 연결 시간 - 20초) + con.setDoOutput(true); // OutputStream으로 POST 데이터를 넘겨주겠다는 옵션. + + con.setRequestProperty("Content-Type", "application/json;charset=utf-8"); // 타입설정(application/json) 형식으로 전송 (Request Body 전달시 application/json로 서버에 전달.) + con.setRequestProperty("Accept", "application/json"); // 서버 Response Data를 JSON 형식의 타입으로 요청. + con.setRequestMethod("POST"); // 요청 방식 선택 (POST) + + // 5. JSON 전문 구성 + + JSONObject jsonData = new JSONObject(); + + jsonData.put("apiToken", api_token); + jsonData.put("apiDate", api_date); + + message = jsonData.toString(); + + // 6. 전송 + // Request Body에 Data를 담기위해 OutputStream 객체를 생성. + wr = con.getOutputStream(); + + // Request Body에 Data 셋팅.(한글깨짐 방지를 위해 utf-8인코딩 처리 + wr.write(message.getBytes("utf-8")); + wr.flush(); + wr.close(); + + // 실제 서버로 Request 요청 하는 부분. (응답 코드를 받는다. 200 성공, 나머지 에러) + int responseCode = con.getResponseCode(); + + // 4. 결과 수신 + if(responseCode == 200){ + bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); + }else{ + bufferedReader = new BufferedReader(new InputStreamReader(con.getErrorStream(), "UTF-8")); + } + + if(bufferedReader != null){ + + StringBuilder stringBuilder = new StringBuilder(); + String line = ""; + + while((line = bufferedReader.readLine()) != null){ + stringBuilder.append(line); + } + bufferedReader.close(); + + String stringRet = stringBuilder.toString(); + + // 5. 넘어온 문자열을 JSON 객체로 변환 + JSONParser jsonParser = new JSONParser(); + + //JSON데이터를 넣어 JSON Object 로 만들어 준다. + JSONObject jsonObj = (JSONObject)jsonParser.parse(stringRet); + + // 6. JSON 객체에서 데이터 가져오기 + + if(jsonObj.get("result_cd") != null){ + result_cd = jsonObj.get("result_cd").toString(); + if("APR01".equals(result_cd)){ + //통신성공 + strResult = "Y"; + rec_cert = jsonObj.get("apiRecCert").toString(); + k_certNum = jsonObj.get("apiCertNum").toString(); + }else if("APR02".equals(result_cd)){ + //실패 - Token Expire + strResult = "N"; + result_msg = "실패 - Token Expire"; + }else if("APR03".equals(result_cd)){ + //실패 - Token Not Found + strResult = "N"; + result_msg = "실패 - Token Not Found"; + }else if("APR04".equals(result_cd)){ + //실패 - API 요청일시 길이 오류 + strResult = "N"; + result_msg = "실패 - API 요청일시 길이 오류"; + }else if("APR05".equals(result_cd)){ + //실패 - API 토큰 길이 오류 + strResult = "N"; + result_msg = "실패 - API 토큰 길이 오류"; + }else if("APR06".equals(result_cd)){ + //실패 - 결과전송 재요청(3회 제한) + strResult = "N"; + result_msg = "실패 - 결과전송 재요청(3회 제한)"; + } + }else{ + //JSON 결과코드 에러 + strResult = "F"; + } + }else{ //timeout except 처리 + strResult = "F"; + } + + // 파라미터 유효성 검증 + if(!strResult.equals("Y")){ + goErrorPage("결과값 비정상, 결과코드["+result_cd+"], "+"상세내용["+result_msg+"]", request, response); + return kmcVO; + } + + //02. 1차 복호화 + rec_cert = seed.getDec(rec_cert, k_certNum); + + //03. 1차 파싱 + int inf1 = rec_cert.indexOf("/",0); + int inf2 = rec_cert.indexOf("/",inf1+1); + + encPara = rec_cert.substring(0,inf1); //암호화된 통합 파라미터 + encMsg1 = rec_cert.substring(inf1+1,inf2); //암호화된 통합 파라미터의 Hash값 + + //04. 위변조 검증 + encMsg2 = seed.getMsg(encPara); + + if(encMsg2.equals(encMsg1)){ + msgChk="Y"; + } + + if(msgChk.equals("N")){ + goErrorPage("비정상적인 접근입니다.!!", request, response); + return kmcVO; + } + + //05. 2차 복호화 + rec_cert = seed.getDec(encPara, ""); + + //06. 2차 파싱 + int info1 = rec_cert.indexOf("/",0); + int info2 = rec_cert.indexOf("/",info1+1); + int info3 = rec_cert.indexOf("/",info2+1); + int info4 = rec_cert.indexOf("/",info3+1); + int info5 = rec_cert.indexOf("/",info4+1); + int info6 = rec_cert.indexOf("/",info5+1); + int info7 = rec_cert.indexOf("/",info6+1); + int info8 = rec_cert.indexOf("/",info7+1); + int info9 = rec_cert.indexOf("/",info8+1); + int info10 = rec_cert.indexOf("/",info9+1); + int info11 = rec_cert.indexOf("/",info10+1); + int info12 = rec_cert.indexOf("/",info11+1); + int info13 = rec_cert.indexOf("/",info12+1); + int info14 = rec_cert.indexOf("/",info13+1); + int info15 = rec_cert.indexOf("/",info14+1); + int info16 = rec_cert.indexOf("/",info15+1); + int info17 = rec_cert.indexOf("/",info16+1); + int info18 = rec_cert.indexOf("/",info17+1); + + certNum = rec_cert.substring(0,info1); + date = rec_cert.substring(info1+1,info2); + CI = rec_cert.substring(info2+1,info3); + phoneNo = rec_cert.substring(info3+1,info4); + phoneCorp = rec_cert.substring(info4+1,info5); + birth = rec_cert.substring(info5+1,info6); + gender = rec_cert.substring(info6+1,info7); + nation = rec_cert.substring(info7+1,info8); + name = rec_cert.substring(info8+1,info9); + result = rec_cert.substring(info9+1,info10); + certMet = rec_cert.substring(info10+1,info11); + ip = rec_cert.substring(info11+1,info12); + reserve1 = rec_cert.substring(info12+1,info13); + reserve2 = rec_cert.substring(info13+1,info14); + reserve3 = rec_cert.substring(info14+1,info15); + reserve4 = rec_cert.substring(info15+1,info16); + plusInfo = rec_cert.substring(info16+1,info17); + DI = rec_cert.substring(info17+1,info18); + + //07. CI, DI 복호화 + CI = seed.getDec(CI, ""); + DI = seed.getDec(DI, ""); + + // ---------------------------------------------------------------------------------- + + }catch(StringIndexOutOfBoundsException ex){ + goErrorPage("StringIndexOutOfBoundsException", request, response); + }catch(NullPointerException ex){ + goErrorPage("NullPointerException", request, response); + }catch(NumberFormatException ex){ + goErrorPage("NumberFormatException", request, response); + }catch(IllegalStateException ex){ + goErrorPage("IllegalStateException", request, response); + }catch(IndexOutOfBoundsException ex){ + goErrorPage("IndexOutOfBoundsException", request, response); + } catch (IOException e) { + goErrorPage("IOException", request, response); + } catch (ParseException e) { + goErrorPage("ParseException", request, response); + } + return kmcVO; + } + private String getDomain(HttpServletRequest request) { @@ -144,5 +443,12 @@ public class KmcCertChecker { return mberCertPhoneVO; } + private void goErrorPage(String msg, HttpServletRequest request, HttpServletResponse response) throws IOException { + FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request); + flashMap.put("msg", msg); + FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request); + flashMapManager.saveOutputFlashMap(flashMap, request, response); + response.sendRedirect("/web/cert/log/kmcErrorPage.do"); + } } diff --git a/src/main/webapp/WEB-INF/jsp/web/cop/kmc/certResultError.jsp b/src/main/webapp/WEB-INF/jsp/web/cop/kmc/certResultError.jsp new file mode 100644 index 00000000..565fdcd6 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/web/cop/kmc/certResultError.jsp @@ -0,0 +1,22 @@ +<%@ page contentType="text/html; charset=utf-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/web/login/usrCheckTerms.jsp b/src/main/webapp/WEB-INF/jsp/web/login/usrCheckTerms.jsp index 0e17e4ed..87a80317 100644 --- a/src/main/webapp/WEB-INF/jsp/web/login/usrCheckTerms.jsp +++ b/src/main/webapp/WEB-INF/jsp/web/login/usrCheckTerms.jsp @@ -634,6 +634,7 @@ +