Skip to content

본인확인-표준창 연동 개발 가이드

  • 버전 : 1.0.7
  • 날짜 : 2025-04-22

1. 본인확인-표준창 서비스

  • 본인확인-표준창 서비스 흐름도

본인확인-표준창 서비스 흐름도

2. 본인확인-표준창 개발 절차

2.1 표준창 연동 업무절차

  1. 이용기관 이동통신사 본인확인 가입절차를 위한 신청서를 제출합니다.

    • 이동통신사 본인확인 심사가 완료되어야 서비스 가능합니다.

    • 도메인 등록 정보, 가입정보등을 기입하여야 합니다.

    • 본인확인서비스를 위한 개발 및 운영 도메인 등록 신청 안내

      도메인등록 작성 예시

      Warning

      웹브라우져에서 서비스 요청시 등록된 도메인 정보가 아닐 경우 "등록되지 않은 사이트입니다." 오류가 발생

  2. 본인확인서비스 담당자가 이동통신사 본인확인 등록 심사결과를 전달합니다.

  3. 본인확인서비스 담당자가 운영서버에 본인확인-표준창 서비스 운영 등록을 진행합니다.

  4. 본인확인 개발용 서비스키 파일을 본인확인서비스 운영자에게 전달받아야 합니다.

    • 본인확인 개발용 서비스키 파일 : mok_keyInfo.dat

      Note

      본인확인 개발용 서비스키는 본인확인서비스 개발서버에서만 사용 가능합니다.

  5. 본인확인서비스 기능 테스트를 진행합니다.

    1. 가이드 내 샘플페이지 적용 테스트

      Info

      • 샘플페이지 테스트로 사전 기능확인을 하여야 본인확인서비스 담당자의 원활한 기술지원을 받으실 수 있습니다.
    2. 이용기관 웹페이지에 본인확인서비스 기능 적용

  6. 본인확인 운영용 서비스키 파일을 본인확인서비스 운영자에게 전달받아야 합니다.

    • 본인확인 운영용 서비스키 파일 : mok_keyInfo.dat
  7. 본인확인 운영용 서비스키를 이용기관 운영시스템에 적용합니다.

2.2 표준창 방화벽 설정

  • 본인확인-표준창 서비스는 방화벽 별도 오픈 없음.

  • 본인확인-표준창 서비스 이용시 이용기관의 Outbound 방화벽 제한시 아래 도메인 또는 IP에 대한 방화벽 오픈 필요

    • 운영) cert.mobile-ok.com (218.50.1.150)

    • 개발) scert.mobile-ok.com (218.50.1.156)

2.3 표준창 연동 준비

본인확인서비스 적용을 위해서는 본인확인서비스 담당자에게 본인확인-표준창 연동을 위한 신청 및 이동통신사 본인확인 등록을 완료 후 본인확인의 아래 정보를 획득하여야 합니다.

  • 서비스 등록 시 확인 정보

    • 본인확인에 등록된 표준창을 사용할 수 있는 도메인 리스트

      • 등록되지 않았을 경우 운영담당자에게 등록 요청
    • 본인확인 이용기관 암복호화키

      • 개발용 키와 운영용 키가 다르므로 각각 용도에 맞는 키 획득

    Warning

    • 신청시 등록한 도메인과 발급받은 본인확인 이용기관 암복호화키정보가 신청하신 등록정보와 동일하여야 서비스 사용이 가능
    • 등록 정보와 일치하지 않을 경우 "등록되지 않은 사이트입니다" 오류가 발생
  • 서비스 등록 후 다운로드 또는 전달 받은 본인확인 암복호화키 정보 (mok_keyInfo.dat)

    • 본인확인 암호화키 ID

    • 본인확인 이용기관 암복호화 비밀키

    본인확인 이용기관 암복호화키 유의사항

    • 본인확인-표준창 암복호화 키파일은 반드시 외부에 유출되지 않도록 보관 필요
    • 본인확인-표준창 암복호화 키파일은 반드시 웹에서 접근되지 않는 서버의 안전한 로컬경로에 별도 저장
    • 웹URL 경로에 본인확인-표준창 암복호화 키파일이 있을경우 보안키가 외부에 노출됨
  • 본인확인-표준창 HTTP 이용 정보

    • HTTPS 암호화 통신 : 사용자 브라우져 또는 이용기관 서버에서 본인확인 서비스 결과 요청시 TLS 1.2 이상 지원하여야 함

    • HTTP 메소드 : POST

    • Charset : utf-8

  • 본인확인-표준창 리턴타입

    • callback 리턴타입

      • 표준창 호출 함수 MOBILEOK.process(이용기관URL, 브라우져타입, 리턴콜백함수) 실행시 리턴콜백함수가 있을경우 callback 리턴 방식으로 처리됨
      • 팝업을 이용한 표준창 호출 기능 사용시 리턴타입
      • 웹브라우져에서 사용가능, 웹브라우져가 아닌 APP을 이용한 경우 APP 지원 여부에 따라 지원여부 확인 필요
      • 웹브라우져가 아닌 타사 APP등을 이용한 경우 "2.6 이용기관 APP 개발시 고려 사항" 의 내용을 확인 후 개발이 필요
      • WebView를 이용한 표준창 호출시 "2.6 이용기관 APP 개발시 고려 사항" 의 내용을 확인 후 개발이 필요
    • redirect 리턴타입

      • 표준창 호출 함수 MOBILEOK.process(이용기관URL, 브라우져타입, "") 실행시 리턴콜백함수가 ""일 경우 표준창 페이지로 URL이 이동되는 redirect 리턴 방식으로 처리됨
      • 팝업을 이용할 수 없는 브라우져 환경일 경우 retType 을 "redirect"로 설정 개발 권고
      • 상위 부모창의 정보를 상속받지 못하는 브라우져 환경일 경우 retType 을 "redirect"로 설정 개발 권고
      • WebView를 이용한 표준창 호출시 "2.6 이용기관 APP 개발시 고려 사항" 의 내용을 확인 후 개발이 필요
      • 페이스북, 인스타그램 등 웹브라우져가 아닌 APP을 이용한 WebView 환경 고려시 "redirect"로 개발
      • 팝업방식처럼 retType 을 "redirect"를 사용하기 위해서는 레이어팝업 내 iframe 방식의 "redirect"로 개발 필요

2.4 표준창 연동 라이브러리

  • 본인확인 개발언어 별 라이브러리

    bouncycastle 라이브러리 사용시 주의점

    한 프로젝트 내에서 bouncycastle 라이브러리를 여러버전 사용 및 여러종류의 암호라이브러리를 사용할 경우 일부 오류가 발생할 수 있습니다.

    • 키관리 라이브러리 phpseclib 1.0 지원 : mobileokManager-phpseclib1.0_1.0.2.zip (필수)
      • phpseclib_path_1.0.php : phpseclib 1.0 에서 사용하는 클래스 경로 설정
      • mobileOK_manager_phpseclib_v1.0_v1.0.2.php : 본인확인-표준창 연동 라이브러리
      • phpseclib_path_1.0.php의 경로를 mobileOK_manager_phpseclib_v1.0_v1.0.2.php에 직접 작성 (작성 필수)
        mobileOK_manager_phpseclib_v1.0_v1.0.2.php 파일 수정정보
        <?php
            $mok_path = './phpseclib_path_1.0.php';
        ?>
        
    • 키관리 라이브러리 phpseclib 3.0 이상 지원 : mobileokManager-phpseclib3.0_1.0.2.zip (필수)
      • phpseclib_path_3.0.php : phpseclib에서 사용하는 클래스 경로 (Composer의 autoload.php 파일 경로)
      • mobileOK_manager_phpseclib_v3.0_v1.0.2.php : 본인확인-표준창 연동 라이브러리
      • phpseclib_path_3.0.php의 경로를 mobileOK_manager_phpseclib_v3.0_v1.0.2.php에 직접 작성 (작성 필수)
        mobileOK_manager_phpseclib_v3.0_v1.0.2.php 파일 수정정보
        <?php
            $mok_path = './phpseclib_path_3.0.php';
        ?>
        
    • phpseclib 버전별 예제 유의사항
      • phpseclib-v1.0
        • PHP 5.5 미만 버전 이용시 예제 유의사항
          • 제공하는 예제 사용시 PHP 5.5 버전 이상 사용 필수
          • PHP 5.4.x 버전 이용시 curl 라이브러리를 사용할 수 없으므로 https 송수신 기능 구현 필요
          • PHP 5.3.x 버전 이용시 json_encode 함수를 사용할 수 없으므로 json encode 기능 구현 필요(PHP 5.4.x 유의사항 포함)
      • phpseclib-v3.0.0
        • 해당사항 없음
    • PHP 5.6 버전 이용시 예제 유의사항
      • https 전송예제에서 php.ini 추가설정 필요 DEPRECATED경고문과 WARNING경고문을 출력하여 데이터와 같이 송신되는 이슈 발생
        $HTTP_RAW_POST_DATA를 사용하지 않는 경우
        #php.ini
        always_populate_raw_post_data = -1
        
        $HTTP_RAW_POST_DATA를 사용하는 경우
        #php.ini
        error_reporting = E_ALL & ~E_DEPRECATED & ~E_WARNING
        
    • PHP 7.0 (64bit) / PHP 7.1 (64bit) 이용시 Composer설치 및 C라이브러리 사용시 이슈 발생
    • openssl암호화 모듈을 사용히는 코드 php.ini 추가설정 필요
      #php.ini
      # Windows
      extension = php_openssl.dll
      # Unix, Linux
      extension = php_openssl.so
      
    • PHP 암호화 보안라이브러리 phpseclib 설치(필수)
    • PHP 데이터 전송 라이브러리 php.ini 설정
      extension_dir = "ext"
      # Windows 
      extension = php_curl.dll
      # Unix, Linux 
      extension = php_curl.so
      default_charset = UTF-8
      
    • Node.js의 기본 모듈인 CommonJS기반으로 구현
    • 키관리 라이브러리 : mobileokManager-Nodejs_1.0.3.zip (필수)
    • Node.js 모듈 이용시 유의사항 (필수)
      • npm install list
        • 'cors'
        • 'express'
        • 'express-session'
        • 'body-parser'
        • 'ejs'
        • 'fs'
        • 'crypto'
        • 'axios'
        • ‘urlencode’
      • Node.js 예제 유의사항
        • https 전송예제에서 사용하는 ‘axios’ 라이브러리는 비동기 방식으로 지원하며 동기방식으로 지원하는 최소 버전은 Node.js 14.0.0 이상 권장
        • EJS 템플릿 엔진 모듈를 사용하는 경우 ejs파일의 경로가 root/views/파일명.ejs로 설정되어 있거나 views폴더 안에 ejs파일이 위치하거나, 경로를 직접 설정하여 사용
        • 13.7.0 버전에서 axios를 사용할 경우 아래 오류가 발생하므로 14.0.0 이상 권장
          (node:18720) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
          
    • Node.js의 기본 모듈인 CommonJS기반으로 구현
    • Node.js 키관리 라이브러리가 동일한 폴더에 있는 것을 권장합니다.
    • 키관리 라이브러리 : mobileokManager-Nodejs_1.0.3.zip (필수)
    • Node.js 모듈 이용시 유의사항 (필수)
      • npm install list
        • 'cors'
        • 'express'
        • 'express-session'
        • 'body-parser'
        • 'fs'
        • 'crypto'
        • 'axios'
        • 'urlencode'
      • npm install list(react)
        • 'react-router-dom'
        • 'react-helmet' (아래 react-helmet 라이브러리 사용시 설치)
      • Node.js 예제 유의사항
        • https 전송예제에서 사용하는 ‘axios’ 라이브러리는 비동기 방식으로 지원하며 동기방식으로 지원하는 최소 버전은 Node.js 14.0.0 이상 권장
        • Node.js 13.7.0 버전에서 axios를 사용할 경우 아래 오류가 발생하므로 Node.js 14.0.0 버전 이상 권장
          (node:18720) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
          
    • 예제 mok_react_index.js 가이드
      • 표준인증창을 띄우기 위해 사용하는 자바스크립트 불러오는 방법
      • 아래의 두 설정을 모두 사용하는 경우 결과를 2번 요청을 보내게 되어 오류가 발생합니다. 설정을 하나만 해주세요
        • index.html 설정
          • npx create-react-app으로 프로젝트 생성 시 public폴더 내에 index.html을 로드하게 되는데, index.html에 아래와 같은 설정
            <!-- 개발 -->
            <script src="https://scert.mobile-ok.com/resources/js/index.js"></script>
            <!-- 운영 -->
            <!-- <script src="https://cert.mobile-ok.com/resources/js/index.js"></script> -->
            
        • react-helmet 라이브러리 사용
          • 이용 시 설치 목록 npm install react-helmet
          • mok_react_index.js에서 주석으로 된 부분 해제 시 사용 가능
            import {Helmet} from 'react-helmet';
            <Helmet>
                {/*개발*/}
                <script src="https://scert.mobile-ok.com/resources/js/index.js"></script>
                {/*운영*/}
                {/*<script src="https://cert.mobile-ok.com/resources/js/index.js"></script>*/}
            </Helmet>
            
          • react-helmet 라이브러리 사용 시 아래와 같은 안내가 나오지만 사용은 가능
            react-dom.development.js:86 Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See <https://reactjs.org/link/unsafe-component-lifecycles> for details.
            React에서 검증하지 않은 라이브러리라는 안내문으로 잘 못 사용하게 되면 서비스에 문제가 될 수 있습니다.
            
    • Node.js의 기본 모듈인 CommonJS기반으로 구현
    • Node.js 키관리 라이브러리가 동일한 폴더에 있는 것을 권장합니다.
    • 키관리 라이브러리 : mobileokManager-Nodejs_1.0.3.zip (필수)
    • Node.js 모듈 이용시 유의사항 (필수)
      • npm install list
        • 'cors'
        • 'express'
        • 'express-session'
        • 'body-parser'
        • 'fs'
        • 'crypto'
        • 'axios'
        • ‘urlencode’
      • npm install list(vue)
        • 'vue-router'
      • Node.js 예제 유의사항
        • https 전송예제에서 사용하는 ‘axios’ 라이브러리는 비동기 방식으로 지원하며 동기방식으로 지원하는 최소 버전은 Node.js 14.0.0 이상 권장
        • 13.7.0 버전에서 axios를 사용할 경우 아래 오류가 발생하므로 14.0.0 이상 권장
          (node:18720) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
          
    • Vue 모듈 이용시 유의사항
      • 프로젝트 생성시에 Node.js 14.0.0 부터 사용 가능합니다.
      • • Node.js 13.x.x에서 @vue/cli 호환성 문제로 인한 에러
        You are using Node v13.7.0, but this version of @vue/cli requires Node ^12.0.0 || >= 14.0.0.Please upgrade your Node version.
        
    • Vue 예제 가이드
      • 예제 mok_vue_index.vue 가이드 표준인증창을 띄우기 위해 사용하는 자바스크립트 불러오는 방법
        • 아래의 두 설정을 모두 사용하는 경우 결과를 2번 요청을 보내게 되어 오류가 발생합니다. 설정을 하나만 해주세요
          • Index.html 설정 Vue create으로 프로젝트 생성시 public폴더 내에 index.html을 로드. index.html에 아래와 같은 설정
            <!-- 개발 -->
            <script src="https://scert.mobile-ok.com/resources/js/index.js">
            </script>
            <!-- 운영 -->
            <!-- <script src="https://cert.mobile-ok.com/resources/js/index.js"> -->
            <!-- </script>  -->
            
          • Mounted 메서드 사용 mok_vue_index.vue에서 주석으로 된 부분 해제 시 사용 가능
            mounted() {
                let scriptTag = document.createElement('script');
                //개발서버
                scriptTag.setAttribute('src', 'https://scert.mobile-ok.com/resources/js/index.js');
                //운영서버
                // scriptTag.setAttribute('src', 'https://cert.mobile-ok.com/resources/js/index.js')
            
                document.head.appendChild(scriptTag);
            },
            
      • 본인확인-표준창 Vue 도메인 설정
        • Vue create로 프로젝트 생성시 package.json파일에 있는 설정 변경
          "scripts": {
              "serve": "vue-cli-service serve --open --host // 이용기관 도메인 --port //포트번호",
              "build": "vue-cli-service build",
              "lint": "vue-cli-service lint"
          }
          
    • .NET framework v4.5 이상 지원 : TLS 1.2 지원
    • ASP.NET 암호라이브러리 (필수)

    • ASP.NET 암호화 확장 라이브러리 : RSA-OAEP, AES256 암호알고리즘 사용 (필수)

      Bouncycastle 암호라이브러리 .NET 설치 방법

      • Bouncycastle dll 다운로드 설치
            1. Bouncycastle dll 다운로드 파일 압축 해제
            2. "3.2 표준창 예제 구조"와 같이 .NET 구조의 bin 디렉토리에 파일 복사
        
    • ASP.NET JSON 이용 라이브러리
      • Newtonsoft.Json 라이브러리 다운로드 Newtonsoft.Json
        • 13.0.3기준 상위 버전

    bouncycastle 라이브러리 사용시 주의점

    한 프로젝트 내에서 bouncycastle 라이브러리를 여러버전 사용 및 여러종류의 암호라이브러리를 사용할 경우 일부 오류가 발생할 수 있습니다.

    • .NET Core v2.0 이상 지원

    • .NET Core 암호라이브러리 (필수)

      csproj 라이브러리 참조 방법

      • 프로젝트명.csproj 내 라이브러리 참조
            <ItemGroup>
                <Reference Include="mobileOKManager.netcore">
                    <HintPath>"mobileOKManager.netcore.dll파일 서버 절대경로"\mobileOKManager.netcore.dll</HintPath>
                </Reference>
            </ItemGroup>
        
    • .NET Core 암호화 확장 라이브러리 : RSA-OAEP, AES256 암호알고리즘 사용 (필수)

      • Bouncycastle 암호라이브러리 2.0.0 이상 다운로드 Bouncycastle

      Bouncycastle 암호라이브러리 .NET 설치 방법

      • Bouncycastle NutGet 설치버전 설치 ```
            NuGet\Install-Package BouncyCastle.Cryptography -Version 2.2.1
        ```
        
    • ASP.NET JSON 이용 라이브러리

      • Newtonsoft.Json 라이브러리 다운로드 Newtonsoft.Json
        • 13.0.3기준 상위 버전

    bouncycastle 라이브러리 사용시 주의점

    한 프로젝트 내에서 bouncycastle 라이브러리를 여러버전 사용 및 여러 종류의 암호라이브러리를 사용할 경우 일부 오류가 발생할 수 있습니다.

2.5 표준창 개발시 고려사항

  • 본인확인-표준창 TLS 1.2 통신오류 고려 사항

    TLS 통신 오류 "Unable to find certificate chain." 또는 "unable to find valid certification path to requested target" 발생시 처리 방법

    • 오류 내용

      • "TLS 통신을 위한 인증기관 인증서 유효성을 확인할수 없다." 라는 의미 입니다. (Java 버전에 따라 표시되는 메시지를 달라질수 있음)
      • 즉, 클라이언트의 루트인증서저장소(cacerts)에 서버로부터 전달받은 인증서를 검증할 루트인증서가 없다면 신뢰성 검증을 할 수 없어서 오류가 발생합니다.
    • 해결 방안

      • 클라이언트의 루트인증서저장소(cacerts)에 서버의 인증서를 발급한 인증기관의 루트인증서를 등록해야 합니다. 해당 루트인증서를 다운받거나 전달받은 후 아래의 명령어로 등록할 수 있습니다.
        - 명령어 : $ keytool -importcert -alias 등록할 별칭 -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file 루트인증서
          (예시) : keytool -importcert -alias DigiCertGlobalRootG2 -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file DigiCertGlobalRootG2.crt.pem
                  > cacerts에 설정된 비밀번호 : changeit
        
    • Root 인증서 다운로드 : DigiCert Global Root G2 Download PEM

    Safari

    • 오류내용
      • 전제조건 인증결과 수신함수에서 alert 함수를 사용하는 경우
      • 현상 Safari 17 이상 버전에서 SMS 인증 시 검증번호 자동채우기(autoFill)를 사용한 직후, 검증을 성공하면 부모창의 alert 창이 스크립트의 진행을 막아 진행이 되지 않는 현상 발생
    • 해결방안
      • 부모창에서 인증결과 수신함수 구현 시 alert 함수를 사용하지 않도록 요청

2.6 이용기관 APP 개발시 고려 사항

  • 본인확인-표준창 WebView 개발 고려사항

    • 팝업을 이용할 수 없는 브라우져 환경일 경우 "redirect" 방식으로 개발 권고

          //x-javascript 함수 redirect 방식 사용 
          MOBILEOK.process("https://이용기관URL/mok/mok_std_request.jsp", "MB", "");
      

    • 이용기관 APP에서 팝업을 이용할 수 없거나 부모창의 설정환경을 상속받지 못하는 웹 환경일 경우 또는 "redirect" 방식으로 개발 권고

    • 이용기관 APP에서 WebView 에서 팝업방식을 이용할때는 팝업창 허용 개발 및 웹브라우져와 동일하게 HTTP 헤더에 'Referer' 도메인 정보등이 포함되도록 개발

      • 이용기관 APP 개발 방법 및 구현 환경에 따라 지원하지 않을 수 있으므로 구현 시 기능 확이 필요
    • WebView 본인확인-표준창 결과 획득 후 이용기관 APP으로 전달받는 부분 개발

    • WebView 본인확인-표준창을 이용할 경우 PASS앱 실행시 PUSH 방식으로 통신사 APP을 구동

  • 본인확인-표준창 WebView 호출시 고려사항

    이용기관 APP에서 본인확인-표준창 필수 정보 설정 안내

    • 본인확인서비스는 본인확인 사용자가 올바른 도메인에서 요청이 되었는지 확인
    • 본인확인을 요청한 요청페이지는 이용기관이 등록한 도메인에서 웹페이지에서 호출
    • 본인확인 요청시 WevView에서 로딩한 웹페이지 HTTP 헤더에 'Referer' 정보가 이용기관에서 신청/등록한 도메인으로 필수 포함 필요

    안드로이드에서 A2A 서비스 이용 설정 안내

    • PASS A2A 서비스를 사용하려고 하는 경우 User-Agent 값에 "_DS_MOBILE_OK_INTENT"를 추가 하여 사용

          @Override
          public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
              WebView webView = new WebView(view.getContext());
              WebSettings webSettings = webView.getSettings();
              webSettings.setJavaScriptEnabled(true);
              webSettings.setUserAgentString(webView.getSettings().getUserAgentString() + "_DS_MOBILE_OK_INTENT");
          }
      

    안드로이드에서 WebView 이용시 referer가 없어지는 현상 발생 시

    • 안드로이드에서 팝업기능 사용 시 "view.loadUrl(url)" 명령어로 팝업을 생성하게 되면 referer 헤더가 없는 이슈 발생할 수 있음
    • "view.loadUrl(url)"를 이용한 팝업을 반드시 이용해야하는 경우 팝업 대신 Layer Pop-up (레이어 팝업)내에 iframe 을 생성하여 우회 이용
      • 웹뷰 -> 이용기관 레이어 팝업 및 iframe 생성 -> iframe 브릿지 페이지(이용기관 URL 이동) -> iframe 내 본인확인 redirect 페이지 호출 -> iframe 본인확인 완료 -> iframe 브릿지 페이지(이용기관 URL 이동)-> 이용기관 부모창에서 레이어 팝업 닫기

    안드로이드 WebView 이용시 PASS앱이 없는 사용자의 PASS 설치페이지 이동 개발 고려사항

    • 안드로이드에서 PASS앱이 없는 사용자의 PASS 사용시 설치페이지로 이동을 위해서는 아래 예시 코드 추가 고려 필요

          private class CustomWebChromeClient extends WebChromeClient {
              ...
      
              @Override
              public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
                  WebView webView = new WebView(view.getContext());
                  WebSettings webSettings = webView.getSettings();
                  webSettings.setx-javascriptEnabled(true);
      
                  webView.setWebViewClient(new WebViewClient() {
                      @Override
                      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                          String url = String.valueOf(request.getUrl());
                          if (url.startsWith("intent:")) {
                              try {
                                  Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
                                  Intent existPackage = getPackageManager().getLaunchIntentForPackage(intent.getPackage());
                                  if (existPackage != null) {
                                      startActivity(intent);
                                  }
                                  else {
                                      Intent marketIntent = new Intent(Intent.ACTION_VIEW);
                                      marketIntent.setData(Uri.parse("market://details?id=" + intent.getPackage()));
                                      startActivity(marketIntent);
                                  }
                                  return true;
                              } catch (Exception e) {
                                  e.printStackTrace();
                              }
                          }
      
                          return super.shouldOverrideUrlLoading(view,request);
                      }
                  });
                  ...
              }
              ...
          }
      

3. 본인확인-표준창 개발 준비

3.1 표준창 연동 순서

본인확인-표준창은 아래와 같은 순서로 연동 적용합니다.

  • 본인확인-표준창 연동 순서

    1. 이용기관 웹페이지에 본인확인-표준창 연동 자바스크립트(Javascript) 개발

    2. 이용기관 본인확인-표준창 요청 API 연동 개발

      • 거래토큰 유효시간은 총 10분으로 인증 요청 후 7분내에 인증처리 되어야 하며 인증번호 2번 재시도가 가능

        • 10분이 넘어가면 새로운 거래토큰을 생성하여 처음부터 처리
    3. 이용기관 본인확인-표준창 결과 API 연동 기능 개발

      1. MOKToken 방식 : 휴대폰본인확인서버 개인정보 요청용 토큰 수신 모드, 개인정보는 이용기관이 휴대폰본인확인서버에 요청하여 수신
    4. 이용기관 본인확인-표준창 결과 처리

  • 본인확인-표준창 결과 토큰 처리 방식

    • MOKToken 방식 : 본인확인-표준창 응답결과를 브라우져를 통해 MOKToken 으로 수신 후 개인정보는 이용기관 서버에서 휴대폰본인확인서버로 직접 연동하여 암호화된 개인정보/CI/DI(MOKResult)를 수신받는 방식

      • 개인정보를 이용기관서버 와 휴대폰본인확인서버간 접속으로 수신하기 때문에 개인정보 외부 유출에 안전한 방식

3.2 표준창 예제 구조

  • 본인확인-표준창 개발예제 구조

    • .
      ├─ WEB-INF
      │   └─ lib/
      │       └─ mobileOKManager-jdk1.8_1.0.1.jar
      └─ mok/
          ├─ mok.html
          ├─ mok_std_request.jsp
          └─ mok_std_result.jsp
      
      .
      ├─ WEB-INF/
      │   └─ lib/
      │       ├─ bcpkix -jdk15to18-xxx.jar
      │       ├─ bcprov -jdk15to18-xxx.jar
      │       ├─ bctls -jdk15to18-xxx.jar
      │       ├─ bcutil -jdk15to18-xxx.jar
      │       └─ mobileOKManager-jdk1.6_1.0.1.jar
      └─ mok/
          ├─ mok.html
          ├─ mok_std_request.jsp
          └─ mok_std_result.jsp
      
      .
      └─ mok/
          ├─ mobileOK_manager_phpseclib_v3.0_v1.0.2.php
          ├─ composer.json
          ├─ composer.lock
          ├─ phpseclib_path_3.0.php
          ├─ mok.html
          ├─ mok_std_request.php
          ├─ mok_std_result.php
          └─ vendor/
              └─ composer/
                  ├─ paragonie
                  ├─ phpseclib
                  └─ autoload.php
      
      .
      └─ mok/
          ├─ mobileOK_manager_phpseclib_v1.0_v1.0.2.php
          ├─ phpseclib_path_1.0.php
          ├─ mok.html
          ├─ mok_std_request.php
          ├─ mok_std_result.php
          └─ phpseclib-1.0.20/
              └─ phpseclib/
                  ├─ Crypt
                  ├─ File
                  ├─ Math
                  ├─ Net
                  ├─ System
                  ├─ bootstrap.php
                  └─ openssl.cnf
      
      .
      ├─ bin/
      │   ├─ BouncyCastle.Crypto.dll
      │   ├─ Newtonsoft.Json.dll
      │   └─ mobileOKManager.net.dll
      ├─ mok/
      │   ├─ mok_std_request.aspx.cs
      │   ├─ mok_std_result.aspx.cs
      │   ├─ mok_std_request.aspx
      │   ├─ mok_std_result.aspx
      │   └─ mok.html
      └─ Web.config
      
      .
      ├─ Controllers/
      │   ├─ RequestController.cs
      │   └─ ResultController.cs
      ├─ Views/
      │   ├─ Request/
      │   │   └─ mok_std_request.cshtml
      │   └─ Result/
      │       └─ mok_std_result.cshtml
      └─ wwwroot/
          └─ mok/
              └─ mok.html
      
    • .
      └─ mok/
          ├─ mok_Key_Manager_v1.0.3.js
          ├─ mok_server_std.js
          ├─ views
          │    └─ mok_std_redirect.ejs
          ├─ mok.html
          ├─ package.json
          ├─ package-lock.json
          └─ node_modules
      

      React Client Project
      1
      2
      3
      4
      5
      6
      7
      8
      .
      ├─ node_modules/
      ├─ public
      │    └─ index.html
      └─ src
          ├─ mok_react_index.js
          ├─ mok_react_redirect.js
          └─ App.js
      
      React Server Project
      1
      2
      3
      4
      .
      ├─ node_modules/
      ├─ mok_Key_Manager_v1.0.3.js
      └─ mok_react_server.js
      

      Vue Client Project
      .
      ├─ node_modules/
      ├─ public
      │    └─ index.html
      └─ src
          ├─ App.vue
          ├─ router
              └─ MOK_Router.js
          └─ components
              ├─ mok_vue_redirect.vue
              └─ mok_vue_index.vue
      
      Vue Server Project
      1
      2
      3
      4
      5
      6
      .
      ├─ node_modules/
      ├─ package.json
      ├─ package-lock.json
      ├─ mok_Key_Manager_v1.0.3.js
      └─ mok_server_std.js
      

4. 본인확인-표준창 웹페이지 연동

이용기관은 본인확인을 연동하는 페이지에 본인확인-표준창 웹 연동 자바스크립트를 추가합니다.

  • 본인확인-표준창 JavaScript URL

    • 운영 URL : https://cert.mobile-ok.com/resources/js/index.js

    • 개발 URL : https://scert.mobile-ok.com/resources/js/index.js

  • 본인확인-표준창 호출 API

    • MOBILEOK.process() 함수 설명

      ID 내용
      mok_request_url 이용기관 본인확인 요청(토큰생성, 인증요청) URL
      deviceBrowser 브라우져 종류 설정(옵션)
      - "WB" : PC웹
      - "MB":모바일웹
      - "MWV":모바일웹 View
      - "HY": 모바일 Hybrid App
      - "NA": 모바일 Native App
      callback_func callback 실행에 대한 호출 함수명
      - callback 함수 사용시 : callback 함수명
      - callback 함수 미 사용시 : "" 입력
  • 본인확인-표준창 웹페이지 연동 예제

    mok.html
    <!DOCTYPE html>
    <html lang="ko">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <meta name="format-detection" content="telephone=no">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
    <!--  개발 URL :  -->
    <script src="https://scert.mobile-ok.com/resources/js/index.js"></script>
    <!--  운영 URL : <script src="https://cert.mobile-ok.com/resources/js/index.js"></script> -->
    <script>
        //모바일/PC 스크립트 인식 구분
        document.addEventListener("DOMContentLoaded", function () {
        document.querySelector("#mok_popup").addEventListener("click", function () {
            MOBILEOK.process("https://이용기관URL/mok/mok_std_request.jsp", "WB", "result");
        })
        // document.querySelector("#mok_move").addEventListener("click", function () {
            // 모바일 전용서비스로 페이지 이동처리 또는 카카오 브라우져 등 새창으로 처리가 어려운, 환경 또는 브라우져에서 처리
            //MOBILEOK.process("https://이용기관URL/mok/mok_std_request.jsp", "WB", "");
        // })
        })
    
        function result(result) {
        try {
            result = JSON.parse(result);
            document.querySelector("#result").value = JSON.stringify(result, null, 4);
        } catch (error) {
            document.querySelector("#result").value = result;
        }
        }
    </script>
    <style>
        .container {
        width: 500px;
        border: 1px black solid;
        display: flex;
        flex-direction: column;
        padding: 5px;
        }
    
        .content {
        border: 1px black solid;
        display: flex;
        flex-direction: column;
        padding: 5px;
        }
    
        .item {
        border: 1px black solid;
        display: flex;
        flex-direction: column;
        padding: 5px;
        }
    
        label {
        margin-bottom: 5px;
        font-weight: 800;
        }
    
        input {
        box-sizing: border-box;
        }
    
        button {
        font-size: 20px;
        font-weight: 800;
        padding: 3px;
        box-sizing: border-box;
        }
    </style>
    <title>휴대폰본인확인_표준창</title>
    </head>
    <body>
    <div class="container">
    <div class="content">
        <div class="item">
        <textarea id="result" rows="20"></textarea>
        </div>
    </div>
    <div class="content">
        <button id="mok_popup">본인확인 시작(팝업)</button>
    </div>
    <!--    <div class="content">-->
    <!--        <button id="mok_move">본인확인 시작(이동)</button>-->
    <!--    </div>-->
    </div>
    </body>
    </html>
    
    App.js
    import MokStdRequest from './mok_react_index'
    import MokStdRedirect from './mok_react_redirect';
    
    import {
    Routes, BrowserRouter as Router,
    Route
    } from 'react-router-dom';
    
    function App() {
    return (
    <Router>
        <Routes>
            <Route exact path="/" element={<MokStdRequest/>}/>
            <Route exact path="/redirect" element={<MokStdRedirect/>}/>
        </Routes>
    </Router>
    );
    }
    
    export default App;
    
    mok_react_index.js
    import React, { Component } from 'react';
    
    /* index.html에 설정을 안 할 시 react-helmet 다운 및 주석해제 */
    // import {Helmet} from 'react-helmet';
    class moK_react_index extends Component {
        componentDidMount() {
            // 인증결과 콜백함수 정의
            const script = document.createElement('script');
            const callBackFunc = document.createTextNode(
                "function result(result) {" +
                    "try {" +
                        "result = JSON.parse(result);" +
                        "document.querySelector('#result').value = JSON.stringify(result, null, 4);" +
                    "} catch (error) {" +
                        "document.querySelector('#result').value = result;" +
                    "}" +
                "}");
    
            script.appendChild(callBackFunc);
            document.body.appendChild(script);
        }
    
        /* PC | 모바일 스크립트 인식 구분 */
        /* PC 스크립트 사용시 */
        mok_popup() {
            window.MOBILEOK.process("https://이용기관 본인인증-표준창 요청 (서버 (Node.js))URL/mok/mok_std_request", "WB", "result");
        }
        /* 모바일 스크립트 사용시 */
        // mok_move 사용시 mok_react_server(pathname 수정 후 사용)
        // mok_move() {
            // 모바일 전용서비스로 페이지 이동처리 또는 카카오 브라우져 등 새창으로 처리가 어려운, 환경 또는 브라우져에서 처리
            // window.MOBILEOK.process("https://이용기관 본인인증-표준창 요청 (서버 (Node.js))URL/mok/mok_std_request", "WB", "");
        // }
    
        render() {
            return (
                <main>
                    {/* index.html에 설정을 안 할 시 주석해제 */}
                    {/* <Helmet> */}
                        {/* 운영 */}
                        {/* <script src="https://cert.mobile-ok.com/resources/js/index.js"></script> */}
                        {/* 개발 */}
                        {/* <script src="https://scert.mobile-ok.com/resources/js/index.js"></script> */}
                    {/* </Helmet>  */}
                    <div>
                        <div>
                            <div>
                            <textarea id="result" rows="20"></textarea>
                            </div>
                        </div>
                        <div>
                            <button onClick={this.mok_popup}>본인확인 시작(팝업)</button>
                        </div>
                        {/* <div> */}
                            {/* <button onClick={this.mok_move}>본인확인 시작(이동)</button> */}
                        {/* </div> */}
                    </div>
                </main>
            )
        }
    
    }
    
    export default moK_react_index;
    
    mok_react_redirect.js
    import React, { Component } from 'react';
    
    class mok_redirect extends Component {
        componentDidMount() {
            // 인증결과 확인
            const script = document.createElement('script');
            const resultData = document.createTextNode(
                "redirectData = new URLSearchParams(location.search).get('data');" +
                "try {" +
                    "redirectData = JSON.parse(redirectData);" +
                    "document.querySelector('#result').value = JSON.stringify(redirectData, null, 4);" +
                "} catch (error) {" +
                    "document.querySelector('#result').value = redirectData;" +
                "}");
    
            script.appendChild(resultData);
            document.body.appendChild(script);
        }
    
        render() {
            return (
                <main>
                    <div>
                        <div>
                            <textarea id="result" rows="20"></textarea>
                        </div>
                    </div>
                </main>
            )
        }
    
    }
    
    export default mok_redirect;
    
    App.vue
    1
    2
    3
    <template>
    <router-view/>
    </template>
    
    main.js
    1
    2
    3
    4
    5
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router/MOK_Router.js'
    
    createApp(App).use(router).mount('#app')
    
    MOK_Router.js
    import { createRouter, createWebHistory } from 'vue-router'
    
    const routes = [
    {
        path: '/',
        name: 'mok_std_request',
        component: () => import(/* webpackChunkName: "about" */ '../components/mok_vue_index.vue')
    },
    {
        path: '/redirect',
        name: 'mok_std_redirect',
        component: () => import(/* webpackChunkName: "about" */ '../components/mok_vue_redirect.vue')
    }
    ]
    
    const router = createRouter({
    history: createWebHistory(process.env.BASE_URL),
    routes
    })
    
    export default router
    
    mok_vue_index.vue
    <template>
        <div>
            <div>
                <textarea id="result" rows="20"></textarea>
            </div>
            <div>
                <button @click=mok_popup>본인확인 시작(팝업)</button>
            </div>
            <!-- <div> -->
                <!-- <button @click=mok_move>본인확인 시작(이동)</button> -->
            <!-- </div> -->
        </div>
    </template>
    <script>
        export default {
            name: 'App',
            mounted () {
                let scriptTag = document.createElement('script');
                //운영서버
                // scriptTag.setAttribute('src', 'https://cert.mobile-ok.com/resources/js/index.js')
                //개발서버
                scriptTag.setAttribute('src', 'https://scert.mobile-ok.com/resources/js/index.js');
    
                document.head.appendChild(scriptTag);
    
                const callBackScript = document.createElement('script');
                callBackScript.innerText = 
                    "function result(result) {" +
                        "try {" +
                            "result = JSON.parse(result);" +
                            "document.querySelector('#result').value = JSON.stringify(result, null, 4);" +
                        "} catch (error) {" +
                            "document.querySelector('#result').value = result;" +
                        "}" +
                    "}"
                ;
    
                document.head.appendChild(callBackScript);
            },
    
            methods:{
                /* PC | 모바일 스크립트 인식 구분 */
                /* PC 스크립트 사용시 */
                mok_popup() {
                    window.MOBILEOK.process("https://이용기관 본인확인-표준창 인증요청 처리 (Node.js)URL/mok/mok_std_request", "WB", "result");
                }
                /* 모바일 스크립트 사용시 */
                // mok_move 사용시 mok_vue_server(pathname 수정 후 사용)
                // , mok_move() {
                    // 모바일 전용서비스로 페이지 이동처리 또는 카카오 브라우져 등 새창으로 처리가 어려운, 환경 또는 브라우져에서 처리
                    // window.MOBILEOK.process("https://이용기관 본인확인-표준창 인증요청 처리 (Vue)URL/mok/mok_std_request", "WB", "");
                // }
            }
        }
    </script>
    
    mok_vue_redirect.vue
    <template>
        <textarea id="result" rows="20"></textarea>
    </template>
    <script>
        export default {
            name: 'App',
            mounted () {
                let scriptTag = document.createElement('script');
                scriptTag.innerText = 
                    "let redirectData = new URLSearchParams(location.search).get('data');" +
                    "try {" +
                        "redirectData = JSON.parse(redirectData);" +
                        "document.querySelector('#result').value = JSON.stringify(redirectData, null, 4);" +
                    "} catch (error) {" +
                        "document.querySelector('#result').value = redirectData;" +
                    "}"
                ;
    
                document.head.appendChild(scriptTag);
        }
    };
    </script>
    
    mok.html
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="format-detection" content="telephone=no">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
        <!--  개발 URL :  -->
        <script src="https://scert.mobile-ok.com/resources/js/index.js"></script>
        <!--  운영 URL : <script src="https://cert.mobile-ok.com/resources/js/index.js"></script> -->
        <script>
        //모바일/PC 스크립트 인식 구분
        document.addEventListener("DOMContentLoaded", function () {
        document.querySelector("#mok_popup").addEventListener("click", function () {
            MOBILEOK.process("http://이용기관URL//mok_std_request.aspx", "WB", "result");
        })
        //document.querySelector("#mok_move").addEventListener("click", function () {
        //    // 모바일 전용서비스로 페이지 이동처리 또는 카카오 브라우져 등 새창으로 처리가 어려운, 환경 또는 브라우져에서 처리
        //    MOBILEOK.process("http://이용기관URL/mok_std_request.aspx", "WB", "");
        //})
        })
    
        function result(result) {
        try {
            result = JSON.parse(result);
            document.querySelector("#result").value = JSON.stringify(result, null, 4);
        } catch (error) {
            document.querySelector("#result").value = result;
        }
        }
        </script>
        <style>
            .container {
                width: 500px;
                border: 1px black solid;
                display: flex;
                flex-direction: column;
                padding: 5px;
            }
    
            .content {
                border: 1px black solid;
                display: flex;
                flex-direction: column;
                padding: 5px;
            }
    
            .item {
                border: 1px black solid;
                display: flex;
                flex-direction: column;
                padding: 5px;
            }
    
            label {
                margin-bottom: 5px;
                font-weight: 800;
            }
    
            input {
                box-sizing: border-box;
            }
    
            button {
                font-size: 20px;
                font-weight: 800;
                padding: 3px;
                box-sizing: border-box;
            }
        </style>
        <title>휴대폰본인확인_표준창</title>
    </head>
    <body>
        <div class="container">
            <div class="content">
                <div class="item">
                    <textarea id="result" rows="20"></textarea>
                </div>
            </div>
            <div class="content">
                <button id="mok_popup">본인확인 시작(팝업)</button>
            </div>
    <!--    <div class="content">-->
    <!--        <button id="mok_move">본인확인 시작(이동)</button>-->
    <!--    </div>-->
        </div>
    </body>
    </html>
    
    mok.html
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <meta name="apple-mobile-web-app-capable" content="yes"/>
        <meta name="format-detection" content="telephone=no">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
        <!--  개발 URL :  -->
        <script src="https://scert.mobile-ok.com/resources/js/index.js"></script>
        <!--  운영 URL : <script src="https://cert.mobile-ok.com/resources/js/index.js"></script> -->
        <script>
            //모바일/PC 스크립트 인식 구분
            document.addEventListener("DOMContentLoaded", function () {
                document.querySelector("#mok_popup").addEventListener("click", function () {
                    MOBILEOK.process("https://이용기관URL/mobileOK_std_request", "WB", "result");
                })
    
                // document.querySelector("#mok_move").addEventListener("click", function () {
                    // 모바일 전용서비스로 페이지 이동처리 또는 카카오 브라우져 등 새창으로 처리가 어려운, 환경 또는 브라우져에서 처리
                    //MOBILEOK.process("https://이용기관URL/mobileOK_std_request", "WB", "");
                // })
            })
    
            function result(result) {
                try {
                    result = JSON.parse(result);
                    document.querySelector("#result").value = JSON.stringify(result, null, 4);
                } catch (error) {
                    document.querySelector("#result").value = result;
                }
            }
        </script>
        <style>
            .container {
                width: 500px;
                border: 1px black solid;
                display: flex;
                flex-direction: column;
                padding: 5px;
            }
    
            .content {
                border: 1px black solid;
                display: flex;
                flex-direction: column;
                padding: 5px;
            }
    
            .item {
                border: 1px black solid;
                display: flex;
                flex-direction: column;
                padding: 5px;
            }
    
            label {
                margin-bottom: 5px;
                font-weight: 800;
            }
    
            input {
                box-sizing: border-box;
            }
    
            button {
                font-size: 20px;
                font-weight: 800;
                padding: 3px;
                box-sizing: border-box;
            }
        </style>
        <title>휴대폰본인확인_표준창</title>
    </head>
    <body>
        <div class="container">
        <div class="content">
            <div class="item">
                <textarea id="result" rows="20"></textarea>
            </div>
        </div>
        <div class="content">
            <button id="mok_popup">본인확인 시작(팝업)</button>
        </div>
        <!--    <div class="content">-->
        <!--        <button id="mok_move">본인확인 시작(이동)</button>-->
        <!--    </div>-->
        </div>
    </body>
    </html>
    

    페이지가 로딩 후(blank 팝업창 등) 본인확인-표준창을 자동 실행시 자바스크립트 설정 안내

    <script src="https://scert.mobile-ok.com/resources/js/index.js"></script>
    <script>
        window.onload = function(){
            MOBILEOK.process("https://이용기관URL/mok/mok_std_request.jsp", "WB", "result");
        }
    </script>
    

5. 본인확인-표준창 인증요청

본인확인-표준창에서 본인확인-표준창 인증요청시 서비스 정보를 설정합니다.

  • 본인확인-표준창 인증요청 준비 사항

    • 본인확인-표준창 암복호화키정보 파일

    • 본인확인-표준창 키파일 패스워드

  • 본인확인-표준창 인증요청 설정

    ID 내용 필수여부
    serviceId 본인확인-표준창 이용기관 서비스 ID
    encryptReqClientInfo 암호화된 본인확인 거래 요청 정보
    serviceType 이용상품 코드
    - "telcoAuth" : 휴대폰본인확인
    - "telcoAuth-LMS" : 휴대폰본인확인 LMS
    usageCode 서비스 이용 코드
    - "01001" : 회원가입
    - "01002" : 정보변경
    - "01003" : ID찾기
    - "01004" : 비밀번호찾기
    - "01005" : 본인확인용
    - "01006" : 성인인증
    - "01007" : 상품구매/결제
    - "01999" : 기타
    retTransferType 본인확인-표준창 결과 수신 타입
    - "MOKToken": 본인확인-표준창 결과 토큰
    returnUrl 본인확인 결과를 전달할 이용기관 URL, 본인확인 처리 결과를 returnUrl에 전달
    "https://" 포함한 URL 입력

    Warning

    • returnUrl 내에 개인정보를 절대 포함시켜서는 안됩니다.
    • 개인정보가 부분적으로 분리되어 저장 또는 처리되더라도, 이를 조합하여 개인을 식별할 수 있는 경우에는 해당 정보는 개인정보에 해당합니다.
    • (ex. hpno1=010&hpno2=1234&hpno3=5678) [휴대폰번호/성명/주민번호 등]
  • 본인확인-표준창 인증요청 예제

    mok_std_request.jsp
    <%@ page import="java.util.UUID" %>
    <%@ page import="java.util.Calendar" %>
    <%@ page import="java.util.logging.SimpleFormatter" %>
    <%@ page import="java.text.SimpleDateFormat" %>
    <%@ page import="com.dreamsecurity.mobileOK.mobileOKKeyManager" %>
    <%@ page import="com.dreamsecurity.mobileOK.MobileOKException" %>
    <%@ page import="com.dreamsecurity.json.JSONObject" %>
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%!
        public String mobileOK_std_request(mobileOKKeyManager mobileOK, HttpSession session, String clientPrefix) {
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
    
            /* 1. 본인확인-표준창 거래요청정보 생성  */
    
            /* 1.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
            // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
            // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
            String clientTxId = clientPrefix + UUID.randomUUID().toString().replaceAll("-", "");
    
            /* 1.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
            // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
            // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
            session.setAttribute("sessionClientTxId", clientTxId);
    
            /* 1.3 거래 ID, 인증 시간을 통한 본인확인 거래 요청 정보 생성  */
            String reqClientInfo = clientTxId + "|" + formatter.format(cal.getTime());
    
            /* 1.4 생성된 거래정보 암호화 */
            String encryptReqClientInfo;
            try {
                encryptReqClientInfo = mobileOK.RSAEncrypt(reqClientInfo);
            } catch (MobileOKException e) {
                return e.getErrorCode() + "|" + e.getMessage();
            }
    
            /* 1.5 거래 요청 정보 JSON 생성 */
            JSONObject jsonObject = new JSONObject();
            /* 본인확인 서비스 용도 */
            /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
            jsonObject.put("usageCode", "01001");
            /* 본인확인 이용기관 서비스 ID (키파일에 serviceId 포함 됨) */
            jsonObject.put("serviceId", mobileOK.getServiceId());
            /* 암호화된 본인확인 거래 요청 정보 */
            jsonObject.put("encryptReqClientInfo", encryptReqClientInfo);
            /* 이용상품 코드 */
            /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 “SMS”)*/
            /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 “LMS”)*/
            jsonObject.put("serviceType", "telcoAuth");
    
            /* 본인확인 결과 타입 */
            /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */        
            jsonObject.put("retTransferType", "MOKToken");
            /* 본인확인 결과 수신 URL "https://" 포함한 URL 입력 */
            /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
            jsonObject.put("returnUrl", "https://이용기관URL/mok/mok_std_result.jsp"); // [변경필요] 결과 수신 후 전달 URL 설정
    
            /* 1.6 거래 요청 정보 JSON 반환 */
            return jsonObject.toString();
        }
    %>
    <%
        /* 2. 본인확인 서비스 API 설정 */
        try {
            mobileOKKeyManager mobileOK = new mobileOKKeyManager();
            /* [변경필요] 키파일 및 키파일 패스워드는 드림시큐리티에서 제공한 mok_keyinfo.dat 경로 및 패스워드를 지정 */
            /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
            /* 키파일은 개발용과 운영용으로 구분 ➔ 개발 및 테스트 시 개발용 키파일을 이용 / 운영 환경에 적용 시 운영용 키파일로 변경 적용 필요 */        
            mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
    
            // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정
            String clientPrefix = "웹관리도구 회원사ID";  // [변경필요] 드림시큐리티에서 배포한 웹관리도구 회원사ID 설정
    
            /* 3. 거래 정보 응답 */
            out.write(mobileOK_std_request(mobileOK, session, clientPrefix));
        } catch (MobileOKException e) {
            out.write(e.getErrorCode() + "|" + e.getMessage());
        }
    %>
    
    mok_std_request.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    
    <%@ page import="java.util.UUID" %>
    <%@ page import="java.util.Calendar" %>
    <%@ page import="java.util.logging.SimpleFormatter" %>
    <%@ page import="java.text.SimpleDateFormat" %>
    <%@ page import="com.dreamsecurity.mobileOK.mobileOKKeyManager" %>
    <%@ page import="com.dreamsecurity.mobileOK.MobileOKException" %>
    <%@ page import="com.dreamsecurity.json.JSONObject" %>
    <%@ page import="java.security.Security"%>
    <%@ page import="org.bouncycastle.jce.provider.BouncyCastleProvider"%>
    <%@ page import="org.bouncycastle.jsse.provider.BouncyCastleJsseProvider"%>
    
    
    <%!
    
        public String mobileOK_std_request(mobileOKKeyManager mobileOK, HttpSession session, String clientPrefix) {
    
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
    
            /* 1. 본인확인-표준창 거래요청정보 생성  */
    
            /* 1.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
            // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
            // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
            String clientTxId = clientPrefix + UUID.randomUUID().toString().replaceAll("-", "");
    
            /* 1.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
            // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
            // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
            session.setAttribute("sessionClientTxId", clientTxId);
    
            /* 1.3 거래 ID, 인증 시간을 통한 본인확인 거래 요청 정보 생성  */
            String reqClientInfo = clientTxId + "|" + formatter.format(cal.getTime());
    
            /* 1.4 생성된 거래정보 암호화 */
            String encryptReqClientInfo;
            try {
                encryptReqClientInfo = mobileOK.RSAEncrypt(reqClientInfo);
            } catch (MobileOKException e) {
                return e.getErrorCode() + "|" + e.getMessage();
            }
    
            /* 1.5 거래 요청 정보 JSON 생성 */
            JSONObject jsonObject = new JSONObject();
            /* 본인확인 서비스 용도 */
            /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
            jsonObject.put("usageCode", "01001");
            /* 본인확인 이용기관 서비스 ID (키파일에 serviceId 포함 됨) */
            jsonObject.put("serviceId", mobileOK.getServiceId());
            /* 암호화된 본인확인 거래 요청 정보 */
            jsonObject.put("encryptReqClientInfo", encryptReqClientInfo);
            /* 이용상품 코드 */
            /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "SMS")*/
            /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "LMS")*/
            jsonObject.put("serviceType", "telcoAuth");
            /* 본인확인 결과 타입 */
            /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */        
            jsonObject.put("retTransferType", "MOKToken");
            /* 본인확인 결과 수신 URL - "https://" 포함한 URL 입력 */
            /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
            jsonObject.put("returnUrl", "https://이용기관URL/mok/mok_std_result.jsp"); // [변경필요] 결과 수신 후 전달 URL 설정
    
            /* 1.6 거래 요청 정보 JSON 반환 */
            return jsonObject.toString();
        }
    %>
    <%
    
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
            Security.addProvider(new BouncyCastleJsseProvider());
            System.setProperty("jdk.tls.trustNameService", "true");
        }
    
        /* 2. 본인확인 서비스 API 설정 */
        try {
            mobileOKKeyManager mobileOK = new mobileOKKeyManager();
            /* [변경필요] 키파일 및 키파일 패스워드는 드림시큐리티에서 제공한 mok_keyinfo.dat 경로 및 패스워드를 지정 */
            /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
            /* 키파일은 개발용과 운영용으로 구분 ➔ 개발 및 테스트 시 개발용 키파일을 이용 / 운영 환경에 적용 시 운영용 키파일로 변경 적용 필요 */        
            mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
    
            // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정
            String clientPrefix = "웹관리도구 회원사ID";  // [변경필요] 드림시큐리티에서 배포한 웹관리도구 회원사ID 설정
    
            /* 3. 거래 정보 응답 */
            out.write(mobileOK_std_request(mobileOK, session, clientPrefix));
        } catch (MobileOKException e) {
            out.write(e.getErrorCode() + "|" + e.getMessage());
        }
    %>
    
    mok_std_request.php
    <?php
        // 각 버전 별 맞는 mobileOKManager-php를 사용
        $mobileOK_path = "./mobileOK_manager_phpseclib_v3.0_v1.0.2.php";
    
        if(!file_exists($mobileOK_path)) {
            die('1000|mobileOK_Key_Manager파일이 존재하지 않습니다.');
        } else {
            require_once $mobileOK_path;
        }
    ?>
    <?php
        header("Content-Type:text/html;charset=utf-8");
    
        /* 1. 본인확인 서비스 API 설정 */
        $mobileOK = new mobileOK_Key_Manager();
        /* [변경필요] 키파일 및 키파일 패스워드는 드림시큐리티에서 제공한 mok_keyinfo.dat 경로 및 패스워드를 지정 */
        /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
        /* 키파일은 개발용과 운영용으로 구분 ➔ 개발 및 테스트 시 개발용 키파일을 이용 / 운영 환경에 적용 시 운영용 키파일로 변경 적용 필요 */
        $key_path = "/본인확인 키정보파일 Path/mok_keyInfo.dat";
        $password = "키파일 패스워드";
        $mobileOK->key_init($key_path, $password);
    
        // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정
        $clientPrefix = "웹관리도구 회원사ID";     // [변경필요] 드림시큐리티에서 배포한 웹관리도구 회원사ID 설정
    
        /* [변경필요] 결과 수신 후 전달 URL 설정 */
        /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
        $result_return_url = "https://이용기관URL/mok/mok_std_result.php";
    
        /* 2. 거래 정보 호출 */
        echo mobileOK_std_request($mobileOK, $result_return_url,$clientPrefix);
    ?>
    <?php
        /* 본인확인 표준창 인증 요청 예제 함수 */
        function mobileOK_std_request($mobileOK, $result_return_url, $clientPrefix) {
            // local시간 설정이 다르게 될  수 있음으로 기본 시간 설정을 서울로 해놓는다.
            date_default_timezone_set('Asia/Seoul');
    
            /* 3. 본인확인-표준창 거래요청정보 생성  */
    
            /* 3.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
            // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
            // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
            $client_tx_id = $clientPrefix.uuid();
    
            /* 3.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
            // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
            // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
            session_start();
            $_SESSION['sessionClientTxId'] = $client_tx_id;
    
            /* 3.3 거래 ID, 인증 시간을 통한 본인확인 거래 요청 정보 생성  */
            $date_time = date("YmdHis");
            $req_client_info = $client_tx_id."|".$date_time;
    
            /* 3.4 생성된 거래정보 암호화 */
            $encrypt_req_client_info = $mobileOK->rsa_encrypt($req_client_info);
    
            /* 3.5 거래 요청 정보 JSON 생성 */
            $send_data = array(
                /* 본인확인 서비스 용도 */
                /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
                'usageCode'=> '01001'
                /* 본인확인 서비스 ID */
                , 'serviceId'=>$mobileOK->get_service_id()
                /* 암호화된 본인확인 거래 요청 정보 */
                , 'encryptReqClientInfo'=>$encrypt_req_client_info
                /* 이용상품 코드 */
                /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "SMS")*/
                /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "LMS")*/
                , 'serviceType'=>'telcoAuth'
                /* 본인확인 결과 타입 */
                /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */            
                , 'retTransferType'=>'MOKToken'             
                /* 본인확인 결과 수신 URL - "https://" 포함한 URL 입력 */
                , 'returnUrl'=>$result_return_url
            );
    
            /* 3.6 거래 요청 정보 JSON 반환 */
            // JSON Encoding시 '/'입력시 '\\/'로 입력되는 현상을 방지하기 위해서 아래의 옵션을 사용
            return json_encode($send_data, JSON_UNESCAPED_SLASHES);
        }
    
        /* 거래 ID(uuid) 생성 예제 함수 */
        function uuid() {
            return sprintf('%04x%04x%04x%04x%04x%04x%04x%04x',
    
            // 32 bits for "time_low"
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
    
            // 16 bits for "time_mid"
            mt_rand(0, 0xffff),
    
            // 16 bits for "time_hi_and_version",
            // four most significant bits holds version number 4
            mt_rand(0, 0x0fff) | 0x4000,
    
            // 16 bits, 8 bits for "clk_seq_hi_res",
            // 8 bits for "clk_seq_low",
            // two most significant bits holds zero and one for variant DCE1.1
            mt_rand(0, 0x3fff) | 0x8000,
    
            // 48 bits for "node"
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
            );
        }
    ?>
    
    mok_server_std.js
    const express = require('express');
    const session = require('express-session');
    const axios = require("axios");
    const bodyParser = require('body-parser');
    const urlencode = require('urlencode');
    
    /* 암호화 라이브러리 mok_Key_Manager */
    let mobileOK;mobileOK
    try {
        mobileOK= require("./mok_Key_Manager_v1.0.3.js"); 
    } catch (error)  {
        console.log('mok_Key_Manager 파일의 경로가 올바르지 않습니다.');
    }
    /* 1. express 서버 설정 */
    const app = express();
    
    /* 1-1 포트(port) 설정 */
    const port = 8080 ;
    
    /* 1-2 루트(root)패키지의 정적파일을 읽기위한 설정 */
    app.use(express.static('./'));
    
    /* 1-3 Content-type : plain-text 설정 */
    app.use(bodyParser.text());
    
    /* 1-4 request-body 데이터 urlencode 설정 */
    app.use(bodyParser.urlencoded({ extended: true }));
    
    /* 1-5 session 설정 */
    app.use(session({
        secret:uuid(),
        resave:false,
        saveUninitialized: false
    }));
    
    /* 1-5 본인확인 Node.js 서버 실행 */
    app.listen(port, () => {
        console.log(`App listening at Port : ${port}`);
    });
    
    // 본인확인 인증결과를 Redirect로 설정하고 뷰(view)를 ejs로 이용시 
    // app.set('view engine', 'ejs');
    
    
    /* 2. 본인확인 인증결과 경로설정 */
    /* 2-1 본인확인 인증결과 API 요청 URL */
    const MOK_RESULT_REQUEST_URL = 'https://scert.mobile-ok.com/gui/service/v1/result/request';  // 개발
    // const MOK_RESULT_REQUEST_URL = 'https://cert.mobile-ok.com/gui/service/v1/result/request';  // 운영
    
    /* 2-1 본인확인 Node.js서버 매핑 URL */
    const requestUri = 'https://본인확인 요청 URL/mok/mok_std_request';  // mok 인증 요청 URI  
    const resultUri = 'https://본인확인 요청 URL/mok/mok_std_result';  // mok 결과 요청 URI
    
    
    /* 2-3 결과 수신 후 전달 URL 설정 - "https://" 포함한 URL 입력 */
    /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
    const resultUrl = 'https://이용기관URL/mok/mok_std_result'; 
    
    /* 3. 본인확인 서비스 API 설정 */
    /* 3-1 키파일 경로(본인확인 키정보파일 Path)설정 */
    /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
    const keyPath = '/본인확인 키정보파일 Path/mok_keyInfo.dat';
    /* 3-2 키파일 비밀번호(본인확인 키파일 패스워드)설정 */
    const password = '키파일 패스워드';
    mobileOK.keyInit(keyPath, password);
    
    // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정, 이용기관식별자는 이용기관코드 영문자로 반드시 수정
    const clientPrefix = "본인확인 이용기관식별자 PREFIX";  // 8자이내 영대소문자,숫자 (예) MOK, TESTCOKR
    
    /* 본인확인 표준창 인증요청 함수 예제 (mok_std_request) */
    app.post(requestUri, (req, res) => {
        /* 1. 본인확인-표준창 거래요청정보 생성  */
    
        /* 1.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
        // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
        // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
        let clientTxId = clientPrefix + uuid();
    
        /* 1.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
        // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
        // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
        req.session.clientTxId = clientTxId;
        /* 1.3 거래 ID, 인증 시간을 통한 본인확인 거래 요청 정보 생성  */
        clientTxId = clientTxId + "|" + getCurrentDate();
    
        /* 1.4 생성된 거래정보 암호화 */
        const encClientTxId = mobileOK.RSAEncrypt(clientTxId);
    
        /* 1.5 거래 요청 정보 설정 */
        const authRequestObject = {
            /* 본인확인 서비스 용도 */
            /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
            'usageCode' : '01001'
            /* 본인확인 서비스 ID */  
            , 'serviceId' : mobileOK.getServiceId()
            /* 암호화된 본인확인 거래 요청 정보 */
            , 'encryptReqClientInfo' : encClientTxId
            /* 이용상품 코드 */
            /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "SMS")*/
            /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "LMS")*/
            , 'serviceType' : 'telcoAuth'
            /* 본인확인 결과 타입 */
            /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */
            , 'retTransferType' : 'MOKToken'
            /* 본인확인 결과 수신 URL */
            , 'returnUrl' : resultUrl
        };
    
        /* 1.6 거래 요청 정보 JSON 반환 */
        res.send(JSON.stringify(authRequestObject));
    })
    
    /* 본인확인 표준창 인증결과 함수 예제 (mok_std_result) */
    app.post(resultUri, async (req, res) => {
        /* 1. 본인확인 결과 타입 설정 */
        const resultRequestString = req.body;
        const resultRequestJson = urlencode.decode(resultRequestString.data);
        const resultRequestObject = JSON.parse(resultRequestJson);
    
        /* 2. 본인확인 결과 타입별 결과 처리 */
        let encryptMOKResult;
        if (resultRequestObject.encryptMOKKeyToken != null) {
            /* 2.1 본인확인 결과 타입 : MOKToken */
            /* 2.1.1 본인확인 결과요청 입력정보 설정 */
            const authResultRequestObject = { encryptMOKKeyToken : resultRequestObject.encryptMOKKeyToken };
            /* 2.1.2 본인확인 결과요청 */
            const resultResponseObject = await sendPost(MOK_RESULT_REQUEST_URL, authResultRequestObject);
            try {
                if (typeof resultResponseObject == 'undefined') {
                    throw MOKException;
                }
            } catch(MOKException) {
                 return res.send('-0|본인확인 서버통신(결과요청)에 실패했습니다.');
            }
            encryptMOKResult = resultResponseObject.encryptMOKResult;
    
            /* 2.1.3 본인확인 결과요청 실패시 */
            if (resultResponseObject.resultCode != '2000') {
                console.log('본인확인 결과요청에 실패했습니다.');
                return res.send(resultResponseObject.resultCode + ', ' + resultResponseObject.resultMsg);
            }
        } else {
            return res.send('-1|본인확인 MOKToken 인증결과 응답이 없습니다.');
        }
    
        // 'encryptMOKResult'가 없을 경우
        try {
            if (encryptMOKResult == null || encryptMOKResult == '' || typeof encryptMOKResult == undefined) {
                throw MOKException;
            }
        } catch (MOKException) {
            return res.send('-1|본인확인 MOKToken 가 없습니다.');
        }
    
        // encryptMOKResult 복호화가 실패하는 경우
        let decryptMOKResultJson = null;
        try {
            decryptMOKResultJson = mobileOK.getResult(encryptMOKResult);
        } catch(error) {
            return res.send('-3|본인확인 결과 복호화 오류');
        }
    
        /* 3. 본인확인 결과정보 변환 */
        /* 3-1 본인확인 결과정보 복호화 */
        const decryptMOKResultObject = JSON.parse(decryptMOKResultJson);
    
        /* 이용기관 거래 ID */
        let clientTxId = '';
        if (decryptMOKResultObject.hasOwnProperty("clientTxId")) {
            clientTxId = decryptMOKResultObject.clientTxId;
        }
        // 세션 내 요청 clientTxId 와 수신한 clientTxId 가 동일한지 반드시 비교
        if (req.session.clientTxId != clientTxId) {
            return res.send('-4|세션값에 저장된 거래ID 비교 실패');
        }
    
        /* 3-2 본인확인 결과정보 설정 */
        /* 사용자 이름 */
        let userName = '';
        if (decryptMOKResultObject.hasOwnProperty("userName")) {
            userName = decryptMOKResultObject.userName;
        }
        /* 이용기관 ID */
        let siteId = '';
        if (decryptMOKResultObject.hasOwnProperty("siteId")) {
              siteId = decryptMOKResultObject.siteId;
        }
        /* 본인확인 거래 ID */
        let txId = '';
        if (decryptMOKResultObject.hasOwnProperty("txId")) {
            txId = decryptMOKResultObject.txId;
        }
        /* 서비스제공자(인증사업자) ID */
        let providerId = '';
        if (decryptMOKResultObject.hasOwnProperty("providerId")) {
            providerId = decryptMOKResultObject.providerId;
        }
        /* 이용 서비스 유형 */
        let serviceType = '';
        if (decryptMOKResultObject.hasOwnProperty("serviceType")) {
            serviceType = decryptMOKResultObject.serviceType;
        }
        /* 사용자 CI */
        let ci = '';
        if (decryptMOKResultObject.hasOwnProperty("ci")) {
            ci = decryptMOKResultObject.ci;
        }
        /* 사용자 DI */
        let di = '';
        if (decryptMOKResultObject.hasOwnProperty("di")) {
            di = decryptMOKResultObject.di;
        }
        /* 사용자 전화번호 */
        let userPhone = '';
        if (decryptMOKResultObject.hasOwnProperty("userPhone")) {
            userPhone = decryptMOKResultObject.userPhone;
        }
        /* 사용자 생년월일 */
        let userBirthday = '';
        if (decryptMOKResultObject.hasOwnProperty("userBirthday")) {
            userBirthday = decryptMOKResultObject.userBirthday;
        }
        /* 사용자 성별 (1: 남자, 2: 여자) */
        let userGender = '';
        if (decryptMOKResultObject.hasOwnProperty("userGender")) {
            userGender = decryptMOKResultObject.userGender;
        }
        /* 사용자 국적 (0: 내국인, 1: 외국인) */
        let userNation = '';
        if (decryptMOKResultObject.hasOwnProperty("userNation")) {
            userNation = decryptMOKResultObject.userNation;
        }
        /* 본인확인 인증 종류 */
        const reqAuthType = decryptMOKResultObject.reqAuthType;
        /* 본인확인 요청 시간 */
        const reqDate = decryptMOKResultObject.reqDate;
        /* 본인확인 인증 서버 */
        const issuer = decryptMOKResultObject.issuer;
        /* 본인확인 인증 시간 */
        const issueDate = decryptMOKResultObject.issueDate;
    
    
    
        /* 4. 이용기관 응답데이터 셔션 및 검증유효시간 처리  */
        // 입력 시간 검증 (검증결과 생성 후 10분 이내 검증 권고) 
        let oldDate = new Date(issueDate);
        oldDate = getOldTime(oldDate);
        const currentDate = getCurrentDate();
    
        if (oldDate < currentDate) {
                return res.send('-5|토큰 생성 10분 결과');
        }
    
        /* 5. 본인확인 결과 반환 */
        // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
        // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
        let data = {
            'errorCode' : '2000'
            , 'resultMsg' : '성공'
            , 'data' : userName
        };
    
        /* 6. 본인확인 결과 응답 방식 */
        /* 6.1 : 팝업창(Pop-Up) : callback 함수 정의시 */
        /* 6.1-1 팝업창(Pop-Up) 결과반환 */
        res.send(data);
        /* 6.2 : 페이지 이동(Redirect) : callback 함수 "" 값으로 미 정의시 */
        /* 6.2-1 이동페이지(Redirect Page) 설정 */
        // const redirectUrl = '/mok_std_redirect.ejs의 경로/mok/mok_std_redirect.ejs'
    
        /* 6.2-2 이동페이지(Redirect Page) 결과반환 */
        // res.render(redirectUrl, {data : JSON.stringify(data)});
    });
    
    /* 거래 ID(uuid) 생성 예제 함수 */
    function uuid() {
        return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    
            return v.toString(16);
        });
    }
    
    /* 본인확인 거래 ID(요청 시간) 생성 예제 함수 */
    function getCurrentDate() {
        let newDate = new Date();
        newDate.toLocaleString('ko-kr');
    
        let year = newDate.getFullYear();
        let mon = newDate.getMonth() + 1;
        let date = newDate.getDate();
    
        let hour = newDate.getHours();
        let min = newDate.getMinutes();
        let sec = newDate.getSeconds();
    
        mon = mon < 10 ? `0${mon}` : `${mon}`;
        date = date < 10 ? `0${date}` : `${date}`;
        hour = hour < 10 ? `0${hour}` : `${hour}`;
        min = min < 10 ? `0${min}` : `${min}`;
        sec = sec < 10 ? `0${sec}` : `${sec}`;
    
        const reqDate = year + mon + date + hour + min + sec;
    
        return reqDate;
    }
    
    /* 본인확인 서버 통신 예제 함수 */
    function getOldTime(oldTime) {
        let year = oldTime.getFullYear();
        let mon = oldTime.getMonth() + 1;
        let date = oldTime.getDate();
    
        let hour = oldTime.getHours();
        let min = oldTime.getMinutes()+ 10;
        let sec = oldTime.getSeconds();
    
        if (min >= 60) {
            min = min - 60;
    
            hour = hour + 1;
        }
        if (hour >= 24) {
            hour = hour - 24;
    
            date = date + 1;
        }
        if (date > new Date(year, mon, 0).getDate()) {
            date = date - (new Date(year, mon, 0).getDate());
    
            mon = mon + 1;
        }
        if (mon >= 13) {
            mon = mon - 12;
    
            year = year + 1;
        }
    
        mon = mon < 10 ? `0${mon}` : `${mon}`;
        date = date < 10 ? `0${date}` : `${date}`;
        hour = hour < 10 ? `0${hour}` : `${hour}`;
        min = min < 10 ? `0${min}` : `${min}`;
        sec = sec < 10 ? `0${sec}` : `${sec}`;
    
        const reqDate = year + mon + date + hour + min + sec;
    
        return reqDate;
    }
    
    async function sendPost(targetUrl, encryptMOKKeyToken) {
        try {
            let responseData = await axios ({
                method : 'post',
                url : targetUrl,
                data : encryptMOKKeyToken
            });
    
            return responseData.data;
        } catch (AxiosError) {
            console.log('본인확인 서버 통신URL이 잘 못 되었습니다.');
        }
    }
    
    views/mok_std_redirect.ejs
    1
    2
    3
    4
    5
    <%# mobile_std_server(mok_std_result) 처리 기능 참조 %>
    <%-
        data
    %>
    <p>Redirect Page</p>
    
    mok_react_server.js
    const express = require('express');
    const session = require('express-session');
    const axios = require("axios");
    const bodyParser = require('body-parser');
    const urlencode = require('urlencode');
    const cors = require('cors');
    const url = require('url');
    
    /* 암호화 라이브러리 mok_Key_Manager */
    let mobileOK;
    try {
        mobileOK= require("./mok_Key_Manager_v1.0.3.js"); 
    } catch (error)  {
        console.log('mok_Key_Manager 파일의 경로가 올바르지 않습니다.');
    }
    /* 1. express 서버 설정 */
    const app = express();
    
    /* 1-1 포트(port) 설정 */
    const port = 5000 ;
    
    /* 1-2 CORS 설정 */
    /* 모든 URL에 대한 CORS 허용 */
    /* app.use(cors()); */
    
    /* 특정 URL에 대한 CORS 허용 */
    let corsOptions = {
        origin: 'https://이용기관 본인확인-표준창 인증요청 처리 (React)URL',
        credentials: true
    }
    app.use(cors(corsOptions));
    
    /* 1-3 루트(root)패키지의 정적파일을 읽기위한 설정 */
    app.use(express.static('./'));
    
    /* 1-4 Content-type : plain-text 설정 */
    app.use(bodyParser.text());
    
    /* 1-5 request-body 데이터 urlencode 설정 */
    app.use(bodyParser.urlencoded({ extended: true }));
    
    /* 1-6 본인확인 Node.js 서버 실행 */
    app.listen(port, () => {
        console.log(`App listening at Port : ${port}`);
    });
    
    /* 2. 본인확인 인증결과 경로설정 */
    /* 2-1 본인확인 인증결과 MOKResult API 요청 URL */
    const MOK_RESULT_REQUEST_URL = 'https://scert.mobile-ok.com/gui/service/v1/result/request';  // 개발
    // const MOK_RESULT_REQUEST_URL = 'https://cert.mobile-ok.com/gui/service/v1/result/request';  // 운영
    
    /* 2-1 본인확인 Node.js서버 매핑 URL */
    const requestUri = 'https://본인확인 요청 URL/mok/mok_std_request';  // mok 인증 요청 URI  
    const resultUri = 'https://본인확인 요청 URL/mok/mok_std_result';  // mok 결과 요청 URI
    
    /* 2-3 결과 수신 후 전달 URL 설정 - "https://" 포함한 URL 입력 */
    /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
    const resultUrl = 'https://이용기관 본인확인-표준창 요청 (Node.js)URL/mok/mok_std_result'; 
    
    /* 3. 본인확인 서비스 API 설정 */
    /* 3-1 키파일 경로(본인확인 키정보파일 Path)설정 */
    /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
    const keyPath = '/본인확인-표준창 키정보파일 Path/mok_keyInfo.dat';
    /* 3-2 키파일 비밀번호(본인확인 키파일 패스워드)설정 */
    const password = '본인확인-표준창 키파일 패스워드';
    mobileOK.keyInit(keyPath, password);
    
    // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정, 이용기관식별자는 이용기관코드 영문자로 반드시 수정
    const clientPrefix = "본인확인 이용기관식별자 PREFIX"     // 8자이내 영대소문자,숫자 (예) MOK, TESTCOKR
    
    /* 본인확인 표준창 인증요청 함수 예제 */
    app.post(requestUri, (req, res) => {
        /* 1. 본인확인-표준창 거래요청정보 생성  */
    
        /* 1.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
        // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
        // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
        let sampleClientTxId = clientPrefix + uuid();
    
        /* 1.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
        // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
        // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
    
        /* 1.3 본인확인-표준창 거래요청정보 생성  */
        const clientTxId = sampleClientTxId + "|" + getCurrentDate();
    
        /* 1.4 본인확인-표준창 거래요청정보 암호화 */
        const encClientTxId = mobileOK.RSAEncrypt(clientTxId);
    
        /* 1.5 본인확인-표준창 거래요청정보 설정 */
        const authRequestObject = {
            /* 본인확인 서비스 용도 */
            /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
            'usageCode' : '01001'
            /* 본인확인 서비스 ID */  
            , 'serviceId' : mobileOK.getServiceId()
            /* 암호화된 본인확인 거래 요청 정보 */
            , 'encryptReqClientInfo' : encClientTxId
            /* 이용상품 코드 */
            /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "SMS")*/
            /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "LMS")*/
            , 'serviceType' : 'telcoAuth'
            /* 본인확인 결과 타입 */
            /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */
            , 'retTransferType' : 'MOKToken'
            /* 본인확인 결과 수신 URL */
            , 'returnUrl' : resultUrl
        };
    
        /* 1.6 거래 요청 정보 JSON 반환 */
        res.send(JSON.stringify(authRequestObject));
    })
    
    /* 본인확인 표준창 인증결과 함수 예제 */
    app.post(resultUri, async (req, res) => {
        /* 1. 본인확인 결과 타입 설정 */
        const resultRequestString = req.body;
        const resultRequestJson = urlencode.decode(resultRequestString.data);
        const resultRequestObject = JSON.parse(resultRequestJson);
    
        /* 2. 본인확인 결과 타입별 결과 처리 */
        let encryptMOKResult;
        if (resultRequestObject.encryptMOKKeyToken != null) {
            /* 2.1 본인확인 결과 타입 : MOKToken */
            /* 2.1.1 본인확인 결과요청 입력정보 설정 */
            const authResultRequestObject = { encryptMOKKeyToken : resultRequestObject.encryptMOKKeyToken };
            /* 2.1.2 본인확인 결과요청 */
            const resultResponseObject = await sendPost(MOK_RESULT_REQUEST_URL, authResultRequestObject);
            try {
                if (typeof resultResponseObject == 'undefined') {
                    throw MOKException;
                }
            } catch(MOKException) {
                return res.send('-0|본인확인 서버통신(결과요청)에 실패했습니다.');
            }
            encryptMOKResult = resultResponseObject.encryptMOKResult;
    
            /* 2.1.3 본인확인 결과요청 실패시 */
            if (resultResponseObject.resultCode != '2000') {
                console.log('본인확인 결과요청에 실패했습니다.');
                return res.send(resultResponseObject.resultCode + ', ' + resultResponseObject.resultMsg);
            }
        } else {
            return res.send('-1|본인확인 MOKToken 인증결과 응답이 없습니다.');
        }
    
    
        // 'encryptMOKResult'가 없을 경우
        try {
            if (encryptMOKResult == null || encryptMOKResult == '' || typeof encryptMOKResult == undefined) {
                throw MOKException;
            }
        } catch (MOKException) {
            return res.send('-1|본인확인 MOKToken 가 없습니다.');
        }
    
        // encryptMOKResult 복호화가 실패하는 경우
        let decryptMOKResultJson = null;
        try {
            decryptMOKResultJson = mobileOK.getResult(encryptMOKResult);
        } catch(error) {
            return res.send('-3|본인확인 결과 복호화 오류');
        }
    
        /* 3. 본인확인 결과정보 변환 */
        /* 3-1 본인확인 결과정보 복호화 */
        const decryptMOKResultObject = JSON.parse(decryptMOKResultJson);
    
        /* 3-2 본인확인 결과정보 설정 */
        /* 사용자 이름 */
        let userName = '';
        if (decryptMOKResultObject.hasOwnProperty("userName")) {
            userName = decryptMOKResultObject.userName;
        }
        /* 이용기관 ID */
        let siteId = '';
        if (decryptMOKResultObject.hasOwnProperty("siteId")) {
            siteId = decryptMOKResultObject.siteId;
        }
        /* 이용기관 거래 ID */
        let clientTxId = '';
        if (decryptMOKResultObject.hasOwnProperty("clientTxId")) {
            clientTxId = decryptMOKResultObject.clientTxId;
        }
        /* 본인확인 거래 ID */
        let txId = '';
        if (decryptMOKResultObject.hasOwnProperty("txId")) {
            txId = decryptMOKResultObject.txId;
        }
        /* 서비스제공자(인증사업자) ID */
        let providerId = '';
        if (decryptMOKResultObject.hasOwnProperty("providerId")) {
            providerId = decryptMOKResultObject.providerId;
        }
        /* 이용 서비스 유형 */
        let serviceType = '';
        if (decryptMOKResultObject.hasOwnProperty("serviceType")) {
            serviceType = decryptMOKResultObject.serviceType;
        }
        /* 사용자 CI */
        let ci = '';
        if (decryptMOKResultObject.hasOwnProperty("ci")) {
            ci = decryptMOKResultObject.ci;
        }
        /* 사용자 DI */
        let di = '';
        if (decryptMOKResultObject.hasOwnProperty("di")) {
            di = decryptMOKResultObject.di;
        }
        /* 사용자 전화번호 */
        let userPhone = '';
        if (decryptMOKResultObject.hasOwnProperty("userPhone")) {
            userPhone = decryptMOKResultObject.userPhone;
        }
        /* 사용자 생년월일 */
        let userBirthday = '';
        if (decryptMOKResultObject.hasOwnProperty("userBirthday")) {
            userBirthday = decryptMOKResultObject.userBirthday;
        }
        /* 사용자 성별 (1: 남자, 2: 여자) */
        let userGender = '';
        if (decryptMOKResultObject.hasOwnProperty("userGender")) {
            userGender = decryptMOKResultObject.userGender;
        }
        /* 사용자 국적 (0: 내국인, 1: 외국인) */
        let userNation = '';
        if (decryptMOKResultObject.hasOwnProperty("userNation")) {
            userNation = decryptMOKResultObject.userNation;
        }
        /* 본인확인 인증 종류 */
        const reqAuthType = decryptMOKResultObject.reqAuthType;
        /* 본인확인 요청 시간 */
        const reqDate = decryptMOKResultObject.reqDate;
        /* 본인확인 인증 서버 */
        const issuer = decryptMOKResultObject.issuer;
        /* 본인확인 인증 시간 */
        const issueDate = decryptMOKResultObject.issueDate;
    
    
    
        /* 4. 수신결과 clientTxId 와 세션에 저장한 clientTxId 가 동일한지 비교(권고, 세션서버 및 DB등을 통한 검증) */
    
        /* 요청 세션검증 이용기관 구현 */
    
        /* 검증정보 유효시간 검증 (검증결과 생성 후 10분 이내 검증 권고) */
        let oldDate = new Date(issueDate);
        oldDate = getOldTime(oldDate);
    
        const currentDate = getCurrentDate();
    
        if (oldDate < currentDate) {
            return res.send('-5|토큰 생성 10분 결과');
        }
    
        /* 5. 이용기관 서비스 기능 처리 */
    
        // - 이용기관에서 수신한 개인정보 검증 확인 처리
    
        // - 이용기관에서 수신한 CI 확인 처리
    
    
        /* 6. 본인확인 결과 반환 */
    
        // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
        // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
    
        let data = {
            'errorCode' : '2000'
            , 'resultMsg' : '성공'
            , 'data' : userName
        };
    
        /* 7. 본인확인 결과 응답 방식 */
        /* 7.1 : 팝업창(Pop-Up) : callback 유 */
        /* 7.1-1 팝업창(Pop-Up) 결과반환 */
        res.send(data);
    
        /* 7.2 : 페이지 이동(Redirect) : callback 무 */
        /* 7.2-1 이동페이지(Redirect Page) 설정 */
        // res.redirect(url.format({
        //     pathname:"https://이용기관 본인확인-표준창 인증요청 처리 (React)URL/mok/redirect",
        //     query: {
        //        "data": JSON.stringify(data),
        //      }
        //   }));
    });
    
    /* 거래 ID(uuid) 생성 예제 함수 */
    function uuid() {
        return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    
            return v.toString(16);
        });
    }
    
    /* 본인확인 거래 ID(요청 시간) 생성 예제 함수 */
    function getCurrentDate() {
        let newDate = new Date();
        newDate.toLocaleString('ko-kr');
    
        let year = newDate.getFullYear();
        let mon = newDate.getMonth() + 1;
        let date = newDate.getDate();
    
        let hour = newDate.getHours();
        let min = newDate.getMinutes();
        let sec = newDate.getSeconds();
    
        mon = mon < 10 ? `0${mon}` : `${mon}`;
        date = date < 10 ? `0${date}` : `${date}`;
        hour = hour < 10 ? `0${hour}` : `${hour}`;
        min = min < 10 ? `0${min}` : `${min}`;
        sec = sec < 10 ? `0${sec}` : `${sec}`;
    
        const reqDate = year + mon + date + hour + min + sec;
    
        return reqDate;
    }
    
    function getOldTime(oldTime) {
        let year = oldTime.getFullYear();
        let mon = oldTime.getMonth() + 1;
        let date = oldTime.getDate();
    
        let hour = oldTime.getHours();
        let min = oldTime.getMinutes()+ 10;
        let sec = oldTime.getSeconds();
    
        if (min >= 60) {
            min = min - 60;
    
            hour = hour + 1;
        }
        if (hour >= 24) {
            hour = hour - 24;
    
            date = date + 1;
        }
        if (date > new Date(year, mon, 0).getDate()) {
            date = date - (new Date(year, mon, 0).getDate());
    
            mon = mon + 1;
        }
        if (mon >= 13) {
            mon = mon - 12;
    
            year = year + 1;
        }
    
        mon = mon < 10 ? `0${mon}` : `${mon}`;
        date = date < 10 ? `0${date}` : `${date}`;
        hour = hour < 10 ? `0${hour}` : `${hour}`;
        min = min < 10 ? `0${min}` : `${min}`;
        sec = sec < 10 ? `0${sec}` : `${sec}`;
    
        const reqDate = year + mon + date + hour + min + sec;
    
        return reqDate;
    }
    
    /* 본인확인 서버 통신 예제 함수 */
    async function sendPost(targetUrl, encryptMOKKeyToken) {
        try {
            let responseData = await axios ({
                method : 'post',
                url : targetUrl,
                data : encryptMOKKeyToken
            });
    
            return responseData.data;
        } catch (AxiosError) {
            console.log('본인확인 서버 통신URL이 잘 못 되었습니다.');
        }
    }
    
    mok_vue_server.js
    const express = require('express');
    const session = require('express-session');
    const axios = require("axios");
    const bodyParser = require('body-parser');
    const urlencode = require('urlencode');
    const cors = require('cors');
    const url = require('url');
    
    /* 암호화 라이브러리 mok_Key_Manager */
    let mobileOK;
    try {
        mobileOK= require("./mok_Key_Manager_v1.0.3.js"); 
    } catch (error)  {
        console.log('mok_Key_Manager 파일의 경로가 올바르지 않습니다.');
    }
    
    /* 1. express 서버 설정 */
    const app = express();
    
    /* 포트(port) 설정 */
    const port = 5000 ;
    
    /* CORS 설정 */
    /* 모든 URL에 대한 CORS 허용 */
    /* app.use(cors()); */
    
    /* 특정 URL에 대한 CORS 허용 */
    let corsOptions = {
        origin: 'https://이용기관 본인확인-표준창 인증요청 처리 (Vue)URL',
        credentials: true
    }
    app.use(cors(corsOptions));
    
    /* 루트(root)패키지의 정적파일을 읽기위한 설정 */
    app.use(express.static('./'));
    
    /* Content-type : plain-text 설정 */
    app.use(bodyParser.text());
    
    /* request-body 데이터 urlencode 설정 */
    app.use(bodyParser.urlencoded({ extended: true }));
    
    /* 본인확인 Node.js 서버 실행 */
    app.listen(port, () => {
        console.log(`App listening at Port : ${port}`);
    });
    
    /* 2. 본인확인 인증결과 경로설정 */
    /* 2-1 본인확인 인증결과 MOKResult API 요청 URL */
    const MOK_RESULT_REQUEST_URL = 'https://scert.mobile-ok.com/gui/service/v1/result/request';  // 개발
    // const MOK_RESULT_REQUEST_URL = 'https://cert.mobile-ok.com/gui/service/v1/result/request';  // 운영
    
    /* 2-1 본인확인 Node.js서버 매핑 URL */
    const requestUri = 'https://본인확인 요청 URL/mok/mok_std_request';  // mok 인증 요청 URI  
    const resultUri = 'https://본인확인 요청 URL/mok/mok_std_result';  // mok 결과 요청 URI
    
    /* 2-3 결과 수신 후 전달 URL 설정 - "https://" 포함한 URL 입력 */
    /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
    const resultUrl = 'https://이용기관 본인확인-표준창 요청 (Node.js)URL/mok/mok_std_result'; 
    
    /* 3. 본인확인 서비스 API 설정 */
    /* 3-1 키파일 경로(본인확인 키정보파일 Path)설정 */
    /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
    const keyPath = '/본인확인-표준창 키정보파일 Path/mok_keyInfo.dat';
    /* 3-2 키파일 비밀번호(본인확인 키파일 패스워드)설정 */
    const password = '본인확인-표준창 키파일 패스워드';
    mobileOK.keyInit(keyPath, password);
    
    // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정, 이용기관식별자는 이용기관코드 영문자로 반드시 수정
    const clientPrefix = "본인확인 이용기관식별자 PREFIX"     // 8자이내 영대소문자,숫자 (예) MOK, TESTCOKR
    
    /* 본인확인 표준창 인증요청 함수 예제 */
    app.post(requestUri, (req, res) => {
        /* 1. 본인확인-표준창 거래요청정보 생성  */
    
        /* 1.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
        // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
        // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
        let sampleClientTxId = clientPrefix + uuid();
    
        /* 1.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
        // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
        // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
    
        /* 1.3 본인확인-표준창 거래요청정보 생성  */
        const clientTxId = sampleClientTxId + "|" + getCurrentDate();
    
        /* 1.4 본인확인-표준창 거래요청정보 암호화 */
        const encClientTxId = mobileOK.RSAEncrypt(clientTxId);
    
        /* 1.5 본인확인-표준창 거래요청정보 설정 */
        const authRequestObject = {
            /* 본인확인 서비스 용도 */
            /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
            'usageCode' : '01001'
            /* 본인확인 서비스 ID */  
            , 'serviceId' : mobileOK.getServiceId()
            /* 암호화된 본인확인 거래 요청 정보 */
            , 'encryptReqClientInfo' : encClientTxId
            /* 이용상품 코드 */
            /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "SMS")*/
            /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 "LMS")*/
            , 'serviceType' : 'telcoAuth'
            /* 본인확인 결과 타입 */
            /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */
            , 'retTransferType' : 'MOKToken'
            /* 본인확인 결과 수신 URL */
            , 'returnUrl' : resultUrl
        };
    
        /* 1.6 거래 요청 정보 JSON 반환 */
        res.send(JSON.stringify(authRequestObject));
    })
    
    /* 본인확인 표준창 인증결과 함수 예제 */
    app.post(resultUri, async (req, res) => {
        /* 1. 본인확인 결과 타입 설정 */
        const resultRequestString = req.body;
        const resultRequestJson = urlencode.decode(resultRequestString.data);
        const resultRequestObject = JSON.parse(resultRequestJson);
    
        /* 2. 본인확인 결과 타입별 결과 요청 */
        let encryptMOKResult;
        if (resultRequestObject.encryptMOKKeyToken != null) {
            /* 2.1 본인확인 결과 타입 : MOKToken */
            /* 2.1.1 본인확인 결과요청 입력정보 설정 */
            const authResultRequestObject = { encryptMOKKeyToken : resultRequestObject.encryptMOKKeyToken };
            /* 2.1.2 본인확인 결과요청 */
            const resultResponseObject = await sendPost(MOK_RESULT_REQUEST_URL, authResultRequestObject);
            try {
                if (typeof resultResponseObject == 'undefined') {
                    throw MOKException;
                }
            } catch(MOKException) {
                return res.send('-0|본인확인 서버통신(결과요청)에 실패했습니다.');
            }
            encryptMOKResult = resultResponseObject.encryptMOKResult;
    
            /* 2.1.3 본인확인 결과요청 실패시 */
            if (resultResponseObject.resultCode != '2000') {
                console.log('본인확인 결과요청에 실패했습니다.');
                return res.send(resultResponseObject.resultCode + ', ' + resultResponseObject.resultMsg);
            }
        } else {
            return res.send('-1|본인확인 MOKToken 인증결과 응답이 없습니다.');
        }
    
        // 'encryptMOKResult'가 없을 경우 오류 처리
        try {
            if (encryptMOKResult == null || encryptMOKResult == '' || typeof encryptMOKResult == undefined) {
                throw MOKException;
            }
        } catch (MOKException) {
            return res.send('-1|본인확인 MOKToken 가 없습니다.');
        }
    
        // encryptMOKResult 복호화
        let decryptMOKResultJson = null;
        try {
            decryptMOKResultJson = mobileOK.getResult(encryptMOKResult);
        } catch(error) {
            console.log(error);
            return res.send('-3|본인확인 결과 복호화 오류');
        }
    
        /* 3. 본인확인 결과정보 변환 */
        /* 3-1 본인확인 결과정보 복호화 */
        const decryptMOKResultObject = JSON.parse(decryptMOKResultJson);
    
        /* 3-2 본인확인 결과정보 설정 */
        /* 사용자 이름 */
        let userName = '';
        if (decryptMOKResultObject.hasOwnProperty("userName")) {
            userName = decryptMOKResultObject.userName;
        }
        /* 이용기관 ID */
        let siteId = '';
        if (decryptMOKResultObject.hasOwnProperty("siteId")) {
            siteId = decryptMOKResultObject.siteId;
        }
        /* 이용기관 거래 ID */
        let clientTxId = '';
        if (decryptMOKResultObject.hasOwnProperty("clientTxId")) {
            clientTxId = decryptMOKResultObject.clientTxId;
        }
        /* 본인확인 거래 ID */
        let txId = '';
        if (decryptMOKResultObject.hasOwnProperty("txId")) {
            txId = decryptMOKResultObject.txId;
        }
        /* 서비스제공자(인증사업자) ID */
        let providerId = '';
        if (decryptMOKResultObject.hasOwnProperty("providerId")) {
            providerId = decryptMOKResultObject.providerId;
        }
        /* 이용 서비스 유형 */
        let serviceType = '';
        if (decryptMOKResultObject.hasOwnProperty("serviceType")) {
            serviceType = decryptMOKResultObject.serviceType;
        }
        /* 사용자 CI */
        let ci = '';
        if (decryptMOKResultObject.hasOwnProperty("ci")) {
            ci = decryptMOKResultObject.ci;
        }
        /* 사용자 DI */
        let di = '';
        if (decryptMOKResultObject.hasOwnProperty("di")) {
            di = decryptMOKResultObject.di;
        }
        /* 사용자 전화번호 */
        let userPhone = '';
        if (decryptMOKResultObject.hasOwnProperty("userPhone")) {
            userPhone = decryptMOKResultObject.userPhone;
        }
        /* 사용자 생년월일 */
        let userBirthday = '';
        if (decryptMOKResultObject.hasOwnProperty("userBirthday")) {
            userBirthday = decryptMOKResultObject.userBirthday;
        }
        /* 사용자 성별 (1: 남자, 2: 여자) */
        let userGender = '';
        if (decryptMOKResultObject.hasOwnProperty("userGender")) {
            userGender = decryptMOKResultObject.userGender;
        }
        /* 사용자 국적 (0: 내국인, 1: 외국인) */
        let userNation = '';
        if (decryptMOKResultObject.hasOwnProperty("userNation")) {
            userNation = decryptMOKResultObject.userNation;
        }
        /* 본인확인 인증 종류 */
        const reqAuthType = decryptMOKResultObject.reqAuthType;
        /* 본인확인 요청 시간 */
        const reqDate = decryptMOKResultObject.reqDate;
        /* 본인확인 인증 서버 */
        const issuer = decryptMOKResultObject.issuer;
        /* 본인확인 인증 시간 */
        const issueDate = decryptMOKResultObject.issueDate;
    
    
        /* 4. 수신결과 clientTxId 와 세션에 저장한 clientTxId 가 동일한지 비교(권고, 세션서버 및 DB등을 통한 검증) */
    
        /* 요청 세션검증 이용기관 구현 */
    
        /* 검증정보 유효시간 검증 (검증결과 생성 후 10분 이내 검증 권고) */
        let oldDate = new Date(issueDate);
        oldDate = getOldTime(oldDate);
    
        const currentDate = getCurrentDate();
    
        if (oldDate < currentDate) {
            return res.send('-5|토큰 생성 10분 결과');
        }
    
    
        /* 5. 이용기관 서비스 기능 처리 */
    
        // - 이용기관에서 수신한 개인정보 검증 확인 처리
    
        // - 이용기관에서 수신한 CI 확인 처리
    
        /* 6. 본인확인 결과 응답 */
    
        // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
        // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
    
        let data = {
            'errorCode' : '2000'
            , 'resultMsg' : '성공'
            , 'data' : userName
        };
    
        /* 6. 본인확인 결과 응답 방식 */
        /* 6.1 : 팝업창(Pop-Up) : callback 유 */
        /* 6.1-1 팝업창(Pop-Up) 결과반환 */
        res.send(data);
    
        /* 6.2 : 페이지 이동(Redirect) : callback 무 */
        /* 6.2-1 이동페이지(Redirect Page) 설정 */
        // res.redirect(url.format({
        //     pathname:"https://이용기관 본인확인-표준창 인증요청 처리 (Vue)URL/redirect",
        //     query: {
        //        "data": JSON.stringify(data),
        //      }
        //   }));
    });
    
    /* 거래 ID(uuid) 생성 예제 함수 */
    function uuid() {
        return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    
            return v.toString(16);
        });
    }
    
    /* 본인확인 거래 ID(요청 시간) 생성 예제 함수 */
    function getCurrentDate() {
        let newDate = new Date();
        newDate.toLocaleString('ko-kr');
    
        let year = newDate.getFullYear();
        let mon = newDate.getMonth() + 1;
        let date = newDate.getDate();
    
        let hour = newDate.getHours();
        let min = newDate.getMinutes();
        let sec = newDate.getSeconds();
    
        mon = mon < 10 ? `0${mon}` : `${mon}`;
        date = date < 10 ? `0${date}` : `${date}`;
        hour = hour < 10 ? `0${hour}` : `${hour}`;
        min = min < 10 ? `0${min}` : `${min}`;
        sec = sec < 10 ? `0${sec}` : `${sec}`;
    
        const reqDate = year + mon + date + hour + min + sec;
    
        return reqDate;
    }
    
    function getOldTime(oldTime) {
        let year = oldTime.getFullYear();
        let mon = oldTime.getMonth() + 1;
        let date = oldTime.getDate();
    
        let hour = oldTime.getHours();
        let min = oldTime.getMinutes()+ 10;
        let sec = oldTime.getSeconds();
    
        if (min >= 60) {
            min = min - 60;
    
            hour = hour + 1;
        }
        if (hour >= 24) {
            hour = hour - 24;
    
            date = date + 1;
        }
        if (date > new Date(year, mon, 0).getDate()) {
            date = date - (new Date(year, mon, 0).getDate());
    
            mon = mon + 1;
        }
        if (mon >= 13) {
            mon = mon - 12;
    
            year = year + 1;
        }
    
        mon = mon < 10 ? `0${mon}` : `${mon}`;
        date = date < 10 ? `0${date}` : `${date}`;
        hour = hour < 10 ? `0${hour}` : `${hour}`;
        min = min < 10 ? `0${min}` : `${min}`;
        sec = sec < 10 ? `0${sec}` : `${sec}`;
    
        const reqDate = year + mon + date + hour + min + sec;
    
        return reqDate;
    }
    
    /* 본인확인 서버 통신 예제 함수 */
    async function sendPost(targetUrl, encryptMOKKeyToken) {
        try {
            let responseData = await axios ({
                method : 'post',
                url : targetUrl,
                data : encryptMOKKeyToken
            });
    
            return responseData.data;
        } catch (AxiosError) {
            console.log('본인확인 서버 통신URL이 잘 못 되었습니다.');
        }
    }
    
    mok_std_request.aspx
    1
    2
    3
    <%@ Page Language="C#" Async="true" AutoEventWireup="true" CodeBehind="mok_std_request.aspx.cs" Inherits="mok_std_request"%>
    <%@ Import Namespace="System" %>
    <%=result%>
    
    mok_std_request.aspx.cs
    using System;
    using System.IO;
    using System.Web;
    using System.Web.UI;
    using mokcrypto;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    public partial class mok_std_request : Page
    {
        protected string result = "";
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
    
                /*  본인확인 서비스 API 설정 */
                MobileOkKeyManager mobileOK = new MobileOkKeyManager();
                /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
                mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
    
                // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정, 이용기관식별자는 이용기관코드 영문자로 반드시 수정
                string PREFIX_ID = "본인확인 이용기관식별자 PREFIX";  // 8자이내 영대소문자,숫자 (예) MOK, TESTCOKR
                /* 거래 정보 응답 */
                result = REDmobileOK_request(mobileOK, PREFIX_ID);
            }
            catch (MobileOKException ex)
            {
                Console.Write(ex.Message);
            }
        }
    
        protected string REDmobileOK_request(MobileOkKeyManager mobileOK, string clientPrefix)
        {
    
            /* 1. 본인확인-표준창 거래요청정보 생성  */
    
            /* 1.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
            // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
            // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
            string randomClientId = clientPrefix + Guid.NewGuid().ToString("N");
            string clientTxId = randomClientId;
    
            /* 1.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
            // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
            // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
            HttpContext.Current.Session["sessionClientTxId"] = randomClientId;
    
            /* 1.3 거래 ID, 인증 시간을 통한 본인확인 거래 요청 정보 생성  */
            DateTime dow = DateTime.Now;
            string formattedDate = dow.ToString("yyyyMMddHHmmss");
            string reqClientInfo = clientTxId + "|" + formattedDate;
    
            /* 1.4 생성된 거래정보 암호화 */
            string encryptReqClientInfo = "";
            try
            {
                encryptReqClientInfo = mobileOK.RSAEncrypt(reqClientInfo);
            }
            catch (MobileOKException e)
            {
                alertASPX(e.Message);
            }
    
            /* 1.5 거래 요청 정보 JSON 생성 */
            dynamic jsonObject = new JObject();
    
            /* 이용상품 코드 */
            /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 “SMS”)*/
            /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 “LMS”)*/
            jsonObject["serviceType"] = "telcoAuth";
            /* 본인확인 서비스 용도 */
            /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
            jsonObject["usageCode"] = "01001";
            /* 본인확인 서비스 ID */
            jsonObject["serviceId"] = mobileOK.ServiceId;
            /* 암호화된 본인확인 거래 요청 정보 */
            jsonObject["encryptReqClientInfo"] = encryptReqClientInfo;
            /* 본인확인 결과 타입 */
            /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */
            jsonObject["retTransferType"] = "MOKToken";
    
            /* 본인확인 결과 수신 URL - https:// 포함한 URL 입력 */
            /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
            jsonObject["returnUrl"] = "https://이용기관URL/mok_std_result.aspx";
    
            return jsonObject.ToString();
        }
    
        private void alertASPX(string errorMsg)
        {
            string script = "window.onload = function() { alert('" + errorMsg + "'); };";
            Page.ClientScript.RegisterStartupScript(this.GetType(), "alert", script, true);
        }
    }
    
    RequestController.cs
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using mokcrypto;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Net.Http;
    using System.Threading.Tasks;
    
    namespace Standard.Controllers
    {
        public class RequestController : Controller
        {
    
            [HttpPost]
            public IActionResult mobileOK_std_request()
            {
                /* 본인확인 서비스 API 설정 */
                try
                {
                    /* 본인확인 키파일을 통한 비밀키 설정 */
                    MobileOkKeyManager mobileOK = new MobileOkKeyManager();
    
                    /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
                    mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
    
                    // 이용기관 거래ID생성시 이용기관별 유일성 보장을 위해 설정, 이용기관식별자는 이용기관코드 영문자로 반드시 수정
                    string PREFIX_ID = "본인확인 이용기관식별자 PREFIX";  // 8자이내 영대소문자,숫자 (예) MOK, TESTCOKR
                    /*3. 거래 정보 응답 */
                    ViewData["message"] = mobileOK_request(mobileOK, PREFIX_ID);
                }
                catch (MobileOKException ex)
                {
                    ViewData["message"] = ex.Message;
                }
    
                return View();
            }
    
            private string mobileOK_request(MobileOkKeyManager mobileOK, string clientPrefix)
            {
                /* 1. 본인확인-표준창 거래요청정보 생성  */
    
                /* 1.1 이용기관 거래ID 생성, 20자 이상 40자 이내 이용기관 고유 트랜잭션ID (예시) 이용기관식별자+UUID, ...  */
                // - 본인확인-표준창 거래ID 는 유일한 값이어야 하며 기 사용한 거래ID가 있는 경우 오류 발생 
                // - 이용기관이 고유식별 ID로 유일성을 보장할 경우 고객이 이용하는 ID사용 가능 
                string randomClientId = clientPrefix + Guid.NewGuid().ToString("N");
                string clientTxId = randomClientId;
    
                /* 1.2 인증 결과 검증을 위한 거래 ID 세션 저장 */
                // 동일한 세션내 요청과 결과가 동일한지 확인 및 인증결과 재사용 방지처리, 응답결과 처리 시 필수 구현
                // 세션 내 거래ID를 저장하여 검증하는 방법은 권고 사항이며, 이용기관 저장매체(DB 등)에 저장하여 검증 가능
                HttpContext.Response.Cookies.Append("sessionClientTxId", clientTxId); 
    
                /* 1.3 거래 ID, 인증 시간을 통한 본인확인 거래 요청 정보 생성  */
                DateTime dow = DateTime.Now;
                string formattedDate = dow.ToString("yyyyMMddHHmmss");
                string reqClientInfo = clientTxId + "|" + formattedDate;
                /* 1.4 생성된 거래정보 암호화 */
                string encryptReqClientInfo = "";
                try
                {
                    encryptReqClientInfo = mobileOK.RSAEncrypt(reqClientInfo);
                }
                catch (MobileOKException e)
                {
                    return e.Message;
                }
    
                /* 1.5 거래 요청 정보 JSON 생성 */
                dynamic jsonObject = new JObject();
                /* 본인확인 서비스 용도 */
                /* 01001 : 회원가입, 01002 : 정보변경, 01003 : ID찾기, 01004 : 비밀번호찾기, 01005 : 본인확인용, 01006 : 성인인증, 01007 : 상품구매/결제, 01999 : 기타 */
                jsonObject["usageCode"] = "01001";
                /* 본인확인 서비스 ID */
                jsonObject["serviceId"] = mobileOK.ServiceId;
                /* 암호화된 본인확인 거래 요청 정보 */
                jsonObject["encryptReqClientInfo"] = encryptReqClientInfo;
                /* 이용상품 코드 */
                /* 이용상품 코드, telcoAuth : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 “SMS”)*/
                /* 이용상품 코드, telcoAuth-LMS : 휴대폰본인확인 (SMS인증시 인증번호 발송 방식 “LMS”)*/
                jsonObject["serviceType"] = "telcoAuth";
                /* 본인확인 결과 타입 */
                /* 본인확인 결과 타입, "MOKToken"  : 개인정보 응답결과를 이용기관 서버에서 본인확인 서버에 요청하여 수신 후 처리 */
                jsonObject["retTransferType"] = "MOKToken";
                /* 팝업 : 본인확인 결과 수신 URL - "https://" 포함한 URL 입력 */
                /* 이동 : 본인확인 결과 수신 URL, 결과 페이지 */
                /* 결과 전달 URL 내에 개인정보 포함을 절대 금지합니다.*/
                jsonObject["returnUrl"] = "https://이용기관URL/mobileOK_std_result";
    
                return jsonObject.ToString();
            }
        }
    }
    
    mobileOK_std_request.cshtml
    @Html.Raw(ViewData["message"])
    

6. 본인확인-표준창 검증결과 요청

본인확인-표준창 결과를 수신하여 본인확인-표준창 요청시 수신 URL("resultUrl")로 결과를 전달 합니다.

  • 본인확인-표준창 인증결과 처리 준비 사항

    • 본인확인-표준창 암복호화 키정보 파일

    • 본인확인-표준창 키정보 파일 패스워드

  • 본인확인-표준창 결과 수신 모드

    • MOKToken 방식

      1. (이용기관) MOKToken 응답 -> (본인확인-표준창 사용자 브라우져)

      2. (본인확인-표준창 사용자 브라우져) MOKToken 응답 -> (이용기관)

      3. (이용기관) MOKToken 요청 -> (본인확인서버)

      4. (본인확인서버) 암호화된 개인정보 MOKResult 응답 -> (이용기관)

      5. (이용기관) 개인정보 복호화

  • 본인확인-표준창 검증요청 API 응답

    • 본인확인-표준창 결과 JSON 설명

      속성 필수여부
      resultCode 응답 결과 코드
      - 2000일 경우 성공
      - 2000이 아닐 경우 에러처리
      resultMsg resultCode 가 2000이 아닐 경우 에러 메시지
      serviceId 본인확인-표준창 이용기관 서비스 ID
      encryptMOKKeyToken 검증결과 요청타입이 MOKToken 일때 응답값
      1. MOKToken 모드 본인확인-표준창 결과 응답 JSON 예시
        1. 본인확인 서버 -> 본인확인 표준창 (사용자 브라우져)
          • 결과 Content-Type : application/json
          • 응답데이터
            {
                "resultCode": "2000",
                "resultMsg": "success",
                "encryptMOKKeyToken": "[L0F/pYaV4NZLJHGkT/ffIOVVrEuvKHBpHlWI3KfeqarwXXt33oLYyBB5MZxhS/VXGwa8JPRECUVxRoHpPZ6oByFfRqkgDI7QT2HtegxT7baQ8...fB0PLlw2pRbOvm4xJg0UTNL"
            }
            
        2. 본인확인 표준창 (사용자 브라우져) -> 이용기관 응답 URL
          • 결과 Content-Type : text/plain
          • HTTP Body
            data=%257B%2522encryptMOKKeyToken%2522%253A%2522%255BssyPQXqt2%252BvA4NXesbUqSOrW2RZwctzmJD0pXLfuFGUD2QG4k...%252F8KsyGpJs7y111ZnGD1xpEeYxEsRFUCwOBWOYBH9xReI1z8bWRTLlc5HRyugJyTGTXaOKOTCkTLyxtMZ0nQSSBlJT%252FHIRDwb%252F4Doyf86lgQazTmbG%252FMFa8C1rPhCXUu1Tl4Vbnf5VN6Xip8KZDZyK49xf%252FMSc7Ot5ZiPllCM%253D%2522%252C%2522resultCode%2522%253A%25222000%2522%252C%2522resultMsg%2522%253A%2522success%2522%257D
            
  • MOKToken 본인확인-표준창 결과 API 응답시 MOKResult 요청 및 응답

    • 본인확인- 표준창 결과 API 요청 URL 및 인증요청 정보

      • URL

        • 본인확인-표준창 인증요청

          • 운영 : https://cert.mobile-ok.com/gui/service/v1/result/request

          • 개발 : https://scert.mobile-ok.com/gui/service/v1/result/request

        • HTTPS 암호화 통신 : TLS 1.2 이상

        • HTTP 메소드 : POST

        • Charset : utf-8

    • MOKToken 본인확인-표준창 결과 수신시 본인확인-표준창 MOKResult 결과 요청

      속성 필수여부
      encryptMOKKeyToken 검증결과 요청타입이 MOKToken 일때 응답값
      • MOKToken 수신시 본인확인-표준창 MOKResult 요청 JSON 예시

        {
            "encryptMOKKeyToken": "[L0F/pYaV4NZLJHGkT/ffIOVVrEuvKHBpHlWI3KfeqarwXXt33oLYyBB5MZxhS/VXGwa8JPRECUVxRoHpPZ6oByFfRqkgDI7QT2HtegxT7baQ8...fB0PLlw2pRbOvm4xJg0UTNL"
        }
        
    • 본인확인-표준창 결과 JSON과 동일한 결과 수신

      • MOKResult 본인확인-표준창 결과 API 응답 JSON 예시

        {
            "resultCode": "2000",
            "resultMsg": "success",
            "serviceId": "4a361beb-4347-4d8d-a2bf-1380216dba1a",
            "encryptMOKResult": "OVbBlXiYrjmJ/9xGVtiFKQ+hRe5qXwHHmcNAWMknbuJ5+NjNHiL9jxVLZ3tyNEUbQ5ffWibcOJ8xUjyo7K0M...//oZnyVUCbh/VQofkUOuZcfZvm9no/GZafOYB26gLZIp0C1qdK8YKM0Er1rcQ=",
        }
        

7. 본인확인-표준창 검증결과 복호화

본인확인-표준창 결과로 수신받은 검증결과 encryptMOKResult을 이용기관 전용 비밀키로 복호화 하고 이름, 전화번호, 생년월일, CI, DI 등의 암호화된 개인정보를 획득 합니다.

이용기관에서 수신한 개인정보에 대한 검증 처리 안내

  • 이용기관에서 사전에 수집한 개인정보가 있는 경우, 본인확인을 통해 수신 후 복호화한 개인정보와 반드시 일치 여부를 검증하여야 함
  • 본인확인-표준창 결과 복호화 JSON 정보

    ID 내용
    siteId 이용기관(이용기관)이 사이트 ID
    clientTxId 이용기관(이용기관)이 발급한 거래 ID
    txId 휴대폰본인확인서버가 발급한 거래 ID
    providerId 사용자 이동통신사 구분 ID
    - "SKT"
    - "KT"
    - "LGU"
    - "SKTMVNO"
    - "KTMVNO"
    - "LGUMVNO"
    serviceType 본인확인 요청 서비스 타입
    ci 주민등록번호 대체 개인 식별 연동정보 CI(Connecting Information)
    di 이용기관 중복 확인 정보 DI(Duplication Information)
    userName 사용자 이름
    userPhone 사용자 전화번호
    userBirthday 사용자 생년월일
    userGender 사용자 성별
    - "1" : 남자
    - "2": 여자
    userNation 사용자 내외국인 정보
    - "0" : 내국인
    - "1": 외국인
    reqdate 본인확인 거래요청시간
    issuer 본인확인 처리 서버 ID
    issueDate 발급일 (yyyy-mm-dd hh:mm:ss.mis)
  • 본인확인-표준창 결과 복호화 JSON 예시

    {
        "siteId" : "CPID0001",
        "clientTxId" : "MOK221209170943157761", 
        "txId" : "f0aea999-2a69-4fc6-b02b-acda6f2993ff",
        "providerId" : "SKT",
        "serviceType" : "telcoAuth",
        "ci" : "lJG65/ma30qVmWY0/....591olSaU3HnDn3MT9czsKmoA==", 
        "di" : "MC0GCCq.....RMBkvnuajLHk=", 
        "userName" : "홍길동", 
        "userPhone" : "01012345678",
        "userBirthday" : "20000101", 
        "userGender" : "1", 
        "userNation" : "0", 
        "reqdate" : "221209170943",
        "issuer" : "MobileOK Agent1", 
        "issueDate" : "2022-12-12 13:34:12.234"
    }
    
  • 본인확인-표준창 결과 처리 예제

    mok_std_result.jsp
    <%@ page import="java.net.HttpURLConnection" %>
    <%@ page import="java.net.URL" %>
    <%@ page import="java.io.*" %>
    <%@ page import="java.util.Date"%>
    <%@ page import="java.text.SimpleDateFormat"%>
    <%@ page import="com.dreamsecurity.mobileOK.mobileOKKeyManager" %>
    <%@ page import="com.dreamsecurity.json.JSONObject" %>
    <%@ page import="java.util.Base64" %>
    <%@ page import="com.dreamsecurity.mobileOK.MobileOKException" %>
    <%@ page import="java.net.URLDecoder" %>
    <%@ page import="java.nio.charset.StandardCharsets" %>
    
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%!
        private BufferedReader bufferedReader;
    
        public String mobileOK_std_result(String result, mobileOKKeyManager mobileOK, HttpSession session) {
            try {
                /* 1. 본인확인 인증결과 MOKToken API 요청 URL */
                String targetUrl = "https://scert.mobile-ok.com/gui/service/v1/result/request";  // 개발
                // String targetUrl = "https://cert.mobile-ok.com/gui/service/v1/result/request";  // 운영
    
                /* 2. 본인확인 결과 타입별 결과 처리 */
                JSONObject resultJSON = new JSONObject(result);
                String encryptMOKKeyToken = resultJSON.optString("encryptMOKKeyToken", null);
                String encryptMOKResult = null;
                /* 2.1 본인확인 결과 타입 : MOKToken */
                if (encryptMOKKeyToken != null) {
                    JSONObject requestData = new JSONObject();
                    requestData.put("encryptMOKKeyToken", encryptMOKKeyToken);
                    String responseData = sendPost(targetUrl, requestData.toString());
                    if (responseData == null) {
                        return "-1|본인확인 MOKToken 인증결과 응답이 없습니다.";
                    }
                    JSONObject responseJSON = new JSONObject(responseData);
                    encryptMOKResult = responseJSON.getString("encryptMOKResult");
                }
                else {
                    return "-1|본인확인 MOKToken 가 없습니다.";
                }
    
                /* 3. 본인확인 결과 JSON 정보 파싱 */
                JSONObject decrpytResultJson = null;
                try {
                    decrpytResultJson = new JSONObject(mobileOK.getResultJSON(encryptMOKResult));
                } catch (MobileOKException e) {
                    return e.getErrorCode() + "|" + e.getMessage();
                }
    
                /* 4. 본인확인 결과 복호화 */
    
                /* 이용기관 거래 ID */
                String clientTxId = decrpytResultJson.optString("clientTxId", null);
    
                String sessionClientTxId = (String) session.getAttribute("sessionClientTxId");
                // 세션 내 요청 clientTxId 와 수신한 clientTxId 가 동일한지 반드시 비교
                if (!sessionClientTxId.equals(clientTxId)) {
                    return "-4|세션값에 저장된 거래ID 비교 실패";
                }
    
                /* 사용자 이름 */
                String userName = decrpytResultJson.optString("userName", null);
                /* 이용기관 ID */
                String siteId = decrpytResultJson.optString("siteId", null);
                /* 본인확인 거래 ID */
                String txId = decrpytResultJson.optString("txId", null);
                /* 서비스제공자(인증사업자) ID */
                String providerId = decrpytResultJson.optString("providerId", null);
                /* 이용 서비스 유형 */
                String serviceType = decrpytResultJson.optString("serviceType", null);
                /* 사용자 CI */
                String ci = decrpytResultJson.optString("ci", null);
                /* 사용자 DI */
                String di = decrpytResultJson.optString("di", null);
                /* 사용자 전화번호 */
                String userPhone = decrpytResultJson.optString("userPhone", null);
                /* 사용자 생년월일 */
                String userBirthday = decrpytResultJson.optString("userBirthday", null);
                /* 사용자 성별 (1: 남자, 2: 여자) */
                String userGender = decrpytResultJson.optString("userGender", null);
                /* 사용자 국적 (0: 내국인, 1: 외국인) */
                String userNation = decrpytResultJson.optString("userNation", null);
                /* 본인확인 인증 종류 */
                String reqAuthType = decrpytResultJson.getString("reqAuthType");
                /* 본인확인 요청 시간 */
                String reqDate = decrpytResultJson.getString("reqDate");
                /* 본인확인 인증 서버 */
                String issuer = decrpytResultJson.getString("issuer");
                /* 본인확인 인증 시간 */
                String issueDate = decrpytResultJson.getString("issueDate");
    
    
                /* 5. 이용기관 응답데이터 셔션 및 검증유효시간 처리  */
    
                // 검증정보 유효시간 검증 (본인확인 결과인증 후 10분 이내 검증 권고) */
                String dataFormat = "yyyy-MM-dd HH:mm:ss";
                SimpleDateFormat formatter = new SimpleDateFormat(dataFormat);
    
                Date currentTime = formatter.parse(formatter.format(new Date()));
                Date targetTime = formatter.parse(issueDate);
    
                long diff = (currentTime.getTime() - targetTime.getTime()) / 1000;
                if (diff > 600) {
                    return "-5|검증결과 토큰 생성 10분 경과 오류";
                }
    
                /* 6. 이용기관 서비스 기능 처리 */
    
                // - 이용기관에서 수신한 개인정보 검증 확인
    
                // - 이용기관에서 수신한 CI 확인
    
                /* 7. 본인확인 결과 응답 */
    
                // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
                // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
    
                JSONObject outputJson = new JSONObject();
                outputJson.put("resultCode", "2000");
                outputJson.put("resultMsg", "성공");
                outputJson.put("userName", userName);
                return outputJson.toString();
            } catch (Exception e) {
                e.printStackTrace();
                return "-999|서버 오류";
            }
        }
    
        /* 본인확인 서버 통신 예제 함수 */
        public String sendPost(String dest, String jsonData) {
            HttpURLConnection connection = null;
            DataOutputStream dataOutputStream = null;
            try {
                URL url = new URL(dest);
                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
                connection.setDoOutput(true);
    
                dataOutputStream = new DataOutputStream(connection.getOutputStream());
                dataOutputStream.write(jsonData.getBytes("UTF-8"));
    
                bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuffer responseData = new StringBuffer();
                String info;
                while ((info = bufferedReader.readLine()) != null) {
                    responseData.append(info);
                }
                return responseData.toString();
            } catch (FileNotFoundException e) {
                // Error Stream contains JSON that we can parse to a FB error
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
    
                    if (dataOutputStream != null) {
                        dataOutputStream.close();
                    }
    
                    if (connection != null) {
                        connection.disconnect();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    %>
    
    <%
        /* 2. 본인확인 서비스 API 설정 */
        mobileOKKeyManager mobileOK = null;
        String data = null;
        try {
            mobileOK = new mobileOKKeyManager();
            /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
            mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
            /* 3. 본인확인 인증 결과 암호문 수신 */
            data = request.getParameter("data");
            data = URLDecoder.decode(data, "UTF-8");
        } catch (MobileOKException e) {
            out.write(e.getErrorCode() + "|" + e.getMessage());
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    %>
    
    <%-- 4. 본인확인 결과 응답 방식 --%>
    <%-- 4.1 : 팝업창 : callback 함수 사용  --%>
    <%= mobileOK_std_result(data, mobileOK, session) %>
    <%-- 4.2 : 페이지 이동 : redirect 방식, 이용기관 지정 페이지로 이동 --%>
    <%--
    <form method="post" action="https://이용기관 URL/mok/result_page.jsp">
        <textarea style="width:500px; height: 500px" name="data">
            <%= mobileOK_std_result(data, mobileOK, session) %>
        </textarea>
    </form>
    --%>
    
    mok_std_result.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    
    <%@ page import="javax.net.ssl.HttpsURLConnection"%>
    <%@ page import="java.net.URL" %>
    <%@ page import="java.io.*" %>
    <%@ page import="java.util.Date"%>
    <%@ page import="java.text.SimpleDateFormat"%>
    <%@ page import="com.dreamsecurity.mobileOK.mobileOKKeyManager" %>
    <%@ page import="com.dreamsecurity.json.JSONObject" %>
    <%@ page import="com.dreamsecurity.mobileOK.MobileOKException" %>
    <%@ page import="java.net.URLDecoder" %>
    <%@ page import="javax.net.ssl.SSLContext"%>
    <%@ page import="java.security.Security"%>
    <%@ page import="java.security.SecureRandom"%>
    <%@ page import="org.bouncycastle.jce.provider.BouncyCastleProvider"%>
    <%@ page import="org.bouncycastle.jsse.provider.BouncyCastleJsseProvider"%>
    
    <%!
        private BufferedReader bufferedReader;
    
        public String mobileOK_std_result(String result, mobileOKKeyManager mobileOK, HttpSession session) {
    
            try {
                /* 1. 본인확인 인증결과 MOKToken API 요청 URL */
                String targetUrl = "https://scert.mobile-ok.com/gui/service/v1/result/request";  // 개발
                // String targetUrl = "https://cert.mobile-ok.com/gui/service/v1/result/request";  // 운영
    
                /* 2. 본인확인 결과 타입별 결과 처리 */
                JSONObject resultJSON = new JSONObject(result);
                String encryptMOKKeyToken = resultJSON.optString("encryptMOKKeyToken", null);
                String encryptMOKResult = null;
                /* 2.1 본인확인 결과 타입 : MOKToken */
                if (encryptMOKKeyToken != null) {
                    JSONObject requestData = new JSONObject();
                    requestData.put("encryptMOKKeyToken", encryptMOKKeyToken);
                    String responseData = sendPost(targetUrl, requestData.toString());
                    if (responseData == null) {
                        return "-1|본인확인 MOKToken 인증결과 응답이 없습니다.";
                    }
                    JSONObject responseJSON = new JSONObject(responseData);
                    encryptMOKResult = responseJSON.getString("encryptMOKResult");
                }
                else {
                    return "-1|본인확인 MOKToken 가 없습니다.";
                }
    
                /* 3. 본인확인 결과 JSON 정보 파싱 */
                JSONObject decrpytResultJson = null;
                try {
                    decrpytResultJson = new JSONObject(mobileOK.getResultJSON(encryptMOKResult));
                } catch (MobileOKException e) {
                    return e.getErrorCode() + "|" + e.getMessage();
                }
    
                /* 4. 본인확인 결과 복호화 */
                /* 이용기관 거래 ID */
                String clientTxId = decrpytResultJson.optString("clientTxId", null);
    
                // 세션 내 요청 clientTxId 와 수신한 clientTxId 가 동일한지 반드시 비교
                String sessionClientTxId = (String) session.getAttribute("sessionClientTxId");
                if (!sessionClientTxId.equals(clientTxId)) {
                    return "-4|세션값에 저장된 거래ID 비교 실패";
                }
    
                /* 사용자 이름 */
                String userName = decrpytResultJson.optString("userName", null);
                /* 이용기관 ID */
                String siteId = decrpytResultJson.optString("siteId", null);
                /* 본인확인 거래 ID */
                String txId = decrpytResultJson.optString("txId", null);
                /* 서비스제공자(인증사업자) ID */
                String providerId = decrpytResultJson.optString("providerId", null);
                /* 이용 서비스 유형 */
                String serviceType = decrpytResultJson.optString("serviceType", null);
                /* 사용자 CI */
                String ci = decrpytResultJson.optString("ci", null);
                /* 사용자 DI */
                String di = decrpytResultJson.optString("di", null);
                /* 사용자 전화번호 */
                String userPhone = decrpytResultJson.optString("userPhone", null);
                /* 사용자 생년월일 */
                String userBirthday = decrpytResultJson.optString("userBirthday", null);
                /* 사용자 성별 (1: 남자, 2: 여자) */
                String userGender = decrpytResultJson.optString("userGender", null);
                /* 사용자 국적 (0: 내국인, 1: 외국인) */
                String userNation = decrpytResultJson.optString("userNation", null);
                /* 본인확인 인증 종류 */
                String reqAuthType = decrpytResultJson.getString("reqAuthType");
                /* 본인확인 요청 시간 */
                String reqDate = decrpytResultJson.getString("reqDate");
                /* 본인확인 인증 서버 */
                String issuer = decrpytResultJson.getString("issuer");
                /* 본인확인 인증 시간 */
                String issueDate = decrpytResultJson.getString("issueDate");
    
    
                /* 5. 이용기관 응답데이터 셔션 및 검증유효시간 처리  */
    
                // 검증정보 유효시간 검증 (본인확인 결과인증 후 10분 이내 검증 권고)
                String dataFormat = "yyyy-MM-dd HH:mm:ss";
                SimpleDateFormat formatter = new SimpleDateFormat(dataFormat);
    
                Date currentTime = formatter.parse(formatter.format(new Date()));
                Date targetTime = formatter.parse(issueDate);
    
                long diff = (currentTime.getTime() - targetTime.getTime()) / 1000;
                if( diff > 600 ) {
                    return "-5|검증결과 토큰 생성 10분 경과 오류";
                }
    
                /* 6. 이용기관 서비스 기능 처리 */
    
                // - 이용기관에서 수신한 개인정보 검증 확인
    
                // - 이용기관에서 수신한 CI 확인
    
                /* 7. 본인확인 결과 응답 */
    
                // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
                // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
    
                JSONObject outputJson = new JSONObject();
                outputJson.put("resultCode", "2000");
                outputJson.put("resultMsg", "성공");
                outputJson.put("userName", userName);
                return outputJson.toString();
            } catch (Exception e) {
                e.printStackTrace();
                return "-999|서버 오류";
            }
        }
    
        /* 본인확인 서버 통신 예제 함수 */
        public String sendPost(String dest, String jsonData) {
            HttpsURLConnection connection = null;
            DataOutputStream dataOutputStream = null;
            try {
                SSLContext sslContext = SSLContext.getInstance("TLSv1.2", new BouncyCastleJsseProvider());
                sslContext.init(null, null, new SecureRandom());
    
                URL url = new URL(dest);
                connection = (HttpsURLConnection) url.openConnection();
                connection.setSSLSocketFactory(sslContext.getSocketFactory());
    
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
                connection.setDoOutput(true);
    
                dataOutputStream = new DataOutputStream(connection.getOutputStream());
                dataOutputStream.write(jsonData.getBytes("UTF-8"));
    
                bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuffer responseData = new StringBuffer();
                String info;
                while ((info = bufferedReader.readLine()) != null) {
                    responseData.append(info);
                }
                return responseData.toString();
            } catch (FileNotFoundException e) {
                // Error Stream contains JSON that we can parse to a FB error
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
    
                    if (dataOutputStream != null) {
                        dataOutputStream.close();
                    }
    
                    if (connection != null) {
                        connection.disconnect();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    %>
    
    <%
    
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
            Security.addProvider(new BouncyCastleJsseProvider());
            System.setProperty("jdk.tls.trustNameService", "true");
        }
    
        /* 2. 본인확인 서비스 API 설정 */
        mobileOKKeyManager mobileOK = null;
        String data = null;
        try {
            mobileOK = new mobileOKKeyManager();
            /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
            mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
    
            /* 3. 본인확인 인증 결과 암호문 수신 */
            data = request.getParameter("data");
            data = URLDecoder.decode(data, "UTF-8");
        } catch (MobileOKException e) {
            out.write(e.getErrorCode() + "|" + e.getMessage());
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    %>
    
    <%-- 4. 본인확인 결과 응답 방식 --%>
    <%-- 4.1 : 팝업창 : callback 함수 사용  --%>
    <%= mobileOK_std_result(data, mobileOK, session) %>
    <%-- 4.2 : 페이지 이동 : redirect 방식, 이용기관 지정 페이지로 이동 --%>
    <%--
    <form method="post" action="https://이용기관 URL/mok/result_page.jsp">
        <textarea style="width:500px; height: 500px" name="data">
            <%= mobileOK_std_result(data, mobileOK, session) %>
        </textarea>
    </form>
    --%>
    
    mok_std_result.php
    <?php
        // 각 버전 별 맞는 mobileOKManager-php를 사용
        $mobileOK_path = "./mobileOK_manager_phpseclib_v3.0_v1.0.2.php";
    
        if(!file_exists($mobileOK_path)) {
            die('1000|mobileOK_Key_Manager파일이 존재하지 않습니다.');
        } else {
            require_once $mobileOK_path;
        }
    ?>
    
    <?php
        header("Content-Type:text/html;charset=utf-8");
    
        /* 1. 본인확인 인증결과 MOKToken API 요청 URL */
        $MOK_RESULT_REQUEST_URL = "https://scert.mobile-ok.com/gui/service/v1/result/request";  // 개발
        // $MOK_RESULT_REQUEST_URL = "https://cert.mobile-ok.com/gui/service/v1/result/request";  //운영
    
        // (/* 7.2 : 페이지 이동 : redirect 방식, 이용기관 지정 페이지로 이동 */) 이용시 이동 URL
        $MOK_RESULT_REDIRECT_URL = "https://이용기관 URL/mok/result_page.php";
    
        /* 2. 본인확인 서비스 API 설정 */
        $mobileOK = new mobileOK_Key_Manager();
        /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
        $key_path = "/본인확인 키정보파일 Path/mok_keyInfo.dat";
        $password = "키파일 패스워드";
        $mobileOK->key_init($key_path, $password);
    ?>
    
    <?php
        /* 본인확인 표준창 결과 요청 예제 함수 */
        function mobileOK_std_result($mobileOK, $MOK_RESULT_REQUEST_URL) {
            // local시간 설정이 다르게 될  수 있음으로 기본 시간 설정을 서울로 해놓는다.
            date_default_timezone_set('Asia/Seoul');
    
            /* 3. 본인확인 인증 결과 암호문 수신 */
            $request_array = $_POST['data'];
            $request_array = urldecode($request_array);
            $request_array = json_decode($request_array);
    
            /* 4. 본인확인 결과 타입별 결과 처리 */
            if (isset($request_array->encryptMOKKeyToken)) {
                /* 4.1 본인확인 결과 타입 : MOKToken */
                $encrypt_MOK_token = $request_array->encryptMOKKeyToken;
                $result_request_array = array(
                    "encryptMOKKeyToken" => $encrypt_MOK_token
                );
                $result_request_json = json_encode($result_request_array, JSON_UNESCAPED_SLASHES);
    
                $result_response_json = sendPost($result_request_json, $MOK_RESULT_REQUEST_URL);
                $result_response_array = json_decode($result_response_json);
    
                $encryptMOKResult = $result_response_array->encryptMOKResult;
            } else {
                die("-1|본인확인 MOKToken 인증결과 응답이 없습니다.");
            }
    
            /* 5. 본인확인 결과 JSON 정보 처리 */
            try {
                $decrypt_result_json = $mobileOK->get_result($encryptMOKResult);
                $decrypt_result_array = json_decode($decrypt_result_json);
            } catch (Exception $e) {
                return '-2|본인확인 결과 복호화 오류';
            }
    
            /* 5-1 본인확인 결과정보 복호화 */
    
            /* 이용기관 거래 ID */
            $client_tx_id = isset($decrypt_result_array->clientTxId) ? $decrypt_result_array->clientTxId : null;
    
            session_start();
            $session_client_tx_id = $_SESSION['sessionClientTxId'];
    
            // 세션 내 요청 clientTxId 와 수신한 clientTxId 가 동일한지 반드시 비교
            if ($session_client_tx_id !== $client_tx_id){
                echo '-4|세션값에 저장된 거래ID 비교 실패';
                return '';
            }
    
            /* 사용자 이름 */
            $user_name = isset($decrypt_result_array->userName) ? $decrypt_result_array->userName : null;
            /* 이용기관 ID */
            $site_id = isset($decrypt_result_array->siteId) ? $decrypt_result_array->siteId : null;
            /* 본인확인 거래 ID */
            $tx_id = isset($decrypt_result_array->txId) ? $decrypt_result_array->txId : null;
            /* 서비스제공자(인증사업자) ID */
            $provider_id = isset($decrypt_result_array->providerId) ? $decrypt_result_array->providerId : null;
            /* 이용 서비스 유형 */
            $service_type = isset($decrypt_result_array->serviceType) ? $decrypt_result_array->serviceType : null;
            /* 사용자 CI */
            $ci = isset($decrypt_result_array->ci) ? $decrypt_result_array->ci : null;
            /* 사용자 DI */
            $di = isset($decrypt_result_array->di) ? $decrypt_result_array->di : null;
            /* 사용자 전화번호 */
            $user_phone = isset($decrypt_result_array->userPhone) ? $decrypt_result_array->userPhone : null;
            /* 사용자 생년월일 */
            $user_birthday = isset($decrypt_result_array->userBirthday) ? $decrypt_result_array->userBirthday : null;
            /* 사용자 성별 (1: 남자, 2: 여자) */
            $user_gender = isset($decrypt_result_array->userGender) ? $decrypt_result_array->userGender : null;
            /* 사용자 국적 (0: 내국인, 1: 외국인) */
            $user_nation = isset($decrypt_result_array->userNation) ? $decrypt_result_array->userNation : null;
            /* 본인확인 인증 종류 */
            $req_auth_type = $decrypt_result_array->reqAuthType;
            /* 본인확인 요청 시간 */
            $req_date = $decrypt_result_array->reqDate;
            /* 본인확인 인증 서버 */
            $issuer = $decrypt_result_array->issuer;
            /* 본인확인 인증 시간 */
            $issue_date = $decrypt_result_array->issueDate;
    
            /* 6. 이용기관 응답데이터 셔션 및 검증유효시간 처리  */
    
            // 검증정보 유효시간 검증 (토큰 생성 후 10분 이내 검증 권고)
            $date_time = date("Y-m-d H:i:s");
    
            $old = strtotime($issue_date);
            $old = date("Y-m-d H:i:s", $old);
    
            $time_limit = strtotime($old."+10 minutes");
            $time_limit = date("Y-m-d H:i:s", $time_limit);
    
            if ($time_limit < $date_time) {
                $errorResult = array("resultMsg" => "-5|토큰 생성 10분 경과");
                return '';
            }
    
            /* 7. 이용기관 서비스 기능 처리 */
    
            // - 이용기관에서 수신한 개인정보 검증 확인 처리
    
            // - 이용기관에서 수신한 CI 확인 처리
    
            /* 8. 본인확인 결과 응답 */
    
            // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
            // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
    
            $result_array = array(
                "resultCode" => "2000"
                , "resultMsg" => "성공"
                , "userName" => $user_name
            );
            $result_json = json_encode($result_array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    
            return $result_json;
        }
    
        /* 본인확인 서버 통신 예제 함수 */
        function sendPost($data, $url) {
            $curl = curl_init();                                                              // curl 초기화
            curl_setopt($curl, CURLOPT_URL, $url);                                            // 데이터를 전송 할 URL
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);                                 // 요청결과를 문자열로 반환
            curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));  // 전송 ContentType을 Json형식으로 설정
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);                                // 원격 서버의 인증서가 유효한지 검사 여부
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);                                    // POST DATA
            curl_setopt($curl, CURLOPT_POST, true);                                           // POST 전송 여부
            $response = curl_exec($curl);                                                     // 전송
            curl_close($curl);                                                                // 연결해제
    
            return $response;
        }
    ?>
    <?php 
        /* 7. 본인확인 결과 응답 방식 */
        /* 7.1 : 팝업창 : callback 함수 사용 */
        echo mobileOK_std_result($mobileOK, $MOK_RESULT_REQUEST_URL);
    ?>
    <?php 
        // redirect 모드 이용시 "7.1 : 팝업창 : callback 함수 사용"  주석 처리 후 "7.2 : 페이지 이동" form 태그 주석제거 및 <?php ~ ?> 제거하여 사용
    
        /* 7.2 : 페이지 이동 : redirect 방식, 이용기관 지정 페이지로 이동 */
        /* 
        <form method="post" action="
        <?php 
            echo $MOK_RESULT_REDIRECT_URL;
        ?>  
        ">
            <textarea style="width:500px; height: 500px" name="data">
               <?php 
                   echo mobileOK_std_result($mobileOK, $MOK_RESULT_REQUEST_URL);
               ?> 
           </textarea>
        </form>
        */
    ?>
    
    // mok_server_std.js 에서 모든 수행 처리
    
    // mok_react_server.js 에서 모든 수행 처리
    
    // mok_vue_server.js 에서 모든 수행 처리
    
    mok_std_result.aspx
    <%@ Page Language="C#" Async="true" AutoEventWireup="true" CodeBehind="mok_std_result.aspx.cs" Inherits="mok_std_result"%>
    <%@ Import Namespace="System" %>
    <%=resultData%>
    <%-- 4. 본인확인 결과 응답 방식 --%>
    <%-- 4.1 : 팝업창 : callback 함수 사용  --%>
    
    <%-- 4.2 : 페이지 이동 : redirect 방식, 이용기관 지정 페이지로 이동 --%>
    <%--
    <form method="post" action="https://이용기관 URL/mok/result_page.jsp">
        <textarea style="width:500px; height: 500px" name="data">
            <%= mobileOK_result(data, mobileOK) %>
        </textarea>
    </form>
    --%>
    
    mok_std_result.aspx.cs
    using System;
    using System.IO;
    using System.Web;
    using System.Web.UI;
    using System.Security.Authentication;
    using System.Text;
    using System.Threading.Tasks;
    
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using mokcrypto;
    using System.Net;
    
    public partial class mok_std_result : Page
    {
        protected string resultData = "";
        protected string REDmobileOK_result(string result, MobileOkKeyManager mobileOK)
        {
            /* 1. 본인확인 인증결과 MOKToken API 요청 URL */
            string targetUrl = "https://scert.mobile-ok.com/gui/service/v1/result/request";  // 개발
            //string targetUrl = "https://cert.mobile-ok.com/gui/service/v1/result/request";  // 운영
    
            /* 2. 본인확인 결과 타입별 결과 처리 */
            JObject resultJSON = JObject.Parse(result);
            string encryptMOKKeyToken = resultJSON["encryptMOKKeyToken"] != null ? resultJSON["encryptMOKKeyToken"].ToString() : null;
            string encryptMOKResult = null;
    
            /* 2.1 본인확인 결과 타입 : MOKToken */
            if (encryptMOKKeyToken != null)
            {
                JObject requestData = new JObject();
                requestData["encryptMOKKeyToken"] = encryptMOKKeyToken;
                string responseData = SendPost(targetUrl, requestData.ToString());
                if (responseData == null)
                {
                    return "-1|본인확인 MOKToken 인증결과 응답이 없습니다.";
                }
                JObject responseJSON = JObject.Parse(responseData);
                encryptMOKResult = responseJSON["encryptMOKResult"].ToString();
            }
            else
            {
                return "-1|본인확인 MOKToken 가 없습니다.";
            }
    
            /* 3. 본인확인 결과 JSON 정보 파싱 */
            JObject decrpytResultJson = new JObject();
            try
            {
                decrpytResultJson = JObject.Parse(mobileOK.getResultJson(encryptMOKResult));
            }
            catch (MobileOKException e)
            {
                return e.Message;
            }
    
            /* 4. 본인확인 결과 복호화 */
    
            // 이용기관 거래 ID //
            string clientTxId = decrpytResultJson != null && decrpytResultJson["clientTxId"] != null ? decrpytResultJson["clientTxId"].ToString() : string.Empty;
    
            //   - redirect 방식일 경우 페이지가 이동되면서 session 값이 유지되지 않음,  MS사에서는 세션관리서버를 별도 이용하는 것을 권고
            string sessionClientTxId = (string)HttpContext.Current.Session["sessionClientTxId"];
    
            // 세션 내 요청 clientTxId 와 수신한 clientTxId 가 동일한지 반드시 비교
            if (!sessionClientTxId.Equals(clientTxId))
            {
                return "-4|세션값에 저장된 거래ID 비교 실패";
            }
    
            // 사용자 이름 //
            string userName = decrpytResultJson != null && decrpytResultJson["userName"] != null ? decrpytResultJson["userName"].ToString() : string.Empty;
            // 이용기관 ID //
            string siteId = decrpytResultJson != null && decrpytResultJson["siteId"] != null ? decrpytResultJson["siteId"].ToString() : string.Empty;
            // 본인확인 거래 ID //
            string txId = decrpytResultJson != null && decrpytResultJson["txId"] != null ? decrpytResultJson["txId"].ToString() : string.Empty;
            // 서비스제공자(인증사업자) ID //
            string providerId = decrpytResultJson != null && decrpytResultJson["providerId"] != null ? decrpytResultJson["providerId"].ToString() : string.Empty;
            // 이용 서비스 유형 //
            string serviceType = decrpytResultJson != null && decrpytResultJson["serviceType"] != null ? decrpytResultJson["serviceType"].ToString() : string.Empty;
            // 사용자 CI //
            string ci = decrpytResultJson != null && decrpytResultJson["ci"] != null ? decrpytResultJson["ci"].ToString() : string.Empty;
            // 사용자 DI //
            string di = decrpytResultJson != null && decrpytResultJson["di"] != null ? decrpytResultJson["di"].ToString() : string.Empty;
            // 사용자 전화번호 //
            string userPhone = decrpytResultJson != null && decrpytResultJson["userPhone"] != null ? decrpytResultJson["userPhone"].ToString() : string.Empty;
            // 사용자 생년월일 //
            string userBirthday = decrpytResultJson != null && decrpytResultJson["userBirthday"] != null ? decrpytResultJson["userBirthday"].ToString() : string.Empty;
            // 사용자 성별 (1: 남자, 2: 여자) //
            string userGender = decrpytResultJson != null && decrpytResultJson["userGender"] != null ? decrpytResultJson["userGender"].ToString() : string.Empty;
            // 사용자 국적 (0: 내국인, 1: 외국인) //
            string userNation = decrpytResultJson != null && decrpytResultJson["userNation"] != null ? decrpytResultJson["userNation"].ToString() : string.Empty;
            // 본인확인 인증 종류 //
            string reqAuthType = decrpytResultJson != null && decrpytResultJson["reqAuthType"] != null ? decrpytResultJson["reqAuthType"].ToString() : string.Empty;
            // 본인확인 요청 시간 //
            string reqDate = decrpytResultJson != null && decrpytResultJson["reqDate"] != null ? decrpytResultJson["reqDate"].ToString() : string.Empty;
            // 본인확인 인증 서버 //
            string issuer = decrpytResultJson != null && decrpytResultJson["issuer"] != null ? decrpytResultJson["issuer"].ToString() : string.Empty;
            // 본인확인 인증 시간 //
            string issueDate = decrpytResultJson != null && decrpytResultJson["issueDate"] != null ? decrpytResultJson["issueDate"].ToString() : string.Empty;
    
            /* 5. 이용기관 응답데이터 셔션 및 검증유효시간 처리  */
    
            // 검증정보 유효시간 검증 (검증결과 생성 후 10분 이내 검증 권고)
            DateTime nowDateTime = DateTime.Now;
            DateTime issueDateTime = DateTime.ParseExact(issueDate, "yyyy-MM-dd HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture).AddMinutes(10);
            int diff = DateTime.Compare(nowDateTime, issueDateTime);
            if(diff > 0)
            {
                return "-5|검증결과 토큰 생성 10분 경과 오류";
            }
    
            /* 6. 이용기관 서비스 기능 처리 */
            // - 이용기관에서 수신한 개인정보 검증 확인 처리
            // - 이용기관에서 수신한 CI 확인 처리
    
            /* 7. 본인확인 결과 응답 */
    
            // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
            // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
    
            JObject resultJson = new JObject();
            resultJson["resultCode"] = "2000";
            resultJson["resultMsg"] = "성공";
            resultJson["userName"] = userName;
    
            return resultJson.ToString();
        }
    
        /* 본인확인 서버 통신 예제 함수 */
        private string SendPost(string url, string json)
        {
            SecurityProtocolType originalProtocol = ServicePointManager.SecurityProtocol;
            try
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "application/json";
    
                byte[] data = Encoding.UTF8.GetBytes(json);
                request.ContentLength = data.Length;
    
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
    
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                        {
                            return reader.ReadToEnd();
                        }
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            finally
            {
                // 기존 TLS 설정 복원
                ServicePointManager.SecurityProtocol = originalProtocol;
            }
        }
    
    
        protected void Page_Load(object sender, EventArgs e)
        {
            /* 2. 본인확인 서비스 API 설정 */
            MobileOkKeyManager mobileOK = new MobileOkKeyManager();
            string data = "";
            try
            {
                /* 키파일은 반드시 서버의 안전한 로컬경로에 별도 저장. 웹URL 경로에 파일이 있을경우 키파일이 외부에 노출될 수 있음 주의 */
                mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
    
                /* 3. 본인확인 인증 결과 암호문 수신 */
                data = HttpContext.Current.Request.Form["data"];
                data = HttpUtility.UrlDecode(data, System.Text.Encoding.UTF8);
            }
            catch (MobileOKException ex)
            {
                Console.Write(ex.Message);
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
            }
            resultData = REDmobileOK_result(data, mobileOK);
    
        }
    
        private void alertASPX(string errorMsg)
        {
            string script = "window.onload = function() { alert('" + errorMsg + "'); };";
            Page.ClientScript.RegisterStartupScript(this.GetType(), "alert", script, true);
        }
    }
    
    ResultController.cs
    using Microsoft.AspNetCore.Mvc;
    using mokcrypto;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    
    namespace Standard.Controllers
    {
        public class ResultController : Controller
        {
            [HttpPost]
            public async Task<IActionResult> mobileOK_std_result()
            {
                /* 2. 본인확인 키파일을 통한 비밀키 설정 */
                MobileOkKeyManager mobileOK = new MobileOkKeyManager();
                string data = "";
                try
                {
                    mobileOK.keyInit("/본인확인 키정보파일 Path/mok_keyInfo.dat", "키파일 패스워드");
    
                    /* 3. 본인확인 인증 결과 암호문 수신 */
                    Dictionary<string, string> formData = new Dictionary<string, string>();
    
                    foreach (var formField in HttpContext.Request.Form)
                    {
                        formData[formField.Key] = formField.Value;
                    }
    
                    data = formData["data"];
                    data = WebUtility.UrlDecode(data);
                }
                catch (MobileOKException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
    
                string message = await mobileOK_result(data, mobileOK);
    
                ViewData["message"] = message;
    
                return View();
            }
    
            protected async Task<string> mobileOK_result(string result, MobileOkKeyManager mobileOK)
            {
                /* 1. 본인확인 인증결과 MOKToken API 요청 URL */
                string targetUrl = "https://scert.mobile-ok.com/gui/service/v1/result/request";  // 개발
                //string targetUrl = "https://cert.mobile-ok.com/gui/service/v1/result/request";  // 운영
    
                /* 2. 본인확인 결과 타입별 결과 처리 */
                JObject resultJSON = JObject.Parse(result);
                string encryptMOKKeyToken = resultJSON["encryptMOKKeyToken"] != null ? resultJSON["encryptMOKKeyToken"].ToString() : null;
                string encryptMOKResult = null;
    
                /* 2.1 본인확인 결과 타입 : MOKToken */
                if (encryptMOKKeyToken != null)
                {
                    JObject requestData = new JObject();
                    requestData["encryptMOKKeyToken"] = encryptMOKKeyToken;
                    string responseData = await SendPost(targetUrl, requestData.ToString());
                    if (responseData == null)
                    {
                        return "-1|본인확인 MOKToken 인증결과 응답이 없습니다.";
                    }
                    JObject responseJSON = JObject.Parse(responseData);
                    encryptMOKResult = responseJSON["encryptMOKResult"].ToString();
                }
                else
                {
                    return "-1|본인확인 MOKToken 가 없습니다.";
                }
    
                /* 3. 본인확인 결과 JSON 정보 파싱 */
                JObject decrpytResultJson = new JObject();
                try
                {
                    decrpytResultJson = JObject.Parse(mobileOK.getResultJson(encryptMOKResult));
                }
                catch (MobileOKException e)
                {
                    return e.Message;
                }
    
                /* 4. 본인확인 결과 복호화 */
    
                // 이용기관 거래 ID //
                string clientTxId = decrpytResultJson != null && decrpytResultJson["clientTxId"] != null ? decrpytResultJson["clientTxId"].ToString() : string.Empty;
    
                //   - redirect 방식일 경우 페이지가 이동되면서 session 값이 유지되지 않음,  MS사에서는 세션관리서버를 별도 이용하는 것을 권고
                string sessionClientTxId = (string)HttpContext.Session.GetString("sessionClientTxId");
    
                // 세션 내 요청 clientTxId 와 수신한 clientTxId 가 동일한지 반드시 비교
                if (!sessionClientTxId.Equals(clientTxId))
                {
                    return "-4|세션값에 저장된 거래ID 비교 실패";
                }  
    
                // 사용자 이름 //
                string userName = decrpytResultJson != null && decrpytResultJson["userName"] != null ? decrpytResultJson["userName"].ToString() : string.Empty;
                // 이용기관 ID //
                string siteId = decrpytResultJson != null && decrpytResultJson["siteId"] != null ? decrpytResultJson["siteId"].ToString() : string.Empty;
                // 본인확인 거래 ID //
                string txId = decrpytResultJson != null && decrpytResultJson["txId"] != null ? decrpytResultJson["txId"].ToString() : string.Empty;
                // 서비스제공자(인증사업자) ID //
                string providerId = decrpytResultJson != null && decrpytResultJson["providerId"] != null ? decrpytResultJson["providerId"].ToString() : string.Empty;
                // 이용 서비스 유형 //
                string serviceType = decrpytResultJson != null && decrpytResultJson["serviceType"] != null ? decrpytResultJson["serviceType"].ToString() : string.Empty;
                // 사용자 CI //
                string ci = decrpytResultJson != null && decrpytResultJson["ci"] != null ? decrpytResultJson["ci"].ToString() : string.Empty;
                // 사용자 DI //
                string di = decrpytResultJson != null && decrpytResultJson["di"] != null ? decrpytResultJson["di"].ToString() : string.Empty;
                // 사용자 전화번호 //
                string userPhone = decrpytResultJson != null && decrpytResultJson["userPhone"] != null ? decrpytResultJson["userPhone"].ToString() : string.Empty;
                // 사용자 생년월일 //
                string userBirthday = decrpytResultJson != null && decrpytResultJson["userBirthday"] != null ? decrpytResultJson["userBirthday"].ToString() : string.Empty;
                // 사용자 성별 (1: 남자, 2: 여자) //
                string userGender = decrpytResultJson != null && decrpytResultJson["userGender"] != null ? decrpytResultJson["userGender"].ToString() : string.Empty;
                // 사용자 국적 (0: 내국인, 1: 외국인) //
                string userNation = decrpytResultJson != null && decrpytResultJson["userNation"] != null ? decrpytResultJson["userNation"].ToString() : string.Empty;
                // 본인확인 인증 종류 //
                string reqAuthType = decrpytResultJson != null && decrpytResultJson["reqAuthType"] != null ? decrpytResultJson["reqAuthType"].ToString() : string.Empty;
                // 본인확인 요청 시간 //
                string reqDate = decrpytResultJson != null && decrpytResultJson["reqDate"] != null ? decrpytResultJson["reqDate"].ToString() : string.Empty;
                // 본인확인 인증 서버 //
                string issuer = decrpytResultJson != null && decrpytResultJson["issuer"] != null ? decrpytResultJson["issuer"].ToString() : string.Empty;
                // 본인확인 인증 시간 //
                string issueDate = decrpytResultJson != null && decrpytResultJson["issueDate"] != null ? decrpytResultJson["issueDate"].ToString() : string.Empty;
    
    
                /* 5. 이용기관 응답데이터 셔션 및 검증유효시간 처리  */
    
                /* 검증정보 유효시간 검증 (검증결과 생성 후 10분 이내 검증 권고) */
                DateTime nowDateTime = DateTime.Now;
                DateTime issueDateTime = DateTime.ParseExact(issueDate, "yyyy-MM-dd HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture).AddMinutes(10);
                int diff = DateTime.Compare(nowDateTime, issueDateTime);
                if (diff > 0)
                {
                    return "-5|검증결과 토큰 생성 10분 경과 오류";
                }
    
                /* 6. 이용기관 서비스 기능 처리 */
                // - 이용기관에서 수신한 개인정보 검증 확인 처리
                // - 이용기관에서 수신한 CI 확인 처리
    
                /* 7. 본인확인 결과 응답 */
    
                // 복호화된 개인정보는 DB보관 또는 세션보관하여 개인정보 저장시 본인확인에서 획득한 정보로 저장하도록 처리 필요
                // 개인정보를 웹브라우져에 전달할 경우 외부 해킹에 의해 유출되지 않도록 보안처리 필요
    
                JObject resultJson = new JObject();
                resultJson["resultCode"] = "2000";
                resultJson["resultMsg"] = "성공";
                resultJson["userName"] = userName;
    
                return resultJson.ToString();
            }
    
            /* 본인확인 서버 통신 예제 함수 */
            private async Task<string> SendPost(string url, string json)
            {
                try
                {
                    HttpClient client = new HttpClient();
    
                    var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
    
                    var response = await client.PostAsync(url, content);
    
                    if (response.IsSuccessStatusCode)
                    {
                        string responseString = await response.Content.ReadAsStringAsync();
                        return responseString;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (HttpRequestException ex)
                {
                    Console.WriteLine("HttpRequestException: " + ex.Message);
                    return null;
                }
                catch (TaskCanceledException ex)
                {
                    Console.WriteLine("TaskCanceledException: " + ex.Message);
                    return null;
                }
                catch (IOException ex)
                {
                    Console.WriteLine("IOException: " + ex.Message);
                    return null;
                }
            }
        }
    }
    
    mobileOK_std_result.cshtml
    @*4. 본인확인 결과 응답 방식*@
    @Html.Raw(ViewData["message"])
    

8. 본인확인-표준창 오류코드

  • 본인확인서비스 오류코드 및 메시지

    에러코드 설명 고객 메시지 운영시 주요 에러코드
    2000 성공 성공
    2910 휴대폰 통신사 가입자 명의인증 실패 입력하신 정보가 올바르지 않습니다. 확인 후 다시 시도해주세요
    2910 휴대폰 통신사 사용자(소유자) 인증번호 검증 실패 입력하신 정보가 올바르지 않습니다. 인증번호를 확인해주세요.
    3001 인증요청 정보에 이름, 전화번호 등 요청문 필수 항목 필드를 확인할 수 없습니다. 입력값 오류가 발생했습니다. (필수 입력값 오류)
    처음부터 다시 시도해 주세요.
    4000 검증 완료 후 결과확인토큰(KeyToken)으로 검증 결과를 재요청하는 경우 발생합니다. (결과검증 성공시 재요청 불가)
    처리 완료 후 10분이 넘어 결과 전달 유효시간이 초과할 경우 발생합니다.
    이미 완료 되었거나 허용시간을 초과 한 인증 요청입니다. 확인 후 다시 시도해 주세요.
    4001 거래ID 및 서비스ID 로 서비스 조회가 안되는 경우 발생합니다.
    인증요청 후 세션 유지시간인 7분을 초과하여 조회가 되지 않을때 발생 할 수 있습니다.
    인증 진행사항을 확인할 수 없습니다.
    처음부터 다시 시도해 주세요.
    4003 인증번호 재발송시 거래ID 및 서비스ID를 서비스에서 확인할 수 없습니다.
    인증요청을 하지 않았거나 인증요청 후 세션 유지시간인 7분을 초과하여 때 발생 할 수 있습니다.
    상세코드
    - 4002, 4003 : 요청 시 저장한 제한횟수등 진행사항이 없음
    - 4004 : ARS 및 SMS OTP 요청을 찾을 수 없는 경우
    이미 완료 되었거나 허용시간을 초과 한 인증 요청입니다.
    확인 후 다시 시도해 주세요. (상세코드)
    4005 통신사 SMS 인증외 인증수단(ARS 등의)인증시 알수없는 서비스제공자가 설정된 경우 발생합니다. ARS서비스에 오류가 발생하였습니니다(ARS사업자정보)
    관리자에게 문의 해 주세요.
    4006 서비스 본인확인 인증 Type 코드 올바르게 입력되어 요청되지 않았습니다. reqAuthType 의 “SMS”, “PASS” 설정 인증 요청 정보가 올바르지 않습니다.(인증구분)
    확인 후 다시 시도해 주세요.
    4007 이미 서비스내에 이용중인 거래ID가 있습니다. 다시 검증을 위해서는 재시도가 필요합니다. 이미 진행중인 인증 요청입니다.
    처음부터 다시 시도해 주세요.
    4008 통신사 또는 인증사업자와의 연결에 이상이 발생하였습니다. 대부분 재시도시 사용가능 하나 오류가 지속될경우 본인확인서비스 운영담당자에게 문의 바랍니다. 선택하신 본인확인 서비스와 연결에 실패했습니다.
    잠시후 다시 시도해 주세요.
    4009 이용기관 에서 등록한 ARS코드가 서비스에 허용된 ARS가 다릅니다. 설정이 맞는지 본인확인서비스 운영담당자에게 문의 바랍니다. ARS서비스에 오류가 발생하였습니니다(ARS코드)
    관리자에게 문의 해 주세요.
    4010 이용기관에서 요청한 인증요청 정보중 통신사 정보가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(통신사정보) 확인 후 다시 시도해 주세요.
    4011 ARS 서비스 연결 요청에 실패하였습니다. 대부분 재시도시 사용가능 하나 오류가 지속될 경우 본인확인서비스 운영담당자에게 문의 바랍니다. ARS 서비스 연결 요청에 실패하였습니다.
    잠시 후 다시 시도해 주세요.
    4012 인증번호 SMS 를 사용자 휴대폰 전송하는데 실패하였습니다. 대부분 재시도시 사용가능 하나 오류가 지속될 경우 본인확인서비스 운영담당자에게 문의 바랍니다. 인증요청 메시지 전송에 실패하였습니다.
    잠시 후 다시 시도해 주세요.
    4013 이용자가 입력한 SMS 점유인증 및 ARS 입력 인증번호가 올바르지 않은 경우 발생합니다. 인증 요청 정보가 올바르지 않습니다(인증번호)
    확인 후 다시 시도해 주세요.
    4014 서비스 이용상품 코드가 올바르게 입력되어 요청되지 않았습니다. serviceType 의 “telcoAuth” : 휴대폰본인확인, “telcoAuth-LMS” : 휴대폰본인확인 LMS 설정 등 인증 요청 정보가 올바르지 않습니다(상품정보)
    확인 후 다시 시도해 주세요.
    4015 PASS등 인증 및 검증 재발송을 허용하지 않는 서비스 진행시 재발송을 요청한 경우 발생합니다. 재전송을 지원하지 않는 서비스입니다.
    확인 후 다시 시도해주세요.
    4016 인증요청 정보중 필수 항목 데이터가 없는 경우에 발생합니다. 통신사에 요청된 정보가 올바르지 않습니다.
    확인 후 다시 시도해주세요.
    4017 인증요청 정보중 통신사 정보가 없거나 정의되지 않은 통신사 정보가 있는 경우에 발생합니다. 인증 요청 정보가 올바르지 않습니다(통신사정보)
    확인 후 다시 시도해 주세요.
    4018 SMS 인증번호 검증시 요청된 서비스ID로 인증요청 정보를 찾을 수 없을경우 발생합니다. 인증요청이 요청되지 않았거나 검증완료 후 검증이 재요청된 경우, 인증 요청 후 10분이 넘어 세션타임이 초과하여 발생합니다. 이미 완료 되었거나 허용시간을 초과 한 인증 요청입니다.
    확인 후 다시 시도해 주세요.
    4020 ARS 인증시 검증결과가 실패인 경우 발생합니다. 예를들어 사용자가 ARS 전화를 받지 않거나 잘못된 정보를 입력한경우가 있습니다. 인증 요청 정보가 올바르지 않습니다(검증실패)
    확인 후 다시 시도해 주세요.
    4021 재전송을 지원하지 않는 서비스에서 재전송을 요청할 경우에 발생합니다. 재전송을 지원하지 않는 서비스입니다.
    확인 후 다시 시도해주세요..
    4022 KT 법인 사용자가 본인확인 인증시 SMS로 전송된 WEB LINK 인증을 진행하지 않은 경우에 발생합니다. 인증 요청에 실패하였습니다. KT법인명의 본인확인을 위해 수신한 SMS 안내에 따라 추가 인증을 진행해주세요.
    4023 사용자가 SKT 부가서비스(휴대폰번호보호서비스, 인증보호서비스 등) 가입자고 부가서비스 2차 인증 미완료시 발생합니다. 부가서비스 인증 완료되지 않았습니다.
    부가서비스 인증을 하신 후 다시 진행해 주세요.
    4101 이용기관의 토큰 요청정보가 올바르지 않습니다. 토큰 발급 시 필요한 필수값 및 설정이 맞는지 확인이 필요합니다. 인증 요청 정보가 올바르지 않습니다.
    확인 후 다시 시도해 주세요.
    4150 요청된 거래ID로 검증완료 후 개인정보결과가 리턴되어 검증요청을 재전송할 수 없는 경우 발생합니다. 이미 처리 완료된 인증 요청입니다.
    4301 본인확인 검증요청 제한 횟수인 3회를 초과하여 발생합니다. 검증요청 제한 횟수를 초과하였습니다.
    처음부터 다시 시도해 주세요.
    4302 인증번호 SMS 재전송 횟수인 3회를 초과하여 발생합니다. 인증요청 제한 횟수를 초과하였습니다.
    처음부터 다시 시도해 주세요.
    4500 ARS 인증결과를 확인 할 수 없습니다. ARS 통화가 완료되지 않거나 ARS 응답이 수신되지 않아 발생할 수 있습니다. ARS인증 결과를 찾을 수 없습니다.
    확인 후 다시 시도해 주세요.
    4501 사용자 ARS 전화요청이 성공한 직후, 전화걸기 재 요청 시 처음 ARS 결과가 아직 수신되지 않아 해당 문구가 안내됩니다. ARS 전화가 현재 진행 중입니다.
    반복적으로 해당 메시지가 수신된 경우, 처음부터 다시 시도해 주세요
    4502 사용자 ARS 전화를 수신 받아 전화연결이 정상적으로 완료된 이후, 다시 전화걸기를 시도하신 경우 해당 문구가 안내됩니다. ARS 인증을 이미 진행하셨습니다.
    4602 사용자 ARS 전화요청시 인증번호가 불일치 한 경우 발생합니다. 인증 요청 정보가 올바르지 않습니다(인증번호)
    확인 후 다시 시도해 주세요.
    4604 사용자 ARS 전화요청시 인증번호를 검증하지 않고 취소 (사용자가 ARS 전화를 받고, "#" 버튼을 눌러 도중에 취소한 경우)하여 인증 요청이 종료된 경우 발생합니다. 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.
    4610 사용자 ARS 전화요청시 없는 번호인 경우 발생합니다. 인증 요청 정보가 올바르지 않습니다(잘못된 휴대폰번호)
    확인 후 다시 시도해 주세요.
    4611 사용자 ARS 전화요청시 사용자가 수신 거부 한 경우 발생합니다. 인증 요청 정보가 올바르지 않습니다(수신거부)
    확인 후 다시 시도해 주세요.
    4612 사용자 ARS 전화요청시 ARS 전화를 안 받은 경우 발생합니다. 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.
    4613 사용자 ARS 전화요청시 착신 전환된 사용자의 경우 발생합니다. 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.
    4620 사용자 ARS 전화요청시 ARS 전화를 받고, 고객이 전화를 끊은 경우 발생합니다. 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.
    4624 사용자 ARS 전화요청시 사용자가 ARS 전화를 받고, 아무 입력이 없어 종료된 경우 발생합니다. 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.
    4641 사용자 ARS 전화요청시 사용자가 통화중인 경우 발생합니다. 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.
    4642 사용자 ARS 전화요청시 사용자 휴대폰 전원이 꺼져서 ARS 진행을 못한 경우 발생합니다. 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.
    4698 사용자 ARS 전화요청시 OTP검증번호 입력 후 통신사와의 검증요청시 오류결과를 받을 경우 발생합니다. ARS서비스에 오류가 발생하였습니니다(ARS사업자오류)
    관리자에게 문의 해 주세요.
    4699 사용자 ARS 전화요청시 ARS전화요청 서버가 오류가 발생한 경우입니다. ARS서비스에 오류가 발생하였습니니다(ARS사업자오류)
    관리자에게 문의 해 주세요.
    5003 본인확인 인증요청 정보중 사용자 이름 정보가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(이름)
    확인 후 다시 시도해 주세요.
    5004 본인확인 인증요청 정보중 사용자 생년월일 정보가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(생년월일)
    확인 후 다시 시도해 주세요.
    5005 본인확인 인증요청 정보중 사용자 성별 정보가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(성별)
    확인 후 다시 시도해 주세요.
    5007 본인확인 인증요청 정보중 ReqAuthType이 올바르지 않습니다. reqAuthType 의 “SMS”, “PASS” 설정 인증 요청 정보가 올바르지 않습니다(인증구분)
    관리자에게 문의해 주세요.
    5008 본인확인 인증요청 정보중 ServiceType이 올바르지 않습니다. serviceType 의 “telcoAuth” : 휴대폰본인확인, “telcoAuth-LMS” : 휴대폰본인확인 LMS 설정 등 인증 요청 정보가 올바르지 않습니다(상품정보)
    관리자에게 문의해 주세요.
    5009 본인확인 인증요청 정보중 등록된 이용기관 ID가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(이용기관정보)
    관리자에게 문의해 주세요.
    5010 본인확인 인증요청 정보중 통신사 정보가 없거나 정의되지 않은 통신사 정보가 있는 경우에 발생합니다. 인증 요청 정보가 올바르지 않습니다(통신사정보)
    확인 후 다시 시도해 주세요.
    5011 본인확인 검증요청 정보중 검증번호(SMS OTP 또는 ARS 입력정보)가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(인증번호)
    확인 후 다시 시도해 주세요.
    5012 본인확인 인증요청 정보중 사용자 휴대폰번호가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(휴대폰번호)
    확인 후 다시 시도해 주세요.
    5013 본인확인 인증요청 정보중 이용기관 ID가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(이용기관)
    관리자에게 문의해 주세요.
    5014 본인확인 요청 이용기관 거래ID가 올바르지 않습니다. 인증 요청 정보가 올바르지 않습니다(이용기관 거래ID)
    관리자에게 문의해 주세요.
    5015 본인확인 요청 통신사 요청 거래ID가 올바르지 않습니다. 본인확인 요청 응답시 수신한 토큰으로 검증요청을 했는지 확인 바랍니다. 인증 요청 정보가 올바르지 않습니다(요청 거래ID)
    관리자에게 문의해 주세요.
    5016 본인확인 검증 통신사 응답 거래ID가 올바르지 않습니다. 본인확인 요청 응답시 수신한 토큰으로 검증요청을 했는지 확인 바랍니다. 인증 요청 정보가 올바르지 않습니다(검증 거래ID)
    관리자에게 문의해 주세요.
    5017 등록된 이용기관 ID 정보를 찾을 수 없습니다. 설정이 맞는지 본인확인서비스 운영담당자에게 문의 바랍니다. 인증 요청 정보가 올바르지 않습니다(이용기관정보)
    관리자에게 문의해 주세요.
    5018 ARS 인증요청 정보중 사용자 생년월일 입력형식이 맞지 않습니다. 예시) 8자리 년월일 20011010 인증 요청 정보가 올바르지 않습니다(생년월일)
    확인 후 다시 시도해 주세요.
    5019 ARS 검증요청 정보중 ARS 거래ID 정보가 없습니다. 본인확인 요청 응답시 수신한 토큰으로 검증요청을 했는지 확인 바랍니다. ARS서비스에 오류가 발생하였습니니다(ARS 거래ID)
    관리자에게 문의 해 주세요.
    5020 본인확인 표준창에서 통신사 정보 및 동의한 약관등 필수정보가 입력되지 않았습니다. 인증 요청 정보가 올바르지 않습니다(통신사정보)
    관리자에게 문의해 주세요.
    5021 모바일웹 본인확인 표준창에서 통신사 정보 및 동의한 약관등 필수정보가 입력되지 않았습니다. 인증 요청 정보가 올바르지 않습니다(통신사정보)
    관리자에게 문의해 주세요.
    5023 등록된 이용기관 서비스 ID 정보를 찾을 수 없습니다. 본인확인 담당자에게 받은 키파일이 올바른지 확인 바랍니다. 인증 요청 정보가 올바르지 않습니다(이용기관)
    관리자에게 문의해 주세요.
    5024 검증요청 정보가 올바르지 않거나 검증을 하지 않은 경우 발생합니다. 인증 요청 정보가 올바르지 않습니다(검증실패)
    확인 후 다시 시도해 주세요.
    5027 이용이 중지된 이용기관 입니다. 본인확인서비스 운영담당자에게 문의 바랍니다. 인증 요청 정보가 올바르지 않습니다(이용기관)
    관리자에게 문의해 주세요.
    5028 이용기관에 등록되지 않은 도메인에 결과를 응답요청하였습니다. 등록된 도메인으로 변경하거나 본인확인서비스 운영담당자를 통해 추가 등록 바랍니다. 인증 요청 정보가 올바르지 않습니다(이용기관)
    관리자에게 문의해 주세요.
    5029 본인확인 OTP 검증 시 인증번호의 형식이 올바르지 않음 인증 요청 정보가 올바르지 않습니다(인증번호 향식오류)
    확인 후 다시 시도해 주세요.
    5030 키보드 보안 복호화 중 문제가 발생했습니다. 인증 요청 정보가 올바르지 않습니다(키보드보안 복호화실패)
    확인 후 다시 시도해 주세요.
    5031 암호화된 개인정보 처리시 오류가 발생했습니다. 원인을 알 수 없는 오류가 발생했습니다.
    잠시 후 다시 시도해 주세요
    5032 요청한 브라우져의 정보 검증시 오류가 발생했습니다. 원인을 알 수 없는 오류가 발생했습니다.
    잠시 후 다시 시도해 주세요
    5033 최초 토큰발급 이후 10분이 경과되어 토큰이 만료되어 발생합니다. 유효시간이 만료되었습니다.
    처음부터 다시 시도해 주세요.
    5034 요청한 ARS-CODE가 없거나 이용기관에 사용이 허가된 ARS코드가 아닐경우 발생합니다. 등록되지 않은 ARS-CODE입니다.
    관리자에게 문의해 주세요
    5037 요청한 ArsCode 기준 사용할 수 있는 SiteId 목록에 없을경우에 발생합니다. 해당 ARS Code를 사용할 수 없는 Site 입니다.
    관리자에게 문의해 주세요
    5101 서비스 이용시 인증요청을 시도한 클라이언트와 검증요청을 시도한 클라이언트의 정보가 변경되어 이상현상이 감지한 경우 발생합니다. 잘못된 요청이 감지되었습니다.
    관리자에게 문의해 주세요.
    6021 요청정보 중 통신사 인증용 트랜잭션ID 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6022 요청정보 중 CPCODE 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 등록되지 않은 CPCODE 입니다.
    관리자에게 문의해 주세요.
    6023 요청정보 중 거래ID 중복요청으로 인하여 오류가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6024 요청정보 중 인증번호(OTP) 전송요청 3분 제한시간이 초과하여 오류가 발생했습니다. OTP 입력시간을 초과하였습니다. 잠시 후 다시 시도해 주세요.
    6025 요청정보 중 CP SMS 미사용 설정 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6026 요청정보 중 Message형식 형식에서 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6027 요청정보 중 MMS 미사용 / CP사 정보 확인시 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6028 본인확인 처리시 원문 무결성 검증데이터 체크에서 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6037 T인증 통신 실패 오류가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6038 T인증 통신 유효시간 초과 실패 오류가 발생했습니다. 유효시간이 만료되었습니다.
    처음부터 다시 시도해 주세요.
    6039 T인증 서버 작업등으로 인한 일시적 오류가 발생했습니다. PASS 서비스 점검중입니다.
    잠시 후 다시 시도해 주세요.
    6040 T인증 트랜잭션ID 요청실패로 인한 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6041 T인증 KEY 처리로 인한 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6042 T인증 서버에서 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6050 SMS 전송 실패가 발생했습니다. SMS 메시지 전송 중 오류가 발생하였습니다.
    잠시 후 다시 시도해 주세요.
    6052 통신사 응답전송실패 실패가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6053 통신사 시스템 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 시스템 오류가 발생했습니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6054 통신사 통신 전문오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6081 통신사 통신시 통합실패 특이케이스가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6082 통신사 통신시 중복 전문 요청이 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6092 LGU+ APP SMS 발송 실패가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6093 LGU+ APP SMS 발송 실패가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6094 통신사 통신시 전문 요청시 이슈가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6095 통신사 인증요청 서버 연동시 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6096 통신사 개인정보 획득시 서버 오류가 발생하였습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6097 SMS/LMS 발송 오류가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6098 통신사 서버에서 오류가 발생하였습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6100 통신사 서버에서 신원확인 처리시 오류가 발생하였습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6101 통신사 서버에서 오류가 발생하였습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6102 통신사 시스템에서 오류가 발생하였습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6118 인증실패 오류가 발생하였습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6200 PASS 인증실패(유효하지 않은 APP Token) 오류가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6201 PASS 인증실패(유효하지 않은 Session ID) 오류가 발생했습니다. PASS인증에 실패하였습니다.
    문자 (SMS) 인증으로 다시 시도해 주세요.
    6204 PASS 인증실패(유효하지 않은 TID) 오류가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6206 PASS 트랜잭션 생성실패 오류가 발생했습니다. 일시적인 오류입니다.
    잠시 후 다시 시도해 주세요.
    6208 PASS 인증실패(민앤지 인증실패) 오류가 발생했습니다. PASS인증에 실패하였습니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    6083 요청정보 중 서비스코드 형식에서 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6084 LGU+ 대행업체코드에서 오류 입력이 확인되었습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6085 요청정보 중 거래번호 입력값에서 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6086 요청정보 중 전화번호 입력값에서 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6087 요청정보 중 명의자 주민번호 입력값에서 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6088 요청정보 중 회원사 URL 미입력 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6089 요청정보 중 인증번호(OTP) 검증구분코드에서 오류가 발생했습니다. 본인확인서비스 운영담당자에게 확인 바랍니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6090 요청정보 중 인증번호(OTPCode) 에서 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6091 요청정보 중 간편본인확인 인증 구분 코드에서 오류가 발생했습니다. 잘못된 요청입니다.
    관리자에게 문의해 주세요.
    6099 인증요청 및 검증요청시 시간초과로 인한 유효시간 만료 오류가 발생하였습니다. 유효시간이 만료되었습니다.
    처음부터 다시 시도해 주세요.
    6701 PASS 미가입 사용자일 경우 발생합니다. 상세코드 참고
    - 6030: T 인증 미가입
    - 6210: PASS 인증실패(미등록 인증서비스코드)
    - 6116: FIDO 미등록 서비스코드
    PASS 서비스 미가입자입니다.
    가입 후 다시 시도해주세요.(상세코드)
    6702 PASS 인증 미진행시 발생합니다. 상세코드 참고
    - 6061: 간편본인확인 진행중
    - 6032: T 인증 대기중
    - 6114 : FIDO 미진행 처리중
    PASS 인증이 완료되지 않았습니다.
    인증 후 다시 시도해 주세요.(상세코드)
    6703 PASS 인증실패 사용자일 경우 발생합니다. 상세코드 참고
    - 6207: PASS 인증실패(인증 미진행 / 처리중)
    - 6202: PASS 인증실패(간편본인확인 요청 처리 완료 전 간편본인확인 결과 확인 요청)
    - 6212 : PASS 인증실패(앱미설치/미가입/미구동 등)
    PASS 인증이 완료되지 않았습니다.
    인증 후 다시 시도해 주세요.(상세코드)
    6704 PASS앱 미설치 사용자일 경우 발생합니다. 상세코드 참고
    - 6113: FIDO App 미설치
    - 6209: PASS 인증실패(App미설치 및 AppToken검증실패)
    - 6041 : PASS 앱 미 설치 에러
    - 6060 : 간편본인확인 미가입
    PASS 앱이 설치되지 않았습니다.
    앱 설치 후 다시 시도해 주세요.(상세코드)
    6705 PASS 고객인증 실패시 발생합니다. 상세코드 참고
    - 6205: PASS 고객인증 실패(사용자취소,PIN등 불일치 등)
    - 6110: FIDO 고객인증실패
    - 6035 : T 인증 사용자 취소
    - 6112 : FIDO 민앤지 인증실패
    - 6033 : T 인증 PIN 입력
    PASS 인증 요청이 취소되었습니다.
    처음부터 다시 시도해 주세요.(상세코드)
    6706 PASS 인증 유효시간 초과시 발생합니다. 상세코드 참고
    - 6034: T 인증 유효시간 초과
    - 6203: PASS 인증실패(인증 TIMEOUT)
    - 6115 : FIDO TIME OUT
    유효시간이 만료되었습니다.
    처음부터 다시 시도해 주세요.(상세코드)
    6707 PASS 인증 가능 휴대폰이 아닐경우 발생합니다. 상세코드 참고
    - 6036: 스마트폰 아님
    - 6063: 스마트폰 아님
    - 6211 : PASS 인증실패(미등록 인증장치)
    - 6117 : FIDO 미등록 인증장치
    PASS 인증을 사용할 수 없습니다.
    문자 (SMS) 인증으로 다시 시도해 주세요. (상세코드)
    6707 PASS 인증 가능 휴대폰이 아닐경우 발생합니다. 상세코드 참고
    - 6036: 스마트폰 아님
    - 6063: 스마트폰 아님
    - 6211 : PASS 인증실패(미등록 인증장치)
    - 6117 : FIDO 미등록 인증장치
    PASS 인증을 사용할 수 없습니다.
    문자 (SMS) 인증으로 다시 시도해 주세요. (상세코드)
    6751 PASS 사용자휴대폰 14세 미만 사용자일 경우 발생합니다. PASS 인증은 만 15세 이상부터 이용가능합니다.
    문자 (SMS) 인증으로 다시 시도해 주세요.
    6752 PASS 앱 PUSH발송 실패일 경우 발생합니다. PUSH 발송에 실패하였습니다.
    잠시 후 다시 시도해 주세요.
    6753 PASS T 인증앱 재등록 실패일 경우 발생합니다. PASS 인증 중 오류가 발생하였습니다.
    PASS 인증 앱 재설치 후 다시 시도해주세요.
    6754 PASS LGU+ 알뜰폰 가입자일 경우 발생합니다. LGU+ 알뜰폰 가입자입니다. 통신사를 알뜰폰으로 선택하여 다시 시도해 주세요.
    6755 PASS 본인확인 차단고객(App설정)일 경우 발생합니다. 본인확인서비스 이용이 차단되어 있습니다.
    차단 해지 후 다시 시도해 주세요.
    6756 PASS 본인확인 메시지 발송 차단 고객(App설정) 경우 발생합니다. 메시지 발송이 차단되어 있습니다.
    차단 해지 후 다시 이용해 주세요.
    (설정-> 메시지-> 차단된 연락처->해지할 연락처 선택).
    6757 SKT인증앱 미설치 사용자 휴대폰에서 발생합니다. SKT 휴대폰인증보호 서비스 앱이 설치되지 않았습니다.
    앱 설치 후 다시 시도해 주세요.
    6999 통신사 시스템 내부 오류가 발생하였습니다. 시스템 오류가 발생했습니다.
    잠시 후 다시 시도해 주세요. 지속적으로 오류가 발생하는 경우 관리자에게 문의해주세요.
    7001 본인확인 완료 후 검증토큰(keyToken)에 해당하는 결과정보를 찾을 수 없습니다. 검증토큰이 올바르지 않거나 검증요청 후 세션 유지시간인 7분을 초과하여 조회가 되지 않을때 발생 할 수 있습니다. 인증 요청 정보가 올바르지 않습니다(검증실패)
    확인 후 다시 시도해 주세요.
    8001 인증요청시 필수 요청 값인 이용기관ID(cpid)가 없습니다. 인증 요청 정보가 올바르지 않습니다(이용기관)
    관리자에게 문의해 주세요.
    8002 인증요청시 필수 요청 값인 응답결과 수신 URL(rtn_url) 정보가 없습니다. 인증 요청 정보가 올바르지 않습니다(return_url)
    관리자에게 문의해 주세요.
    8003 인증요청시 필수 요청 값인 요청 날짜, 요청번호등 필수 요청값(req_info) 이 없습니다. 인증 요청 정보가 올바르지 않습니다(요청정보)
    관리자에게 문의해 주세요.
    8004 본인확인 서비스에 등록되지 않은 이용기관 서비스 ID 입니다. 본인확인 담당자에게 문의하시기 바랍니다. 인증 요청 정보가 올바르지 않습니다(상품정보)
    관리자에게 문의해 주세요.
    8005 본인확인 서비스에 등록되지 않은 이용기관 ID 입니다. 본인확인 담당자에게 문의하시기 바랍니다. 인증 요청 정보가 올바르지 않습니다(이용기관)
    관리자에게 문의해 주세요.
    8006 본인확인 서비스에 등록되지 않은 이용기관 도메인 입니다. 본인확인 담당자에게 문의하시기 바랍니다. 인증 요청 정보가 올바르지 않습니다(이용기관)
    관리자에게 문의해 주세요.
    8007 본인확인 서비스에 등록되지 않은 이용기관 응답결과 수신 도메인(허가된 응답결과 수신 도메인) 입니다. 본인확인 담당자에게 문의하시기 바랍니다. 인증 요청 정보가 올바르지 않습니다(return_url)
    관리자에게 문의해 주세요.
    8101 본인확인 서비스 요청 응답 결과 복호화에 실패했습니다. 올바른 본인확인 복호화용 키가 설정되어 있는지 확인바랍니다. 인증 요청 정보가 올바르지 않습니다(요청정보 복호화)
    관리자에게 문의해 주세요.
    8102 본인확인 서비스 요청 정보 생성에 실패했습니다. 올바른 본인확인 암호화용 키가 설정되어 있는지 확인바랍니다. 인증 요청 정보가 올바르지 않습니다(요청정보 생성실패)
    관리자에게 문의해 주세요.
    8201 본인확인 서비스 응답결과 생성시 결과값 암호화에 실패했습니다. 본인확인 검증요청시 이름 등 길이제한을 초과하여 입력한 경우 발생할 수 있습니다. 인증 요청 정보가 올바르지 않습니다(결과값 암호화실패)
    관리자에게 문의해 주세요.
    9997 PASS등 인증 및 검증 재발송을 허용하지 않는 서비스 진행시 재발송을 요청한 경우 발생합니다. 재발송을 제공하지 않는 서비스입니다.
    확인 후 다시 시도해 주세요.
    9998 인증요청 정보중 필수 항목 데이터가 없는 경우에 발생합니다. 인증 요청 정보가 올바르지 않습니다.
    확인 후 다시 시도해 주세요.
    9999 서비스 중 알 수 없는 오류(예외처리 등)가 발생되었으며 자세한 사항은 본인확인서비스 운영담당자에게 문의 바랍니다. 원인을 알 수 없는 오류가 발생했습니다.
    잠시 후 다시 시도해 주세요
    기타코드 서비스 모듈에서 일반적이지 않은 오류가 발생했거나 통신사 응답값에 일반적이지 않은 오류가 발생한 경우 에러코드표에 없는 오류코드가 응답될 수 있습니다. 본인확인 담당자에게 문의하시기 바랍니다. 원인을 알 수 없는 오류가 발생했습니다. 잠시 후 다시 시도해 주세요
Back to top