보안인증 본인인증 기능 추가

This commit is contained in:
wyh 2024-11-20 11:10:11 +09:00
parent 34efc8d6fb
commit 4755c88f39
4 changed files with 414 additions and 1 deletions

View File

@ -171,6 +171,7 @@ public class EgovMypageController {
@RequestMapping(value="/web/user/mberInfoIndex.do")
public String mberInfoIndex(
ModelMap model
, HttpServletRequest request
, RedirectAttributes redirectAttributes) throws Exception {
//로그인 권한정보 불러오기
@ -448,6 +449,27 @@ public class EgovMypageController {
}
{
/**
* 보안인증 본인인증 기능추가
* 20241120 원영현 과장 추가
* */
KmcCertChecker kmcCertCheck = new KmcCertChecker();
//kmc 본인인증 /개발 서버 구분
String serverNm = "";
if(request.getServerName().contains("219.240.88.15") || request.getServerName().contains("localhost")) {
serverNm = request.getScheme() + "://219.240.88.15:8095";
}else{
serverNm = request.getScheme() + "://www.munjaon.co.kr";
}
AuthCertVO certVO = kmcCertCheck.authCertCheckNine(serverNm + "/web/user/selectSecurityAuthn.do", loginVO.getId());
model.addAttribute("certVO", certVO);
}
return "web/user/mberInfoIndex";
}
@ -3494,4 +3516,254 @@ public class EgovMypageController {
}
return modelAndView;
}
/**
* 회원정보 조회 휴대폰 인증
*/
@RequestMapping("/web/user/selectSecurityAuthn.do")
public String selectSecurityAuthn(
HttpServletRequest request, ModelMap model
, @RequestParam Map<String, Object> commandMap
, @ModelAttribute("searchVO") KmcVO kmcVO ) throws Exception {
//개인회원일 mblDn 비교 본인 명의 휴대폰만 변경 가능하게끔
LoginVO loginVO = EgovUserDetailsHelper.isAuthenticated()? (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser():null;
String mblDn = userManageService.selectUserMblDnById(loginVO.getId());
model.addAttribute("loginVO", loginVO);
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가-<2D>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) ;
}
}
//KMC 본인인증 로그
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());
model.addAttribute("kmcVO", kmcVO);
return "web/user/securityAuthnPage";
}
}

View File

@ -586,4 +586,77 @@ public class KmcCertChecker {
return certVO;
}
// 마이페이지 보안인증
public AuthCertVO authCertCheckNine(String trUrl, String id) {
AuthCertVO certVO = new AuthCertVO();
//kmc step 01 데이터
//날짜 생성
Calendar today = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String day = sdf.format(today.getTime());
Random ran = new Random();
//랜덤 문자 길이
int numLength = 6;
String randomStr = "";
for (int i = 0; i < numLength; i++) {
//0 ~ 9 랜덤 숫자 생성
randomStr += ran.nextInt(10);
}
//reqNum은 최대 40byte 까지 사용 가능
String reqNum = day + randomStr; //요청번호
String tr_cert = "";
String cpId = "MJOM1001"; // 회원사ID
String urlCode = "001014"; // URL코드
//kmc 본인인증 /개발 서버 구분
if(trUrl.contains("119.193.215.98") || trUrl.contains("localhost")) {
urlCode = "005005";
}
String certNum = reqNum; // 요청번호 ( 본인인증 요청시 중복되지 않게 생성해야함. (-시퀀스번호) )
String date = day; // 요청일시
String certMet = "M"; // 본인인증방법 - M:휴대폰 본인인증, C:신용카드인증, P:공인인증서 인증
String name = ""; // 성명
String phoneNo = ""; // 휴대폰번호
String phoneCorp = ""; // 이동통신사
if(phoneCorp == null) phoneCorp = "";
String birthDay = ""; // 생년월일
String gender = ""; // 성별
if(gender == null) gender = "";
String nation = ""; // 내외국인 구분 - 0:내국인, 1:외국인
String plusInfo = id; // 추가DATA정보
String extendVar = "0000000000000000"; // 확장변수
//End-tr_cert 데이터 변수 선언 ---------------------------------------------------------------
String tr_url = trUrl;//"http://www.munjaon.co.kr/web/cop/kmc/authRequestAjax.do"; // 본인인증서비스 결과수신 POPUP URL
String tr_add = "N"; // IFrame사용여부
//01. 한국모바일인증() 암호화 모듈 선언
IcertSecuManager seed = new IcertSecuManager();
//02. 1차 암호화 (tr_cert 데이터변수 조합 암호화)
String enc_tr_cert = "";
tr_cert = cpId +"/"+ urlCode +"/"+ certNum +"/"+ date +"/"+ certMet +"/"+ birthDay +"/"+ gender +"/"+ name +"/"+ phoneNo +"/"+ phoneCorp +"/"+ nation +"/"+ plusInfo +"/"+ extendVar;
enc_tr_cert = seed.getEnc(tr_cert, "");
//03. 1차 암호화 데이터에 대한 위변조 검증값 생성 (HMAC)
String hmacMsg = "";
hmacMsg = seed.getMsg(enc_tr_cert);
//04. 2차 암호화 (1차 암호화 데이터, HMAC 데이터, extendVar 조합 암호화)
tr_cert = seed.getEnc(enc_tr_cert + "/" + hmacMsg + "/" + extendVar, "");
certVO.setTr_cert(tr_cert);
certVO.setTr_url(tr_url);
certVO.setTr_add(tr_add);
return certVO;
}
}

View File

@ -408,8 +408,47 @@ function getMberGrdChk() {
});
}
//휴대푠 번호 등록 [시작]--------------------------------------------------------------------------------------------
window.name = "kmcis_web_sample";
var KMCIS_window;
//휴대폰 인증팝업 열기
function openKMCISWindow(){
var UserAgent = navigator.userAgent;
/* 모바일 접근 체크*/
// 모바일일 경우 (변동사항 있을경우 추가 필요)
if (UserAgent.match(/iPhone|iPod|Android|Windows CE|BlackBerry|Symbian|Windows Phone|webOS|Opera Mini|Opera Mobi|POLARIS|IEMobile|lgtelecom|nokia|SonyEricsson/i) != null || UserAgent.match(/LG|SAMSUNG|Samsung/) != null) {
document.reqKMCISForm.target = 'KMCISWindow'; // 모바일
} else { // 모바일이 아닐 경우
KMCIS_window = window.open('', 'KMCISWindow', 'width=425, height=550, resizable=0, scrollbars=no, status=0, titlebar=0, toolbar=0, left=435, top=250' );
if(KMCIS_window == null){
alert(" ※ 윈도우 XP SP2 또는 인터넷 익스플로러 7 사용자일 경우에는 \n 화면 상단에 있는 팝업 차단 알림줄을 클릭하여 팝업을 허용해 주시기 바랍니다. \n\n※ MSN,야후,구글 팝업 차단 툴바가 설치된 경우 팝업허용을 해주시기 바랍니다.");
}
document.reqKMCISForm.target = 'KMCISWindow';
}
document.reqKMCISForm.action = 'https://www.kmcert.com/kmcis/web/kmcisReq.jsp';
document.reqKMCISForm.submit();
}
// /web/user/selectSecurityAuthn.do 리다이렉트 URL
//자식창에서 호출
function callTo() {
alert("호출입니다.");
}
//휴대푠 번호 등록 [끝]--------------------------------------------------------------------------------------------
</script>
<form name="reqKMCISForm" method="post" action="#">
<input type="hidden" id="tr_url" name="tr_url" value = "${certVO.tr_url}">
<input type="hidden" id="tr_add" name="tr_add" value = "${certVO.tr_add}">
<input type="hidden" id="tr_cert" name="tr_cert" value = "${certVO.tr_cert}">
</form>
<form id="levelForm" name="levelForm" method="post">
<input type="hidden" id="pageType" name="pageType" value=""/>
<input type="hidden" id="pageIndex" name="pageIndex" value=""/>
@ -657,7 +696,7 @@ function getMberGrdChk() {
<p class="lately_date">최근 변경일시 : <span>2024-11-01 12:49</span></p>
<div class="tab_depth1">
<a href="#none" class="on">ON</a>
<a href="#none" class="on" onclick="openKMCISWindow()">ON</a>
<a href="#none">OFF</a>
</div>
</div>

View File

@ -0,0 +1,29 @@
<%@ 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"%>
<%
//************************************************************************
// //
// 본 샘플소스는 개발 및 테스트를 위한 목적으로 만들어졌으며, //
// //
// 실제 서비스에 그대로 사용하는 것을 금합니다. //
// //
//************************************************************************
%>
<!-- [본인인증서비스 테스트 결과 수신 Sample] <br> <br> -->
<script src="<c:url value='/js/jquery.js' />"></script>
<html>
<head>
<meta name="robots" content="noindex">
<script language=javascript>
opener.callTo();
self.close();
</script>
</head>
<body>
</body>
</html>