document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
* 문제 : iScroll4 컨텐츠 내용 높이 계산 오류.
* 해결방안 : setTimeout() 함수로 컨텐츠에 css 적용이 완료되고 iscroll 생성이 되도록 한다.
setTimeout(function()
{
myScroll = new iScroll(thisPage,
{
checkDOMChanges: true,
onBeforeScrollStart:function(e)
{
}
});
},
500);
== CallBack 함수에서 alert() 를 포함하면 문제가 발생할수 있다 (phoneGap) ==
* 문제 : 폰갭에 지정한 콜백 함수에서 alert() 메시지 호출시 동작 오류.
* 해결 방안 : 비동기 함수를 사용하거나 alert()처럼 스레드를 잡는 함수는 사용하지 않는다.
== Xcode 4.5에서 실행 시 주의 사항 ==
Xcode 4.5부터 iOS 6, iPhone 5를 지원하는데, 해당 디바이스와 OS를 지원을 할 경우 PhoneGap 1.9.0의 라이브러리는 Xcode 4.X에서 컴파일되어 배포되는 라이브러리라 프로젝트 옵션을 조정할 필요가 있다.\\
1. 옵션 설정\\
{{:egovframework:hyb:guide:ios:xcode4.5_제약사항1.png|}}
2. armv7s 삭제\\
{{:egovframework:hyb:guide:ios:xcode4.5_제약사항2.png|}}
=== 크로스 도메인 사용 ===
폰갭에서 특정 외부 도메인이나 외부 도메인의 하위 도메인을 사용해야할 경우,\\ Resource/Cordova.plist에서
window.plugins.magicxsign.init(var Flag)
^Option^설명^비고^
|Flag|MagicXSign Debug 출력 여부|true:디버그 출력, false:디버그 출력 안함|
window.plugins.magicxsign.init("false");
window.plugins.magicxsign.init("true");
== window.plugins.magicxsign.getcertlist ==
* 단말의 인증서를 jsonString 형식으로 맞추어서 읽어온다.
window.plugins.magicxsign.getcertlist( success return , fail return, jsonString);
^Option^설명^비고^
|success return|성공시 리턴되는 함수| |
|fail return|실패시 리턴되는 함수| |
|jsonString|인증서의 정보 요청| |
== jsonString ==
* 조회 할 인증서의 정보
^속성^내용^속성^내용^
|issuer|인증서 발급 기관|name|사용자이름|
|ver|버전|sn|일련번호|
|issuedn|발급자|start|만료일(시작)|
|end|만료일(끝)|subjdn|주체자|
|pubkeyalgo|공개키 알고리즘|pubkey|공개키|
|aia|기관 정보 접근|aki|발급자 키식별자|
|ski|주체자 키식별자|keyuse|키사용|
|policy|정책|policyid|정책 ID|
|subaltname|주체 대채이름|crl|CRL 위치|
var setDefine = ["oidname","issuer","name","subjdn","start","end"];
window.plugins.magicxsign.getcertlist(getcertlistSuccess, getcertlistFail, JSON.stringify(setDefine));
== window.plugins.magicxsign.certdel ==
* 인증서를 삭제 한다.
window.plugins.magicxsign.certdel(success return, fail return, Cert Index);
^Option^설명^비고^
|success return|성공시 리턴되는 함수| |
|fail return|실패시 리턴되는 함수| |
|Cert Index|인증서 Index(0 부터 시작)|window.plugins.magicxsign.getcertlist 호출에 대한 결과 index 값|
window.plugins.magicxsign.certdel(certdelSuccess, certdelFail, 0);
== window.plugins.magicxsign.certchagepassword ==
* 인증서의 비밀번호를 변경한다.
window.plugins.magicxsing.certchagepassword(success return, fail return, jsonString);
^Option^설명^비고^
|success return|성공시 리턴되는 함수| |
|fail return|실패시 리턴되는 함수| |
|jsonString|인증서 Index, 구/신 비밀번호를 jsonString 전달| |
var setDefine = {};
setDefine["certindex"] = iCertIndex; //선택된 인증서 index
setDefine["oldpassword"] = oldpassword; //선택된 인증서 Password
setDefine["newpassword"] = newpassword; //신규 인증서 Password
window.plugins.magicxsing.certchagepassword(certchagepasswordSuccess, certchagepasswordFail, JSON.stringify(setDefine));
== window.plugins.magicxsign.makesign ==
* 서명 데이터를 생성한다.
window.plugins.magicxsing.makesign(success return, fail return, jsonString);
^Option^설명^비고^
|success return|성공시 리턴되는 함수| |
|fail return|실패시 리턴되는 함수| |
|jsonString|인증서 Index, 구/신 비밀번호를 jsonString 전달| |
var setDefine = {};
setDefine["plaintext"] = encodeURIComplnent(MagicXSign_makeQueryString(form));
setDefine["url"] = sURL;
setDefine["certindex"] = document.getElementById("xsigncertindex").value;
setDefine["certpassword"] = document.getElementById("xsigncertpassword").value;
window.plugins.magicxsign.makesign(makesign_ok, makesign_fail, JSON.stringify(setDefine));
== window.plugins.magicxsign.mrs_makecode ==
* 인증서버에 접속 하여 인증번호를 얻어온다.
window.plugins.magicxsign.mrs_makecode(success return, fail return, jsonString);
^Option^설명^비고^
|success return|성공시 리턴되는 함수| |
|fail return|실패시 리턴되는 함수| |
|jsonString|phoneno, serverip, serverport, serviceid 형태의 Json String| |
var setDefine = {};
setDefine["phoneno"] = "123456789";
setDefine["serverip"] = "125.141.204.173";
setDefine["serverport"] = "10001";
setDefine["serviceid"] = "dreamAPP";
window.plugins.magicxsign.makesign(makesign_ok, makesign_fail, JSON.stringify(setDefine));
== window.plugins.magicxsign.mrs_waitcert ==
* 인증서를 전송 받아 저장하고 인증서 정보를 리턴한다.
window.plugins.magicxsign.mrs_makecode(success return, fail return, jsonString);
^Option^설명^비고^
|success return|성공시 리턴되는 함수| |
|fail return|실패시 리턴되는 함수| |
|jsonString|얻어온 인증서의 정보 보기용|certlist 함수 참조|
var setDefine = ["oidname","issuer","name","subjdn","start","end"]
window.plugins.magicxsign.mrs_waitcert(getcertlistSuccess, getcertlistFail, JSON.stringify(setDefine));
== window.plugins.magicxsign.mrs_stopcertmove ==
* 인증서 이동을 중지한다.
window.plugins.magicxsign.mrs_stopcertmove();
== window.plugins.magicxsign.ollecert_check ==
* 올레인증서가 인스톨 되어 있는지 확인한다.
^Option^설명^비고^
|success return|올레인증서가 설치되어있음| |
|fail return|올레인증서가 설치되어있지않음| |
window.plugins.magicxsign.ollecert_check(ollecert_Check_Success, ollecert_Check_Fail);
== window.plugins.magicxsign.ollecert_install ==
* 올레인증서 인스톨을 위해 AppStore의 올레인증서 인스톨 화면 호출
window.plugins.magicxsign.ollecert_install();
== window.plugins.magicxsign.ollecert_getcert ==
* 올레인증서에서 인증서를 요청하여 선택된 인증서를 저장한다.
^Option^설명^비고^
|Yes return|성공시 리턴|JsonString - handshake필드로 생성된 HandShake정보를 리턴|
|No return|오류시 리턴| |
|jsonString|얻어온 인증서의 정보 보기용|certlist 함수 참조|
var setDefine = ["oidname","issuer","name","subjdn","start","end"];
window.plugins.magicxsign.ollecert_getcert(certGetFromOlleCert_Success, certGetFromOlleCert_Fail, JSON.stringify(setDefine));
==== Server Application ====
=== 관련 소스 ===
^유형^대상소스명^비고^
|Controller|egovframework.hyb.ios.pki.web.EgovPKIiOSAPIController.java|NPKIAPI 가이드 프로그램 Controller Class|
|Service|egovframework.hyb.ios.pki.service.EgovPKIiOSAPIService.java|NPKIAPI 가이드 프로그램 Service Class|
|ServiceIimpl|egovframework.hyb.ios.pki.service.impl.EgovPKIiOSAPIServiceImpl.java|NPKIAPI 가이드 프로그램 ServiceImpl Class|
|VO|egovframework.hyb.ios.pki.service.PKIiOSAPIDefaultVO.java|NPKIAPI 가이드 프로그램 VO Class|
|VO|egovframework.hyb.ios.pki.service.PKIiOSAPIVO.java|NPKIAPI 가이드 프로그램 VO Class|
|VO|egovframework.hyb.ios.pki.service.PKIiOSAPIXmlVO.java|NPKIAPI 가이드 프로그램 XML 관련 VO Class|
|DAO|egovframework.hyb.ios.pki.service.impl.PKIiOSAPIDAO.java|NPKIAPI 가이드 프로그램 Dao Class|
|QUERY XML|resources/egovframework/sqlmap/hyb/ios/pki/EgovPKIiOSAPIGuide_SQL_XXX.xml|NPKIAPI 가이드 프로그램 QUERY XML|
|Idgen XML|resources/egovframework/spring/context-idgen.xml|NPKIAPI 가이드 프로그램 Id생성 Idgen XML|
=== 관련 테이블 ===
^테이블명^테이블명(영문)^비고^
|PKI|PKI|인증서 인증 로그 관리|
=== 테이블 정의서 ===
* PKI
^No^컬럼ID^컬럼명^타입^길이^Null^
|1|SN|일련번호|NUMERIC|6|NotNull|
|2|UUID|UUID|VARCHAR|50|NotNull|
|3|DN|인증데이터|VARCHAR|255|Null|
|4|CFTFC_DT|인증날짜시간|DATETIME| |Null|
|5|ENTRPRS_SE_CODE|업체구분|CHAR|15|Null|
=== ERD ===
{{:egovframework:hyb:guide:ios:erd.jpg|}}
=== 표준 보안 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 ====
=== Cordova.plist ===
Plugins
InterfaceAPI
EgovInterface
MagicXSignPlugin
MagicXSignPlugin
=== eGovModule/EGovComModule.h ===
#define kSERVER_URL @"http://192.168.100.222:8080/DeviceAPIGuideTotal_Web_V1.7.1"
==== Server Application ====
=== resource/egovframework/sqlmap/sql-map-config_[DB명].xml ===
=== 표준 보안 API ===
설정 참조
===== 관련기능 =====
NPKI 디바이스 API 가이드는 크게 ** 모바일 기기 인증서 선택/인증하기 **, ** 인증 로그 정보 보기 ** 기능으로 구성되어있다.
==== 모바일 기기 인증서 선택/인증하기 ====
=== 비즈니스 규칙 ===
디바이스 API를 통해 모바일 기기에 저장된 인증서 리스트를 조회하고, 리스트에서 선택 한 인증서로 인증서 인증을 한다.
=== 관련코드 ===
디바이스 API 내의 인증서 리스트 조회 함수를 사용하는 JavaScript 코드를 통해 인증서 리스트를 조회 하고, 서명 데이터를 만드는 JavaScript 함수를 사용하여 서명 한다.
// 인증서 리스트 조회
function fn_egov_show_certlist()
{
console.log('DeviceAPIGuide fn_egov_show_certlist');
$.mobile.showPageLoadingMsg('a');
var setDefine = ["oidname","issuer","name","subjdn","start","end"];
// setDefine 에 지정된 리스트로 데이타를 요청한다
window.plugins.magicxsign.getcertlist(fn_egov_getcertlistSuccess, fn_egov_getcertlistFail, JSON.stringify(setDefine));
}
// 인증서 서명
function fn_egov_login_member() {
console.log('fn_egov_login_member()');
$.mobile.showPageLoadingMsg('a');
var setDefine = {};
setDefine["plaintext"]=encodeURIComponent("usrId=&password=&name="); // form Data
setDefine["certindex"]=document.getElementById("xsigncertindex").value; // 선택된 인증서 INDEX
setDefine["certpassword"]=$("#loginPasswd").val(); // 선택된 인증서 Password
window.plugins.magicxsign.makesign(fn_egov_makesign_ok, fn_egov_makesign_fail, JSON.stringify(setDefine));
}
// 인증서 서명 데이터 서버로 인증 요청
function fn_egov_makesign_ok(arg)
{
console.log('DeviceAPIGuide fn_egov_makesign_ok');
var jsonobj = JSON.parse(arg);
var signedData = jsonobj.sign;
var vidRandom = jsonobj.vidRandom;
var acceptType = "json";
var params = { uuid : device.uuid,
sign : signedData,
entrprsSeCode : "PKI01"};
alert('Http Method:POST\nAcceptType:JSON\n전송데이터:' + JSON.stringify(params));
$.mobile.showPageLoadingMsg('a');
EgovInterface.submitAsynchronous(
[params, "/pki/addPKIiOSInfo.do"],
function(result) {
console.log("PKIMagicXSignAPIGuide fn_egov_makesign_ok Completed");
var str = '{';
for (myKey in result){
str += myKey + ':' + result[myKey] + '\n';
}
str += '}';
alert('응답방식:RESTful\n응답Type:json, post\nParam:\n' + str);
//window.history.back();
$.mobile.hidePageLoadingMsg('a');
location.href = "index.html";
},
function(error) {
console.log("PKIMagicXSignAPIGuide fn_egov_makesign_ok Failed");
var str = '{';
for (myKey in result){
str += myKey + ' : ' + result[myKey] + '\n';
}
str += '}';
$.mobile.hidePageLoadingMsg('a');
alert('응답방식:RESTful\n전송Type:json, post\nParam:\n' + str);
}
);
document.getElementById("innerhtmlArea").innerHTML= "SendResult :
"+str+"
";
}
//올레인증서가 설치되어있는지 확인
function fn_egov_check_ollecert()
{
console.log('fn_egov_check_ollecert()');
window.plugins.magicxsign.ollecert_check(fn_egov_ollecert_Check_Success, fn_egov_ollecert_Check_Fail);
}
//올레인증서 호출
function fn_egov_certGetFromOlleCert()
{
console.log('fn_egov_certGetFromOlleCert()');
var setDefine = ["oidname","issuer","name","subjdn","start","end"];
window.plugins.magicxsign.ollecert_getcert( fn_egov_certGetFromOlleCert_Success, fn_egov_certGetFromOlleCert_Fail, JSON.stringify(setDefine) );
}
=== 관련화면 및 수행매뉴얼 ===
^Action^URL^Controller method^QueryID^
|인증서 인증|/pki/addPKIiOSInfo.do|addPKIInfo|"PKIiOSAPIDAO.insertPKIInfo"|
^인증서 리스트^인증서 인증^
|{{:egovframework:hyb:guide:ios:magic_cert_list.png|}}|{{:egovframework:hyb:guide:ios:magic_log2.png|}}|
인증서 리스트 화면에서 인증 할 인증서를 선택하고 인증서 인증 화면에서 PASSWD 항목에 패스워드를 입력 후 "인증 확인" 버튼을 클릭한다. \\
단, PASSWD 항목에서 validation을 확인하고, 조건이 불충분 할 경우 오류 메시지가 출력된다.
인증 확인 : 인증서 인증을 하기 위해서 PASSWD 항목에 인증서 패스워드를 입력 후 "인증 확인" 버튼을 클릭한다. \\
Back 버튼 : **NPKI 디바이스 API 가이드 프로그램 메뉴** 화면 또는 **인증서 리스트** 화면으로 이동한다. \\
==== 인증 로그 정보 보기 ====
=== 비즈니스 규칙 ===
웹 서버 어플리케이션으로 부터 인증서 인증 결과 로그를 조회한다. \\
=== 관련코드 ===
function fn_goLoginInfoList()
{
console.log('fn_goLoginInfoList()');
var accept_type = "json";
// get the data from server
$.mobile.showPageLoadingMsg('a');
EgovInterface.submitAsynchronous(
["/pki/pkiInfoList.do"],
function(result) {
console.log("PKIMagicXSignAPIGuide fn_goLoginInfoList Completed");
var list_html = "";
var totcnt = result.pkiInfoList.length;
for (var i = 0; i < totcnt; i++) {
var data = result.pkiInfoList[i];
var entrprsSe = "NONE";
var entrprsSeCode = data.entrprsSeCode;
if(entrprsSeCode == 'PKI01')
entrprsSe = "MagicXSign";
else if(entrprsSeCode == 'PKI02')
entrprsSe = "WizSign";
else if(entrprsSeCode == 'PKI03')
entrprsSe = "XecureSmart";
list_html += "subjdn : " + data.dn + "
";
list_html += "Date : " + data.crtfcDt + "
";
list_html += "NPKI : " + entrprsSe + "
";
}
var theList = $('#theLogList');
theList.html(list_html);
$.mobile.changePage("#loginInfoList", "slide", false, false);
theList.listview("refresh");
$.mobile.hidePageLoadingMsg('a');
setTimeout(loadiScrollList, 1000);
},
function(error) {
console.log("PKIMagicXSignAPIGuide fn_goLoginInfoList Failed");
var str = '{';
for (var myKey in error){
str += myKey + ' : ' + error[myKey] + '\n';
}
str += '}';
$.mobile.hidePageLoadingMsg('a');
alert('응답방식:RESTful\n전송Type:json, post\nParam:\n' + str);
}
);
}
=== 관련화면 및 수행매뉴얼 ===
^기능^URL^Controller^method^QueryID^
|인증서 인증 결과 로그 조회|/pki/pkiInfoList.do|EgovPKIiOSAPIController|selectPKIInfoList|PKIiOSAPIDAO.selectPKIInfoList|
{{:egovframework:hyb:guide:ios:magic_log2.png|}}
===== 컴파일 디버깅 배포 =====
==== 컴파일 ====
=== NPKI Device Applicaton 컴파일 방법 ===
1. 디바이스 또는 시뮬레이터에서 실행하고자 할 경우 빨간 테두리 영역을 클릭한다.\\
{{:egovframework:hyb:guide:ios:xcode실행영역선택1.png|}}\\
2. 디바이스 또는 시뮬레이터를 선택한다.\\
{{:egovframework:hyb:guide:ios:xcode실행영역선택2.png|}}\\
3. 실행 버튼을 클릭한다.\\
{{:egovframework:hyb:guide:ios:xcode실행버튼.png|}}\\
4. 인트로 화면과 메인 화면을 확인한다.\\
{{:egovframework:hyb:guide:ios:magic_intro2.png|}}{{:egovframework:hyb:guide:ios:magic_main2.png|}}
=== NPKI Server Applicaton 컴파일 방법 ===
* NPKIAPI 서버사이드 가이드 프로그램의 실행은 프로젝트를 마우스 오른쪽 버튼을 클릭 한후 Run As>Run On Server 버튼을 통해 실행 할 수 있다.
{{:egovframework:hyb:guide:ios:서버실행.png?640|}}
* 빌드가 성공적으로 수행 되면 이클립스의 콘솔 창에서 'Server Startup in xxx ms' 메시지를 확인 할 수 있다.
{{:egovframework:hyb:guide:ios:웹서버실행성공.png?700|}}
==== 디버깅 ====
디바이스 어플리케이션에서 발생한 오류 내용 확인 및 디버깅을 위해서는 폰갭 프레임워크에서 제공하는 console.log를 이용할 수 있다. console.log 함수는 자바스크립트 구문에서 사용할 수 있는 디버그 코드로 이클립스 및 Xcode에서 확인 할 수 있다.
* 실제 콘솔 로그 예
function fn_egov_network_check(doCheck)
{
console.log('DeviceAPIGuide fn_egov_network_check');
var networkState = navigator.network.connection.type;
...
}
* xCode 콘솔 창
{{:egovframework:hyb:guide:ios:cameradebugxcode.png?700|}}\\
* Organizer 로그 창
{{:egovframework:hyb:guide:ios:cameradebugorganizer.png?700|}}\\
NPKI API 가이드 프로그램 에서는 디버깅을 위하여 다음과 같이 콘솔 정보를 출력한다.
^디버그 코드^디버깅 내용^
|PKIMagicXSignAPIGuide deviceready Success|Device 준비 성공 시|
|PKIMagicXSignAPIGuide fn_egov_makesign_ok request Completed|웹 서버 어플리케이션으로 부터 인증서 인증 성공 시 |
|PKIMagicXSignAPIGuide fn_egov_makesign_ok request Failed|웹 서버 어플리케이션으로 부터 인증서 인증 실패 시 |
|PKIMagicXSignAPIGuide fn_egov_makesign_ok Success|인증서 서명 성공 시 |
|PKIMagicXSignAPIGuide fn_egov_makesign_fail Failed|인증서 서명 실패 시 |
|PKIMagicXSignAPIGuide fn_egov_getcertlistSuccess Success|인증서 리스트 조회 성공 시 |
|PKIMagicXSignAPIGuide fn_egov_getcertlistFail Failed|인증서 리스트 조회 실패 시 |
|PKIMagicXSignAPIGuide fn_egov_ollecert_Check_Fail Failed|올레인증서 미 설치 시 |
|PKIMagicXSignAPIGuide fn_egov_ollecert_Check_Fail Completed|올레인증서 설치 시|
|PKIMagicXSignAPIGuide fn_egov_certGetFromOlleCert_Fail Failed|올레인증서 호출 실패 시|
|PKIMagicXSignAPIGuide fn_egov_certGetFromOlleCert_Success Success|올레인증서 호출 성공 시|
==== 배포 ====
NPKI 디바이스 API 가이드 다운로드 : [[http://www.egovframe.go.kr/cop/bbs/selectBoardArticle.do?bbsId=BBSMSTR_000000000161&nttId=535&menu=3&submenu=9|Click]]
===== 참고자료 =====
* UX/UI 라이브러리 : [[http://jquerymobile.com/|jQuery Mobile]] \\
* Hybrid : [[http://www.phonegap.com/|PhoneGap]] \\
* 표준보안API : http://www.gpki.go.kr/ \\