eGovFrame GPKI 라이브러리 미발급 상태에서 개발 진행시

JSP & Spring 2015. 6. 23. 03:33

pom.xml 파일에 주석처리

(pom.xml 파일 참조 : GPKI 관련 dependency 2종)

<!-- GPKI인증서 로그인처리 라이브러리 -->
    <dependency>
        <groupId>kr.go.gpki</groupId>
        <artifactId>gpkisecureweb</artifactId>
        <version>1.0.4.9</version>
        <scope>system</scope>
        <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gpkisecureweb-1.0.4.9.jar</systemPath>
    </dependency>
    <dependency>
        <groupId>kr.go.gpki</groupId>
        <artifactId>libgpkiapi_jni</artifactId>
        <version>1.4.0.0</version>
        <scope>system</scope>
        <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/libgpkiapi_jni-1.4.0.0.jar</systemPath>
    </dependency>


관련 파일 삭제

GPKI 인증서 관련 JAVA 파일

src/main/java/egovframework/com/sec/pki/service/impl/EgovGPKIServiceImpl.java
src/main/java/egovframework/com/sec/pki/web/EgovGPKITestController.java(설명에 있으나 찾을 수 없음)
src/main/java/egovframework/com/utl/sec/service/EgovCertInfoUtil.java
src/main/java/egovframework/com/utl/sec/web/EgovCertLoginController.java


파일 소스 - ver3.2

src/main/java/egovframework/com/sec/pki/service/impl/EgovGPKIServiceImpl.java

package egovframework.com.sec.pki.service.impl;

import java.util.Enumeration;

import egovframework.com.cmm.service.EgovProperties;
import egovframework.com.sec.pki.service.EgovGPKIService;

import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;

import netscape.ldap.LDAPConnection;
import netscape.ldap.LDAPEntry;
import netscape.ldap.LDAPException;
import netscape.ldap.LDAPSearchConstraints;
import netscape.ldap.LDAPSearchResults;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.gpki.gpkiapi_jni;

/**
 * GPKI(Goverment Public Key Infrastructure)를 위한 서비스 구현 클래스
 * @author 공통컴포넌트개발팀 한성곤
 * @since 2009.06.04
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *   수정일      수정자           수정내용
 *  -------    --------    ---------------------------
 *   2009.6.4  한성곤          최초 생성
 *
 * </pre>
 */
@Service("EgovGPKIService")
public class EgovGPKIServiceImpl extends EgovAbstractServiceImpl implements EgovGPKIService {
    /** GPKI API JNI */
    private gpkiapi_jni gpkiAPI = null;
    /** 속성 파일 정보 */
    private String config = null;

    private static final Logger LOGGER = LoggerFactory.getLogger(EgovGPKIServiceImpl.class);

    /*
    // PostConstruct 사용 시 startup loading으로 인하여 gpkiapi_jni.dll이 없는 경우 servlet loading되지 못함
    // setup(synchronized) 메소드  사용 방식으로 변경
    @PostConstruct
    public void init() {
    //--------------------------------
    // 속성 정보 얻기
    //--------------------------------
    config = EgovProperties.getProperty("Globals.GPKIConfPath");

    //--------------------------------
    // GPKI JNI 취득
    //--------------------------------
    // gpkiapki_jni.jar의 경우는 System Classpath에 추가되어야 함..
    // 그렇지 않은 경우는 다음과 같은 오류가 reload시 발생됨
    // Native Library C:\WINDOWS\system32\gpkiapi_jni.dll already loaded in another classloader
    //--------------------------------
    gpkiAPI = new gpkiapi_jni();
    }
    */

    public void setup() {
        synchronized (this) {
            if (config == null || gpkiAPI == null) {
                //--------------------------------
                // 속성 정보 얻기
                //--------------------------------
                config = EgovProperties.getPathProperty("Globals.GPKIConfPath");

                //--------------------------------
                // GPKI JNI 취득
                //--------------------------------
                // gpkiapki_jni.jar의 경우는 System Classpath에 추가되어야 함..
                // 그렇지 않은 경우는 다음과 같은 오류가 reload시 발생됨
                // Native Library C:\WINDOWS\system32\gpkiapi_jni.dll already loaded in another classloader
                //--------------------------------
                gpkiAPI = new gpkiapi_jni();
            }
        }
    }

    /**
     * 현 서버의 ID를 얻는다.
     */
    public String getServerId() throws Exception {
        //-----------------------------------------
        // @PostConstruct 미사용 방식
        //-----------------------------------------
        if (config == null || gpkiAPI == null) {
            setup();
        }
        ////---------------------------------------

        return EgovProperties.getProperty(config, "gpki.certificate.server");
    }

    /**
     * LDAP에서 인증서 얻기.
     *
     * @param code
     * @return
     * @throws Exception
     */
    protected byte[] getCertFromLDAP(String code) throws Exception {
        //-----------------------------------------
        // @PostConstruct 미사용 방식
        //-----------------------------------------
        if (config == null || gpkiAPI == null) {
            setup();
        }
        ////---------------------------------------

        //--------------------------------
        // LDAP 관련 정보 얻기
        //--------------------------------
        String serverIp = EgovProperties.getProperty(config, "gpki.ldap.ip");
        String serverPort = EgovProperties.getProperty(config, "gpki.ldap.port");
        String basedn = EgovProperties.getProperty(config, "gpki.ldap.basedn");
        String readEntry = "cn=SVR" + code;
        String attribute = EgovProperties.getProperty(config, "gpki.ldap.attribute");

        String pwd = null;

        //--------------------------------
        // LDAP 연결
        //--------------------------------
        byte[] cert = null;
        LDAPEntry entry = null;
        Enumeration enumerator = null;
        LDAPSearchConstraints cons = null;
        LDAPSearchResults res = null;
        LDAPConnection ld = null;
        LDAPSearchConstraints constraints = null;

        try {
            ld = new LDAPConnection();
            constraints = new LDAPSearchConstraints();
            constraints.setTimeLimit(5000);
            ld.setConnectTimeout(3);
            ld.setConstraints(constraints);

            ld.connect(serverIp, Integer.parseInt(serverPort), basedn, pwd);

            cons = ld.getSearchConstraints();
            cons.setBatchSize(1);
            res = ld.search(basedn, 2, readEntry, null, false, cons);
            entry = (LDAPEntry) res.nextElement();
            enumerator = entry.getAttribute(attribute).getByteValues();
            cert = (byte[]) enumerator.nextElement();
        } finally {
            if (ld != null) {
                try {
                    ld.disconnect();
                } catch (LDAPException ignore) {
                    LOGGER.debug("Ignored Exception (LDAP Disconnect)", ignore);
                }
            }
        }

        return cert;
    }

    /**
     * 데이터 암호화 처리.
     *
     * @see egovframework.com.sec.pki.service.EgovGPKIService#encrypt(byte[], java.lang.String)
     */
    public byte[] encrypt(byte[] message, String target) throws Exception {
        //-----------------------------------------
        // @PostConstruct 미사용 방식
        //-----------------------------------------
        if (config == null || gpkiAPI == null) {
            setup();
        }
        ////---------------------------------------

        byte[] cert = getCertFromLDAP(target);

        byte[] encryptedData = null;

        try {
            gpkiAPI.API_Init(".");
            int returnCode = 0;

            returnCode = gpkiAPI.API_SetOption(gpkiapi_jni.API_OPT_RSA_ENC_V20);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }

            returnCode = gpkiAPI.CMS_MakeEnvelopedData(cert, message, gpkiapi_jni.SYM_ALG_SEED_CBC);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            encryptedData = gpkiAPI.baReturnArray;

        } finally {
            if (gpkiAPI != null) {
                gpkiAPI.API_Finish();
            }
        }

        return encryptedData;
    }

    /**
     * 복호화 처리.
     *
     * @see egovframework.com.sec.pki.service.EgovGPKIService#decrypt(byte[])
     */
    public byte[] decrypt(byte[] data) throws Exception {
        //-----------------------------------------
        // @PostConstruct 미사용 방식
        //-----------------------------------------
        if (config == null || gpkiAPI == null) {
            setup();
        }
        ////---------------------------------------

        //----------------------------------
        // 설정 정보 (암호화용 인증서 정보 필요)
        //----------------------------------
        String path = EgovProperties.getProperty(config, "gpki.certificate.path");

        String certForEnvFile = path + "/SVR" + EgovProperties.getProperty(config, "gpki.certificate.server") + "_env.cer";
        String keyForEnvFile = path + "/SVR" + EgovProperties.getProperty(config, "gpki.certificate.server") + "_env.key";
        String pinForEnv = EgovProperties.getProperty(config, "gpki.privatekey.password");

        //----------------------------------
        // 복호화 처리
        //----------------------------------
        byte[] plainData = null;

        try {
            gpkiAPI.API_Init(".");
            int returnCode = 0;

            byte[] baPriKey = null;
            byte[] certificate = null;

            returnCode = gpkiAPI.STORAGE_ReadPriKey(gpkiapi_jni.MEDIA_TYPE_FILE_PATH, keyForEnvFile, pinForEnv, gpkiapi_jni.DATA_TYPE_OTHER);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            baPriKey = gpkiAPI.baReturnArray;

            returnCode = gpkiAPI.STORAGE_ReadCert(gpkiapi_jni.MEDIA_TYPE_FILE_PATH, certForEnvFile, gpkiapi_jni.DATA_TYPE_OTHER);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            certificate = gpkiAPI.baReturnArray;

            returnCode = gpkiAPI.CMS_ProcessEnvelopedData(certificate, baPriKey, data);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            plainData = gpkiAPI.baReturnArray;

        } finally {
            if (gpkiAPI != null) {
                gpkiAPI.API_Finish();
            }
        }

        return plainData;
    }

    /**
     * 전자서명 처리.
     *
     * @see egovframework.com.sec.pki.service.EgovGPKIService#sign(byte[])
     */
    public byte[] sign(byte[] message) throws Exception {
        //-----------------------------------------
        // @PostConstruct 미사용 방식
        //-----------------------------------------
        if (config == null || gpkiAPI == null) {
            setup();
        }
        ////---------------------------------------

        //----------------------------------
        // 설정 정보 (전자서명용 인증서 정보 필요)
        //----------------------------------
        String path = EgovProperties.getProperty(config, "gpki.certificate.path");

        String certForSignFile = path + "/SVR" + EgovProperties.getProperty(config, "gpki.certificate.server") + "_sig.cer";
        String keyForSignFile = path + "/SVR" + EgovProperties.getProperty(config, "gpki.certificate.server") + "_sig.key";
        String pinForSign = EgovProperties.getProperty(config, "gpki.privatekey.password");

        //----------------------------------
        // 전자서명 처리
        //----------------------------------
        byte[] signedData = null;
        byte[] certificate = null;
        byte[] key = null;

        try {
            gpkiAPI.API_Init(".");
            int returnCode = 0;

            returnCode = gpkiAPI.STORAGE_ReadCert(gpkiapi_jni.MEDIA_TYPE_FILE_PATH, certForSignFile, gpkiapi_jni.DATA_TYPE_OTHER);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            certificate = gpkiAPI.baReturnArray;

            returnCode = gpkiAPI.STORAGE_ReadPriKey(gpkiapi_jni.MEDIA_TYPE_FILE_PATH, keyForSignFile, pinForSign, gpkiapi_jni.DATA_TYPE_OTHER);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            key = gpkiAPI.baReturnArray;

            returnCode = gpkiAPI.CMS_MakeSignedData(certificate, key, message, "");
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            signedData = gpkiAPI.baReturnArray;

        } finally {
            if (gpkiAPI != null) {
                gpkiAPI.API_Finish();
            }
        }

        return signedData;
    }

    /**
     * 전자서명 검증.
     *
     * @see egovframework.com.sec.pki.service.EgovGPKIService#verifySign(byte[])
     */
    public byte[] verifySign(byte[] signedData) throws Exception {
        //-----------------------------------------
        // @PostConstruct 미사용 방식
        //-----------------------------------------
        if (config == null || gpkiAPI == null) {
            setup();
        }
        ////---------------------------------------

        //----------------------------------
        // 전자서명 확인
        //----------------------------------
        byte[] plainData = null;

        try {
            gpkiAPI.API_Init(".");
            int returnCode = 0;

            returnCode = gpkiAPI.CMS_ProcessSignedData(signedData);
            if (returnCode != 0) {
                throw new IllegalAccessException((new StringBuffer(String.valueOf(returnCode))).toString() + " : " + gpkiAPI.sDetailErrorString);
            }
            plainData = gpkiAPI.baData;

        } finally {
            if (gpkiAPI != null) {
                gpkiAPI.API_Finish();
            }
        }

        return plainData;
    }

    /**
     * BASE64 encoding 처리.
     *
     * @see egovframework.com.sec.pki.service.EgovGPKIService#getBASE64String(byte[])
     */
    public String getBASE64String(byte[] data) throws Exception {
        return new String(Base64.encodeBase64(data));
    }

    /**
     * BASE64 decoding 처리.
     *
     * @see egovframework.com.sec.pki.service.EgovGPKIService#getDataFromBASE64(java.lang.String)
     */
    public byte[] getDataFromBASE64(String base64) throws Exception {
        return Base64.decodeBase64(base64.getBytes());
    }
}

src/main/java/egovframework/com/sec/pki/web/EgovGPKITestController.java

No search file!

src/main/java/egovframework/com/utl/sec/service/EgovCertInfoUtil.java

package egovframework.com.utl.sec.service;

import javax.servlet.http.HttpServletRequest;

import com.dsjdf.jdf.Config;
import com.dsjdf.jdf.Configuration;
import com.dsjdf.jdf.ConfigurationException;
import com.gpki.gpkiapi.cert.X509Certificate;
import com.gpki.gpkiapi.exception.GpkiApiException;
import com.gpki.gpkiapi.storage.Disk;
import com.gpki.gpkiapi.util.Base64;
import com.gpki.servlet.GPKIHttpServletRequest;

/**
 * GPKISecureWeb 인증서 로그인 서비스 유틸
 * @author 공통컴포넌트개발팀 한성곤
 * @since 2009.08.06
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *   수정일      수정자           수정내용
 *  -------    --------    ---------------------------
 *   2009.08.06  한성곤          최초 생성
 *
 * </pre>
 */
public class EgovCertInfoUtil {
    /**
     * 서버인증서에 대한 Base64 정보를 얻는다.
     *
     * @return
     * @throws ConfigurationException
     * @throws GpkiApiException
     */
    public static String getBase64ServerCert() throws ConfigurationException, GpkiApiException {
    /*
     * Configuration를 사용하기 위해서는 다음과 같은 시스템 변수 지정이 필요함
     *
     * -Dcom.dsjdf.config.file="/product/jeus/egovProps/gpkisecureweb/conf/dsjdf.properties"
     */
    Config dsjdf = new Configuration();

    String certPath = dsjdf.get("GPKISecureWeb.CertFilePathName");

    X509Certificate x509Cert = null;
    byte[] cert = null;
    String base64cert = null;

    x509Cert = Disk.readCert(certPath);
    cert = x509Cert.getCert();
    Base64 base64 = new Base64();
    base64cert = base64.encode(cert);

    return base64cert;
    }

    /**
     * 인증서에 대한 정보를 제공한다.
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static CertInfoVO getCertInfo(HttpServletRequest request) throws Exception {
    CertInfoVO certInfo = new CertInfoVO();

    GPKIHttpServletRequest gpkirequest = null;

    //System.out.println(request.getParameter("encryptedData"));

    gpkirequest = new GPKIHttpServletRequest(request);

    X509Certificate cert = gpkirequest.getSignerCert();

    certInfo.setSubjectDn(cert.getSubjectDN());
    certInfo.setIssuerDn(cert.getIssuerDN());

    return certInfo;
    }
}

src/main/java/egovframework/com/utl/sec/web/EgovCertLoginController.java

package egovframework.com.utl.sec.web;

import egovframework.com.utl.sec.service.EgovCertInfoUtil;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * GPKISecureWeb 인증서 로그인 Controller
 * @author 공통컴포넌트개발팀 한성곤
 * @since 2009.08.06
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *   수정일      수정자           수정내용
 *  -------    --------    ---------------------------
 *   2009.08.06  한성곤          최초 생성
 *
 * </pre>
 */
@Controller
public class EgovCertLoginController {
    /**
     * 인증서 로그인에 관련된 환경변수를 설정한다.
     *
     * @param type
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/utl/sec/certVar.do")
    public String var(@RequestParam(value="type", required=false) String type, Model model) throws Exception {
    String typeInfo = type;

    //------------------------------------------------------------
    // 서버 인증서 정보 처리
    //------------------------------------------------------------
    String serverCert = EgovCertInfoUtil.getBase64ServerCert();

    model.addAttribute("serverCert", serverCert);

    //------------------------------------------------------------
    // install 후 이동될 페이지 지정 (프로젝트에 맞게 수정 필요)
    //-----------------------------------------------------------
    if (typeInfo == null) {
        typeInfo = "";
    }

    String startPage = null;

    if (typeInfo.equalsIgnoreCase("login")) {
        startPage = "/utl/sec/certLogin.do";
    } else if (typeInfo.equalsIgnoreCase("regist")) {
        startPage = "/utl/sec/certInfoPopup.do";
    } else {
        startPage = "/utl/sec/certLogin.do";
    }

    model.addAttribute("startPage", startPage);

    return "egovframework/com/utl/sec/EgovCertVar";
    }

    /**
     * 인증서 관련 설치 페이지를 표시한다.
     *
     * @param type
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/utl/sec/certInstall.do")
    public String certInstall(@RequestParam(value="type", required=false) String type, Model model) throws Exception {
    String typeInfo = type;

    //------------------------------------------------------------
    // install 후 이동될 페이지 지정 (프로젝트에 맞게 수정 필요)
    //-----------------------------------------------------------
    if (typeInfo == null || typeInfo.equals("")) {
        typeInfo = "login";
    }

    model.addAttribute("type", typeInfo);

    return "egovframework/com/utl/sec/EgovCertInstall";
    }

    /**
     * 인증서 로그인 관련 설치 정보를 제공하는 설정 페이지를 표시한다.
     *
     * @return
     * @throws Exception
     */
    @RequestMapping("/utl/sec/certSetup.do")
    public String certSetup() throws Exception {
    return "egovframework/com/utl/sec/EgovCertSetup";
    }

    /**
     * 인증서 로그인 관련 오류메시지 페이지를 표시한다.
     *
     * @param errMsg
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/utl/sec/certGPKIError.do")
    public String certGPKIError(@RequestParam("errmsg") String errMsg, Model model) throws Exception {

    model.addAttribute("errmsg", errMsg);

    return "egovframework/com/utl/sec/EgovCertGPKIError";
    }

    /**
     * 인증서 DN 등록을 위한 팝업 페이지를 표시한다.
     *
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping(value="/utl/sec/certInfoPopup.do")
    public String certInfoPopup(Model model) throws Exception {

    return "egovframework/com/utl/sec/EgovCertInfoPopup";
    }

    /**
     * 인증서 로그인 페이지(테스트)를 표시한다.
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value="/utl/sec/certLogin.do", method=RequestMethod.GET)
    public String certLogin() throws Exception {

    return "egovframework/com/utl/sec/EgovCertLogin";
    }

    /**
     * 인증서 로그인 확인 페이지(테스트)를 표시한다.
     *
     * @param request
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping(value="/utl/sec/certLogin.do", method=RequestMethod.POST)
    public String certLoginConfirm(HttpServletRequest request, Model model) throws Exception {

    // 인증서 정보
    model.addAttribute("certInfo", EgovCertInfoUtil.getCertInfo(request));

    return "egovframework/com/utl/sec/EgovCertLoginConfirm";
    }

    /**
     * 인증서 등록을 위한 팝업 페이지(테스트)를 표시한다.
     *
     * @return
     * @throws Exception
     */
    @RequestMapping("/utl/sec/certLoginInfo.do")
    public String certLoginPopup() throws Exception {

    return "egovframework/com/utl/sec/EgovCertLoginInfo";
    }
}

: