NPKI(WizSign) 디바이스API 가이드 프로그램

개요

NPKI 가이드 프로그램(WizSign)은 모바일 디바이스 API 실행환경을 활용하여 하이브리드 앱을 개발 시 참고 및 활용될 수 있도록 구현된 전자정부 디바이스 API에 대한 가이드 앱으로써, 모바일 스마트 디바이스의 NPKI 관련 기능을 JavaScript 기반으로 구성 된 NPKI DeviceAPI 를 통하여 이용할 수 있도록 지원한다.

또한, 전자정부 표준프레임워크 기반의 웹 서버 어플리케이션과 연계하여 모바일기기에 저장된 인증서를 정부에서 제공하는 인증을 이용하여 인증서 인증을 하고 결과를 서버에 저장하며 인증서 인증 결과 로그를 조회하는 기능으로 구성되어 있다.

특징

본 가이드 프로그램 에서는 NPKI 기능을 가이드 할 수 있도록 모바일 기기 인증서 선택/인증하기 , 인증 로그 정보 보기 기능을 제공하고 있으며 웹 서버 어플리케이션에 표준 보안 API 를 적용하여 인증서 정보를 확인 할 수 있는 기능으로 구현되었다.

기능흐름도

기능시퀀스

전제조건

구분내용
Local 디바이스 개발 환경 전자정부표준프레임워크 개발환경3.6, Android SDK API 23(version 6.0 Marshmallow)
서버 사이드 개발 환경 전자정부표준프레임워크 개발환경3.6
Mash up Open API 연계 N/A
테스트 디바이스 Galaxy S3, G5
테스트 플랫폼 Android 2.3, Android 6.0
추가 라이브러리 적용NPKI WizSign 모듈

NPKI WizSign Library

파일명설명
libs/jldap-4.3.jar WizSign 라이브러리
libs/KSignCrypto_Applet.jar WizSign 라이브러리
libs/WizSign.jar 전자서명, 보안채널, 인증서 관련 기능들을 수행하는 핵심 라이브러리
assets/www/js/egovframework/mbl/hyb/wizsignpg.js PhoneGap기반의 Hybrid앱에서 WizSign API를 사용하기 위한 자바스크립트 인터페이스

제약사항

NPKI 기술협력에 대한 제약 사항

NPKI 디바이스 API 구성 라이브러 중 아래 코드 라이브러리는 보안 Native Module로서 라이선스를 가지고 있다. 그에 따라, 표에 기재된 라이브러리의 경우 NPKI 디바이스 API 배포 시 배포 리소스에서 제외하여 배포되고, 해당 모듈을 적용하여, 테스트 및 실제 구현을 진행하고자 하는 정부기관이나, 업체에서는 아래 기술협력 업체로 연락 문의해야 한다.

업체명담당자연락처E-Mail
(주)케이사인신동수 선임02-564-0182 men4u@ksign.com

전자정부 보안표준 API 적용을 위한 방법

전자정부 보안표준 API를 사용하기 위해서는 별도로 보안표준 API를 신청하여야 하며, 이는 행정전자서명 인증관리센터(http://www.gpki.go.kr)에서 주관하고 있다.

서비스 신청 방법은 다음과 같다.

▶ 표준 API 보급관리시스템 접속이 가능한 경우
ㅇ [표준API보급관리시스템] 에서 웹으로 API신청(공문, 구성도 첨부)
ㅇ 서비스 URL : http://api.gpki.go.kr
공문은 한국지역정보개발원 - 지역정보센터 - 정보기반과로 보내주면 된다.
공문 내용은 업무시스템명, 담당자, 연락처 및 표준 API 를 신청한다는 내용.
- 해당서비스는 행정망에서만 이용가능함 -

▶ 외부망 (http://api.gpki.go.kr 접속 불가) 일경우
ㅇ 행정전자서명 인증관리센터(http://www.gpki.go.kr) 사이트의 “자료실-인증서신청관련양식-7.표준 API 신청방법 및 표준 API 신청서”에 있는 표준 API 신청서를 작성하셔서 공문과 함께 신청서를 보내주면 된다.
공문 수신처 : 한국지역정보개발원 - 지역정보센터 - 정보기반과
공문 내용은 업무시스템명, 담당자, 연락처 및 표준 API 를 신청한다는 내용.

기타 자세한 정보 확인 및 문의는 행정전자서명 인증관리센터(http://www.gpki.go.kr)를 참고한다.

지원 디바이스 및 플랫폼

N/A

크로스 도메인 사용

폰갭에서 특정 외부 도메인이나 외부 도메인의 하위 도메인을 사용해야할 경우,
Res/xml/config.xml에서 <access origin=”” />에 외부 도메인 주소를 추가 설정해야 외부 도메인에 접속할 수 있다.

설명

NPKI 디바이스API 가이드 프로그램은 크게 모바일 기기내의 인증서를 선택 및 서명 데이터를 만들어 웹 서버 어플리케이션으로 전송하여 인증서 인증하는 기능과 인증서 인증된 로그 데이터를 조회하는 기능으로 구성되어 있다.(관련기능 부분참조)

관련 클래스다이어그램

Device Application

관련 소스

유형대상소스명비고
Activitykr.go.egovframework.hyb.pkiapi.wizsign.PKIWizSignAPIGuide_AndroidActivityNPKI 가이드 프로그램 Activity Class
CSSassets/www/css/egovframwork/mbl/hyb/PKIWizSignAPI.css NPKIAPI 가이드 프로그램 주요 Cascading Style Sheets
IMAGE assets/www/images/egovframwork/mbl/hyb/ NPKIAPI 가이드 프로그램 주요 Image 폴더
JS assets/www/js/egovframwork/mbl/hyb/PKIWizSignAPI.js NPKIAPI 가이드 프로그램 주요 JavaScript
JS assets/www/js/egovframwork/mbl/hyb/wizsignpg.js NPKIAPI 가이드 프로그램 주요 JavaScript
JS assets/www/js/egovframwork/mbl/hyb/messages_ko.js Validate 메세지 처리 JavaScript
RES assets/www/res/ NPKIAPI 가이드 프로그램 주요 Resource 폴더
XML AndroidManiFest.xml 안드로이드 어플리케이션 설정 XML
HTMLassets/www/PKIWizSignAPI.htmlNPKIAPI 메인 페이지
HTMLassets/www/Intro.htmlNPKIAPI Intro 페이지
HTMLassets/www/license.htmlNPKIAPI 라이센스 페이지
HTMLassets/www/overview.htmlNPKIAPI 기능설명 페이지

전체 기능 API

가이드프로그램에서 활용한 API

doSignature
  • 선택한 인증서로 전자서명을 수행하여 서명값을 반환한다.

- 파라메터 : 인증서 번호, 인증서 비밀번호, 서명대상 원문
- 반환값(해시 테이블)

'signedData' : 서명데이터
'errMsg' : 에러 발생시 에러메시지
var args = new Array();
args[0] = selectCertNum.toString() ;
args[1] = '1';
args[2] = stringToSign;

WizSignPG.doSignature(args, function(result) {
        var signedData = result['signedData'];	// 서명데이터
    }, function(error) {
        alert(error['errMsg']);	// 에러메시지
});
getCertificates
  • 저장된 인증서목록을 가져와 반환한다.

- 파라메터 : N/A
- 반환값(해시 테이블)

'Certificates' : 인증서 목록
'errMsg' : 에러 발생시 에러메시지
WizSignPG.getCertificates("", function(result) {
    var certList = result['Certificates'];

    for(var i=0 ; i<certList.length ; i++) {
        certList[i]['NUM'];
        certList[i]['주체자'];
        certList[i]['발급자'];
        certList[i]['만료일'];
    }

    }, function(error) {
        alert("error['errMsg']);
});

인증서 정보 해시테이블

해시테이블설명
NUM인증서 번호
버전인증서 버전
일련번호인증서 시리얼번호
서명알고리즘인증서 서명알고리즘
발급자인증서의 발급자 정보
효력발생일인증서의 효력 발생일
만료일인증서 만료일
주체자인증서 주체자 정보
공개키알고리즘인증서 공개키 알고리즘
발급자시리얼번호발급자시리얼번호
공개키공개키값
기관키식별자기관키식별자
주체자식별자주체자식별자
정책정책
주체대체이름주체대체이름
CRL분배지점CRL분배지점
기관정보액세스기관정보액세스(OCSP)
키사용키사용용도
서명인증서 서명값
verifyCertPassword
  • 선택한 인증서의 비밀번호를 검증한다.

- 파라메터 : 인증서 번호, 인증서 비밀번호
- 반환값(해시 테이블)

'result' : 인증서 비밀번호 검증결과(성공시 'OK')
'errMsg' : 에러 발생시 에러메시지
var args = new Array();
args[0] = certNum.toString();
args[1] = certPass;

WizSignPG.verifyCertPassword(args, function(result) {
    var runResult = result['result'];

    if(runResult == 'OK') {
        alert('인증서 비밀번호가 일치합니다.');	
    }
			
    }, function(error) {
    alert(error['errMsg']);
});

Server Application

관련 소스

유형대상소스명비고
Controlleregovframework.hyb.add.pki.web.EgovPKIAndroidAPIController.javaNPKIAPI 가이드 프로그램 Controller Class
Serviceegovframework.hyb.add.pki.service.EgovPKIAndroidAPIService.javaNPKIAPI 가이드 프로그램 Service Class
ServiceIimplegovframework.hyb.add.pki.service.impl.EgovPKIAndroidAPIServiceImpl.javaNPKIAPI 가이드 프로그램 ServiceImpl Class
VOegovframework.hyb.add.pki.service.PKIAndroidAPIDefaultVO.javaNPKIAPI 가이드 프로그램 VO Class
VOegovframework.hyb.add.pki.service.PKIAndroidAPIVO.javaNPKIAPI 가이드 프로그램 VO Class
VOegovframework.hyb.add.pki.service.PKIAndroidAPIXmlVO.javaNPKIAPI 가이드 프로그램 XML 관련 VO Class
DAOegovframework.hyb.add.pki.service.impl.PKIAndroidAPIDAO.javaNPKIAPI 가이드 프로그램 Dao Class
QUERY XMLresources/egovframework/sqlmap/hyb/add/pki/EgovPKIAndroidAPIGuide_SQL_XXX.xmlNPKIAPI 가이드 프로그램 QUERY XML
Idgen XMLresources/egovframework/spring/context-idgen.xmlNPKIAPI 가이드 프로그램 Id생성 Idgen XML

관련 테이블

테이블명테이블명(영문)비고
PKIPKI인증서 인증 로그 관리

테이블 명세서

  • PKI
No.컬럼컬럼명타입길이NullKEY
1SN일련번호NUMERIC6NotNullpk
2UUIDUUIDVARCHAR50NotNullpk
3DMDMVARCHAR255Null
4CRTFC_DT인증일시DATE Null
5ENTRPRS_SE_CODE이메일DATE Null

ERD

표준 보안 API

public String verifyCert(PKIAndroidAPIVO pkiVo) throws Exception {
    // API 초기화
    GpkiApi.init("C:/libgpkiapi_jni/conf");
    String sign;
    sign = pkiVo.getSign();	
    return verify(Base64.decode(sign));   	
}

private String verify(final byte[] bSignedData)  {
    String sClientName = "";
    try {
        // 서명값을 검증
        SignedData signedData = null;
        signedData = new SignedData();			
        signedData.verify(bSignedData);		
			
        // 서명자의 인증서 검증을 위해서 서버의 서명용 인증서 획득
        X509Certificate clientCert = null;
        clientCert = signedData.getSignerCert(0);
	
        // 인증서 검증
        CertPathValidator certPathValiditor = null;
        certPathValiditor = new CertPathValidator("C:/libgpkiapi_jni/conf/gpkiapi.conf");
			
        // 신뢰하는 최상위 인증서 추가
        X509Certificate rootCertRsa = null;
        rootCertRsa = Disk.readCert("C:/libgpkiapi_jni/conf/root-rsa2.der");
        X509Certificate rootCertRsaSha = null;
        rootCertRsaSha = Disk.readCert("C:/libgpkiapi_jni/conf/root-rsa-sha2.der");
        certPathValiditor.addTrustedRootCert(rootCertRsa);
        certPathValiditor.addTrustedRootCert(rootCertRsaSha);			
			
        // 클라이언트의 인증서 검증 범위 설정
        certPathValiditor.setVerifyRange(CertPathValidator.CERT_VERIFY_FULL_PATH);
			
        // 클라이언트의 인증서 폐지여부 확인 설정 (CRL/ARL 검증 설정함)
        certPathValiditor.setRevokationCheck(CertPathValidator.REVOKE_CHECK_ARL | CertPathValidator.REVOKE_CHECK_CRL);
			
        // 인증서 검증 요청
        certPathValiditor.validate(CertPathValidator.CERT_SIGN, clientCert);	
					
        sClientName = clientCert.getSubjectDN();			
			
			
    } catch (Exception e) {			
        sClientName = "";
    }
    return sClientName;
}

환경설정

NPKI 디바이스API 가이드 프로그램에서 제공하는 모바일 디바이스의 NPKI 관련 기능을 활용하기 위하여 필요한 항목 및 그 환경 설정은 다음과 같다.

Device Application

res/xml/config.xml

    <!--전자정부 Interface 디바이스 API를 사용하기 위한 Phonegap Plugin 클래스-->
    <plugin name="EgovInterfacePlugin" value="kr.go.egovframework.hyb.plugin.EgovInterfacePlugin" />
    <!--전자정부 NPKI 디바이스 API를 사용하기 위한 Phonegap Plugin 클래스-->
    <plugin name="WizSignPG" value="com.ksign.wizsign.sdk.wizsignAPI.WizSignPG"/>

res/values/serverinfo.xml

    <!--전자정부 Interface 디바이스 API에서 사용하기 위한 서버경로 설정-->
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
	<string name="SERVER_URL">http://192.168.100.222:8080/DeviceAPIGuideTotal_Web_V1.7.1</string>
    </resources>

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Server Application

pom.xml

<dependency>
	<groupId>egovframework.com.cmm.uat</groupId>
	<artifactId>libgpkiapi_jni</artifactId>
	<version>1.4.0.0</version>
</dependency>

resource/egovframework/sqlmap/sql-map-config_[DB명].xml

<sqlMap resource="egovframework/sqlmap/hyb/add/dvc/EgovPKIAndroidAPIGuide_SQL_[DB명].xml"/>
  • 표준 보안 API 설정
구분설정방법
Class 경로 설정방법 1. java 옵션 이용 : java -classpath jar_directory\libgpkiapi_jni.jar
방법 2. 환경 변수 등록 : “내컴퓨터→속성→고급→환경변수” 에서 새로 만들기를 클릭하여 classpath 변수를 등록

구분설정방법
라이브러리 경로 설정1. JNI를 비롯한 C/C++용 표준보안API와 LDAP 라이브러리가 위치해 있는 경로를 환경 변수에 등록한다.
2. “내컴퓨터→속성→고급→환경변수” 에서 기존 “path” 변수에 “라이브러리가 설치된 디렉토리”를 추가한다.

관련기능

NPKI 디바이스 API 가이드는 크게 모바일 기기 인증서 선택/인증하기 , 인증 로그 정보 보기 기능으로 구성되어있다.

모바일 기기 인증서 선택/인증하기

비즈니스 규칙

디바이스 API를 통해 모바일 기기에 저장된 인증서 리스트를 조회하고, 리스트에서 선택 한 인증서로 인증서 인증을 한다.

관련코드

디바이스 API 내의 인증서 리스트 조회 함수를 사용하는 JavaScript 코드를 통해 인증서 리스트를 조회 하고, 서명 데이터를 만드는 JavaScript 함수를 사용하여 서명 한다.

// 인증서 리스트 조회
function fn_egov_go_certlist() {    
    console.log('DeviceAPIGuide fn_egov_go_certlist');
    WizSignPG.getCertificates(fn_egov_getcertlistSuccess,fn_egov_getcertlistFail);
}

// 인증서 비밀번호 확인
function fn_egov_confirm_password() {		
    console.log('DeviceAPIGuide fn_egov_confirm_password');

    var args = new Array();
    args[0] = Number(document.getElementById("xsigncertindex").value) + 1
    args[1] = $("#loginPasswd").val();
	
    WizSignPG.verifyCertPassword(args, function(result) {
        console.log('DeviceAPIGuide fn_egov_confirm_password Success');
        //Certificates
        var runResult = result['result'];
        var error = result['errMsg'];
		
        if(error!=null){
            alert(error);
            alert(runResult);
        }
		
        if(runResult == 'OK') {
            alert('인증서 비밀번호가 일치합니다.');	
            fn_egov_make_sign();
        }				
					
        }, function(error) {
            console.log('DeviceAPIGuide fn_egov_confirm_password Fail');
            alert("Error: \r\n" + error['errMsg']);
    });
}

// 인증서 서명
function fn_egov_make_sign()
{
    console.log('DeviceAPIGuide fn_egov_make_sign');
    var args = new Array();
    args[0] = Number(document.getElementById("xsigncertindex").value) + 1
    args[1] = $("#loginPasswd").val();
    args[2] = "usrId=&password=&name=";
					
    WizSignPG.doSignature(args, fn_egov_makesign_ok, fn_egov_makesign_fail);
}

// 인증서 서명 데이터 서버로 인증 요청
function fn_egov_makesign_ok(arg)
{
    console.log('DeviceAPIGuide fn_egov_makesign_ok Success');
    var jsonobj = JSON.parse(arg);
	
    // jsonobj.sign에서 서면 값, jsonobj.vidRandom에서 본인확인을 위한 VID Random값을 가져올 수 있다.
    var signedData = jsonobj.sign;	
    
    var url = "/pki/xml/addPKIInfo.do";
    var acceptType = "xml";
    var params = {uuid :  device.uuid,			
		  sign: signedData,
		  entrprsSeCode: 'PKI02'};
    alert('Http Method:POST\nacceptType:'+ acceptType + '\n요청데이터:' + JSON.stringify(params));
	
    // get the data from server
    window.plugins.EgovInterface.post(url,acceptType, params, function(xmldata) {		
        console.log('DeviceAPIGuide fn_egov_makesign_ok request Complete');
        alert('응답데이터:' + xmldata)
        if($(xmldata).find("resultState").text() == "OK"){				
            window.history.go(-2);
        }else{
            jAlert($(xmldata).find("resultMessage").text(), '오류', 'c');
        }
    });	
}

관련화면 및 수행매뉴얼

ActionURLController methodQueryID
인증서 인증/pki/xml/addPKIInfo.doaddPKIInfoXml“PKIAndroidAPIDAO.insertPKIInfo”
인증서 리스트인증서 인증

인증서 리스트 화면에서 인증 할 인증서를 선택하고 인증서 인증 화면에서 PASSWD 항목에 패스워드를 입력 후 “인증 확인” 버튼을 클릭한다.
단, PASSWD 항목에서 validation을 확인하고, 조건이 불충분 할 경우 오류 메시지가 출력된다.

인증 확인 : 인증서 인증을 하기 위해서 PASSWD 항목에 인증서 패스워드를 입력 후 “인증 확인” 버튼을 클릭한다.
Back 버튼 : NPKI 디바이스 API 가이드 프로그램 메뉴 화면 또는 인증서 리스트 화면으로 이동한다.

인증 로그 정보 보기

비즈니스 규칙

웹 서버 어플리케이션으로 부터 인증서 인증 결과 로그를 조회한다.

관련코드

function fn_egov_go_loginInfoList() {
    console.log('DeviceAPIGuide fn_egov_go_loginInfoList');
    //3G 사용시 과금이 발생 할 수 있다는 경고 메시지 표시
    if(!fn_egov_network_check(false)) {
    	return;
    }
    
    $.mobile.changePage("#loginInfoList", "slide", false, false);
	
    var url = "/pki/xml/pkiInfoList.do";
    var accept_type = "xml";
    // get the data from server
    window.plugins.EgovInterface.post(url,accept_type, null, function(xmldata) {
        console.log('DeviceAPIGuide fn_egov_go_loginInfoList request Complete');
        var list_html = "";		
        $(xmldata).find("pkiInfoList").each(function(){
            var dn = $(this).find("dn").text();
            var date = $(this).find("crtfcDt").text();
            var entrprsSeCode = $(this).find("entrprsSeCode").text().replace(/\s+$/, "");
            var entrprsSe = "NONE";
            if(entrprsSeCode == 'PKI01')
                entrprsSe = "MagicXSign";
            else if(entrprsSeCode == 'PKI02')
                entrprsSe = "WizSign";
            else if(entrprsSeCode == 'PKI03')
                entrprsSe = "XecureSmart";

            list_html += "<li><h3>subjdn : " + dn + "</h3>";
            list_html += "<p><strong>Date : " + date + "</strong></p>";						
            list_html += "<p><strong>NPKI : " + entrprsSe + "</strong></p></li>";
        });
        var theList = $('#theLogList');
        theList.html(list_html);				
        theList.listview("refresh"); 
        setTimeout(loadiScrollList, 1000);	
    });
}

관련화면 및 수행매뉴얼

기능URLControllermethodQueryID
인증서 인증 결과 로그 조회/pki/xml/pkiInfoList.doEgovPKIAndroidAPIControllerselectPKIInfoListXmlPKIAndroidAPIDAO.selectPKIInfoList

컴파일 디버깅 배포

컴파일

Device Applicaton 컴파일 방법

  • 프로젝트 선택 > 오른쪽 클릭 > Run As > Android Application

  • 상단의 메뉴 > Run As > Android Application

  • 실행할 타겟 선택 > 에뮬레이터, 디바이스(디버깅모드)

  • 디바이스를 이용한 실행 화면

Server Applicaton 컴파일 방법

  • 서버사이드 가이드 프로그램의 실행은 프로젝트를 마우스 오른쪽 버튼을 클릭 한후 Run As>Run On Server 버튼을 통해 실행 할 수 있다.

  • 빌드가 성공적으로 수행 되면 이클립스의 콘솔 창에서 'Server Startup in xxx ms' 메시지를 확인 할 수 있다.

디버깅

디바이스 어플리케이션에서 발생한 오류 내용 확인 및 디버깅을 위해서는 폰갭 프레임워크에서 제공하는 console.log를 이용할 수 있다. console.log 함수는 자바스크립트 구문에서 사용할 수 있는 디버그 코드로 이클립스에서 확인 할 수 있다.

console.log의 작성 방법은 다음과 같다.

function fn_egov_getcertlistSuccess(result) 
{
    console.log('DeviceAPIGuide fn_egov_getcertlistSuccess Success');
    g_certList = result['Certificates'];
    var list_html = "";
    ....
}

디버깅 코드가 실행 되면 아래와 같은 메시지를 개발도구의 콘솔 메시지 창에서 볼 수 있다.

NPKI 디바이스 API 가이드 프로그램 에서는 디버깅을 위하여 다음과 같이 콘솔 정보를 출력한다.

디버그 코드디버깅 내용
DeviceAPIGuide fn_egov_getcertlistSuccess Success 인증서 리스트 조회 성공 시
DeviceAPIGuide fn_egov_getcertlistFail Fail 인증서 리스트 조회 실패 시
DeviceAPIGuide fn_egov_confirm_password Success 인증서 비밀번호 확인 성공 시
DeviceAPIGuide fn_egov_confirm_password Fail 인증서 비밀번호 확인 실패 시
DeviceAPIGuide fn_egov_makesign_ok Success 인증서 서명 성공 시
DeviceAPIGuide fn_egov_makesign_fail Fail 인증서 서명 실패 시
DeviceAPIGuide fn_egov_makesign_ok request Complete 웹 서버 어플리케이션으로 부터 인증서 인증 성공 시
DeviceAPIGuide fn_egov_go_loginInfoList request Complete 인증서 인증 로그 정보 조회 성공 시

배포

NPKI(WizSign) 디바이스 API 가이드 다운로드 : Click

참고자료

  • Cordova : Click
  • UX/UI 라이브러리 : jQuery MobileClick
  • 표준보안API : Click
  • NPKIAPI : (주)케이사인 Click
 
egovframework/hyb3.9/guide/add/npki_wizsign.txt · 마지막 수정: 2023/12/21 05:21 (외부 편집기)
 
이 위키의 내용은 다음의 라이센스에 따릅니다 :CC Attribution-Noncommercial-Share Alike 3.0 Unported
전자정부 표준프레임워크 라이센스(바로가기)

전자정부 표준프레임워크 활용의 안정성 보장을 위해 위험성을 지속적으로 모니터링하고 있으나, 오픈소스의 특성상 문제가 발생할 수 있습니다.
전자정부 표준프레임워크는 Apache 2.0 라이선스를 따르고 있는 오픈소스 프로그램입니다. Apache 2.0 라이선스에 따라 표준프레임워크를 활용하여 발생된 업무중단, 컴퓨터 고장 또는 오동작으로 인한 손해 등에 대해서 책임이 없습니다.
Recent changes RSS feed CC Attribution-Noncommercial-Share Alike 3.0 Unported Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki