package kr.co.udapsoft.common.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Properties; import crosscert.Base64; import crosscert.Certificate; import crosscert.Decrypt; import crosscert.PrivateKey; import crosscert.Signer; import crosscert.Verifier; import kr.co.hsnc.common.base.WAFLogger; import kr.co.hsnc.common.config.WAFConfig; public class Crosscert { private String sOrgData = ""; // 데이타 원문 private String sDn = ""; // 인증서DN값 /** * 암호화 하기 위한 인증키값 리턴 * @param sDerFileNm 키값 * @return * @throws Exception */ public String getBase64EncodeCert(String sDerFileNm) { String sBase64EncodeCert = ""; FileInputStream inCert = null; try { //서버인증서를 읽는다. : 원문을 암호화 하기 위함 int nCertlen = 0; int nRet = 0; byte[] Certfilebuf = null; String path = WAFConfig.get("waf.key.file.path"); inCert = new FileInputStream(new File(path+sDerFileNm)); nCertlen = inCert.available(); Certfilebuf = new byte[nCertlen]; nRet = inCert.read(Certfilebuf); Base64 base64 = new Base64(); nRet = base64.Encode(Certfilebuf, nCertlen); if (nRet != 0) { WAFLogger.debug("base인코드 에러내용 : " + base64.errmessage); WAFLogger.debug("base인코드에러코드 : " + base64.errcode); } sBase64EncodeCert = new String(base64.contentbuf); } catch (FileNotFoundException e) { WAFLogger.error("[ERROR "+this.getClass().getName() + ".getBase64EncodeCert()] :" + e.toString()); } catch (IOException e) { WAFLogger.error("[ERROR "+this.getClass().getName() + ".getBase64EncodeCert()] :" + e.toString()); }finally { try { if(inCert != null) inCert.close(); } catch (IOException e) { WAFLogger.error("[ERROR "+this.getClass().getName() + ".getBase64EncodeCert()] :" + e.toString()); } } return sBase64EncodeCert; } /** * 전자서명 검증 * @param sSignData 서명데이타 * @return * @throws UnsupportedEncodingException */ public String chkSignVerify(String sSignData) throws UnsupportedEncodingException { String sMsg = "SIGN_SUCCESS"; try { int nRet = 0; Base64 CBase64 = new Base64(); nRet = CBase64.Decode(sSignData.getBytes("KSC5601"), sSignData.getBytes("KSC5601").length); if(nRet==0) { WAFLogger.debug("서명값 Base64 Decode 결과 : 성공") ; } else { WAFLogger.debug("서명값 Base64 Decode 결과 : 실패") ; WAFLogger.debug("에러내용 : " + CBase64.errmessage); WAFLogger.debug("에러코드 : " + CBase64.errcode); sMsg = "SIGN_ERROR"; } Verifier CVerifier = new Verifier(); nRet=CVerifier.VerSignedData(CBase64.contentbuf, CBase64.contentlen); if(nRet==0) { this.setOrgData(CVerifier); WAFLogger.debug("전자서명 검증 결과 : 성공") ; WAFLogger.debug("원문 : " + this.getOrgData()); } else { WAFLogger.debug("전자서명 검증 결과 : 실패") ; WAFLogger.debug("에러내용 : " + CVerifier.errmessage); WAFLogger.debug("에러코드 : " + CVerifier.errcode); sMsg = "SIGN_ERROR"; } //인증서 정보 추출 결과 Certificate CCertificate = new Certificate(); nRet=CCertificate.ExtractCertInfo(CVerifier.certbuf, CVerifier.certlen); if (nRet ==0) { this.setDn(CCertificate); WAFLogger.debug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); WAFLogger.debug("serial; "+ CCertificate.serial); WAFLogger.debug("issuer; "+ CCertificate.issuer); WAFLogger.debug("subject; "+ CCertificate.subject); WAFLogger.debug("from; "+ CCertificate.from); WAFLogger.debug("to; "+ CCertificate.to); WAFLogger.debug("policy; "+ CCertificate.policy); /** WAFLogger.debug("version; "+ CCertificate.version); WAFLogger.debug("serial; "+ CCertificate.serial); WAFLogger.debug("issuer; "+ CCertificate.issuer); WAFLogger.debug("subject; "+ CCertificate.subject); WAFLogger.debug("subjectAlgId; "+ CCertificate.subjectAlgId); WAFLogger.debug("from; "+ CCertificate.from); WAFLogger.debug("to; "+ CCertificate.to); WAFLogger.debug("signatureAlgId; "+ CCertificate.signatureAlgId); WAFLogger.debug("pubkey; "+ CCertificate.pubkey); WAFLogger.debug("signature; "+ CCertificate.signature); WAFLogger.debug("issuerAltName; "+ CCertificate.issuerAltName); WAFLogger.debug("subjectAltName; "+ CCertificate.subjectAltName); WAFLogger.debug("keyusage; "+ CCertificate.keyusage); WAFLogger.debug("policy; "+ CCertificate.policy); WAFLogger.debug("basicConstraint; "+ CCertificate.basicConstraint); WAFLogger.debug("policyConstraint; "+ CCertificate.policyConstraint); WAFLogger.debug("distributionPoint;"+ CCertificate.distributionPoint); WAFLogger.debug("authorityKeyId; "+ CCertificate.authorityKeyId); WAFLogger.debug("subjectKeyId; "+ CCertificate.subjectKeyId); **/ }else { WAFLogger.debug("인증서 검증 결과 : 실패") ; WAFLogger.debug("에러내용 : " + CCertificate.errmessage); WAFLogger.debug("에러코드 : " + CCertificate.errcode); sMsg = "SIGN_ERROR"; } // 인증서 검증 String Policies = "1.2.410.200004.5.2.1.1|" + // 한국정보인증 법인 "1.2.410.200004.5.1.1.7|" + // 한국증권전산 법인, 단체, 개인사업자 "1.2.410.200005.1.1.5|" + // 금융결제원 법인, 임의단체, 개인사업자 "1.2.410.200004.5.3.1.1|" + // 한국전산원 기관(국가기관 및 비영리기관) "1.2.410.200004.5.3.1.2|" + // 한국전산원 법인(국가기관 및 비영리기관을 제외한 공공기관, 법인) "1.2.410.200004.5.4.1.2|" + // 한국전자인증 법인, 단체, 개인사업자 "1.2.410.200012.1.1.3|" + // 한국무역정보통신 법인 "1.2.410.200004.5.4.2.369|" + // 나이스디앤비전용 법인 "1.2.410.200004.5.4.1.3|" + // 서버인증서 "1.2.410.200004.5.4.2.424|" + // SGC이앤씨 전용 인증서 "1.2.410.200004.5.2.1.2|" + // 한국정보인증 개인 "1.2.410.200004.5.1.1.5|" + // 한국증권전산 개인 "1.2.410.200005.1.1.1|" + // 금융결제원 개인 "1.2.410.200004.5.3.1.9|" + // 한국전산원 개인 "1.2.410.200004.5.4.1.1|" + // 한국전자인증 개인 "1.2.410.200012.1.1.1|" + // 한국무역정보통신 개인 "1.2.410.200005.1.1.4|" + // 은행용 실서버에스는 제거필 개인 ""; CCertificate.errmessage = ""; nRet=CCertificate.ValidateCert(CVerifier.certbuf, CVerifier.certlen, Policies, 1); if(nRet==0) { WAFLogger.debug("인증서 검증 결과 : 성공") ; } else { WAFLogger.debug("인증서 검증 결과 : 실패 ㅜㅜ") ; WAFLogger.debug("에러내용 : " + CCertificate.errmessage); WAFLogger.debug("에러코드 : " + CCertificate.errcode); WAFLogger.debug("에러코드 : " + Integer.toHexString(CCertificate.errcode)); WAFLogger.debug("에러내용 : " + CCertificate.errdetailmessage); sMsg = "SIGN_ERROR"; } } catch (UnsupportedEncodingException e) { sMsg = "SIGN_ERROR"; WAFLogger.debug("[ERROR "+this.getClass().getName() + ".getBase64EncodeCert()] :" + e.toString()); throw new UnsupportedEncodingException("[ERROR "+this.getClass().getName() + ".getBase64EncodeCert()] :" + e.toString()); } return sMsg; } /** * 데이타 복호화 * @param sSignData 암호화데이타 * @return * @throws IOException */ public String decryptData(String sSignData) throws IOException { String sOrgData = ""; try { int nRet = 0; InputStream inPri = null; InputStream inCert = null; byte[] Prifilebuf; byte[] Certfilebuf; //복호화용 개인키 읽기 start int nPrilen; int nCertlen; String sDerFullPath = ""; String sKeyFullPath = ""; String path = WAFConfig.get("waf.key.file.path"); sDerFullPath = path + "signCert.der"; sKeyFullPath = path + "signPri.key"; inPri = new FileInputStream(new File(sKeyFullPath)); inCert = new FileInputStream(new File(sDerFullPath)); nPrilen = inPri.available(); Prifilebuf = new byte[nPrilen]; nRet = inPri.read(Prifilebuf); nCertlen = inCert.available(); Certfilebuf = new byte[nCertlen]; nRet = inCert.read(Certfilebuf); //복호화용 개인키 읽기 end //인증서 정책 String policies = ""; // 법인상호연동용(범용) policies +="1.2.410.200004.5.2.1.1" + "|"; // 한국정보인증 법인 policies +="1.2.410.200004.5.1.1.7" + "|"; // 한국증권전산 법인, 단체, 개인사업자 policies +="1.2.410.200005.1.1.5" + "|"; // 금융결제원 법인, 임의단체, 개인사업자 policies +="1.2.410.200004.5.3.1.1" + "|"; // 한국전산원 기관(국가기관 및 비영리기관) policies +="1.2.410.200004.5.3.1.2" + "|"; // 한국전산원 법인(국가기관 및 비영리기관을 제외한 공공기관, 법인) policies +="1.2.410.200004.5.4.1.2" + "|"; // 한국전자인증 법인, 단체, 개인사업자 policies +="1.2.410.200012.1.1.3" + "|"; // 한국무역정보통신 법인 policies +="1.2.410.200004.5.4.2.369" + "|"; // 나이스디앤비 법인 //서버에서 개인키 읽어오기 PrivateKey CPrivateKey = new PrivateKey(); //개인키 추출 클래스 Base64 CBase64 = new Base64(); //base64 인코딩 디코딩 Decrypt decrypt = new Decrypt(); //복호화 클래스 //Certificate CCertificate = new Certificate(); //인증서 추출 및 검증 Verifier CVerifier = new Verifier(); // 서명검증을 위한 클래스 //String sSignPwd = Startup.conf.getString("servercert.pwd"); String sSignPwd = WAFConfig.get("waf.key.pwd"); WAFLogger.debug("sSignPwd["+sSignPwd+"]"); // 개인키 추출 nRet = CPrivateKey.DecryptPriKey(sSignPwd, Prifilebuf, nPrilen); if (nRet != 0) { WAFLogger.debug("에러내용 : " + CPrivateKey.errmessage); WAFLogger.debug("에러코드 : " + CPrivateKey.errcode); sOrgData = ""; } // 서명값 base64 디코딩 nRet = CBase64.Decode(sSignData.getBytes(), sSignData.getBytes().length); if (nRet != 0) { WAFLogger.debug("base64디코드 에러내용(서명값) : " + CBase64.errmessage); WAFLogger.debug("base64디코드 에러코드 : " + CBase64.errcode); sOrgData = ""; } // 전자서명 검증 nRet=CVerifier.VerSignedData(CBase64.contentbuf, CBase64.contentlen); if(nRet != 0) { WAFLogger.debug("전자서명 검증 결과 : 실패") ; WAFLogger.debug("에러내용 : " + CVerifier.errmessage); WAFLogger.debug("에러코드 : " + CVerifier.errcode); sOrgData = ""; } // 원문 암호화값 base64 디코딩 nRet = CBase64.Decode(CVerifier.contentbuf, CVerifier.contentlen); if (nRet != 0) { WAFLogger.debug("base64디코드 에러내용(원문 암호화값) : " + CBase64.errmessage); WAFLogger.debug("base64디코드 에러코드 : " + CBase64.errcode); sOrgData = ""; } //인증서 복호화 nRet = decrypt.DecEnvelopedData(CPrivateKey.prikeybuf, CPrivateKey.prikeylen, Certfilebuf, nCertlen, CBase64.contentbuf, CBase64.contentlen); if (nRet != 0) { WAFLogger.debug("복호화 에러내용 : " + decrypt.errmessage); WAFLogger.debug("복호화 에러코드 : " + decrypt.errcode); sOrgData = decrypt.errcode+""; }else{ // sOrgData = new String(decrypt.contentbuf , "KSC5601"); // sOrgData = URLDecoder.decode(sOrgData); try{ sOrgData = new String(decrypt.contentbuf , "KSC5601"); System.out.println("============================================="); System.out.println(sOrgData); System.out.println("============================================="); sOrgData = URLDecoder.decode(sOrgData); } catch( Exception e){ sOrgData = new String(decrypt.contentbuf , "KSC5601"); } } } catch (FileNotFoundException e) { WAFLogger.error("[ERROR Config.decryptData()] :" + e.toString()); throw new FileNotFoundException("[ERROR Config.decryptData()] :" + e.toString()); } catch (IOException e) { WAFLogger.error("[ERROR Config.decryptData()] :" + e.toString()); throw new IOException("[ERROR Config.decryptData()] :" + e.toString()); } return sOrgData; } /** * 데이타 복호화 * @param sSignData 암호화데이타 * @return * @throws IOException */ public String decryptDataOld(String sSignData) throws IOException { String sOrgData = ""; try { int nRet = 0; InputStream inPri = null; InputStream inCert = null; byte[] Prifilebuf; byte[] Certfilebuf; //복호화용 개인키 읽기 start int nPrilen; int nCertlen; String sDerFullPath = ""; String sKeyFullPath = ""; String path = WAFConfig.get("waf.key.file.path.old"); sDerFullPath = path + "signCert.der"; sKeyFullPath = path + "signPri.key"; inPri = new FileInputStream(new File(sKeyFullPath)); inCert = new FileInputStream(new File(sDerFullPath)); nPrilen = inPri.available(); Prifilebuf = new byte[nPrilen]; nRet = inPri.read(Prifilebuf); nCertlen = inCert.available(); Certfilebuf = new byte[nCertlen]; nRet = inCert.read(Certfilebuf); //복호화용 개인키 읽기 end //인증서 정책 String policies = ""; // 법인상호연동용(범용) policies +="1.2.410.200004.5.2.1.1" + "|"; // 한국정보인증 법인 policies +="1.2.410.200004.5.1.1.7" + "|"; // 한국증권전산 법인, 단체, 개인사업자 policies +="1.2.410.200005.1.1.5" + "|"; // 금융결제원 법인, 임의단체, 개인사업자 policies +="1.2.410.200004.5.3.1.1" + "|"; // 한국전산원 기관(국가기관 및 비영리기관) policies +="1.2.410.200004.5.3.1.2" + "|"; // 한국전산원 법인(국가기관 및 비영리기관을 제외한 공공기관, 법인) policies +="1.2.410.200004.5.4.1.2" + "|"; // 한국전자인증 법인, 단체, 개인사업자 policies +="1.2.410.200012.1.1.3" + "|"; // 한국무역정보통신 법인 policies +="1.2.410.200004.5.4.2.369" + "|"; // 나이스디앤비 법인 //서버에서 개인키 읽어오기 PrivateKey CPrivateKey = new PrivateKey(); //개인키 추출 클래스 Base64 CBase64 = new Base64(); //base64 인코딩 디코딩 Decrypt decrypt = new Decrypt(); //복호화 클래스 //Certificate CCertificate = new Certificate(); //인증서 추출 및 검증 Verifier CVerifier = new Verifier(); // 서명검증을 위한 클래스 //String sSignPwd = Startup.conf.getString("servercert.pwd"); String sSignPwd = WAFConfig.get("waf.key.pwd.old"); WAFLogger.debug("sSignPwd["+sSignPwd+"]"); // 개인키 추출 nRet = CPrivateKey.DecryptPriKey(sSignPwd, Prifilebuf, nPrilen); if (nRet != 0) { WAFLogger.debug("에러내용 : " + CPrivateKey.errmessage); WAFLogger.debug("에러코드 : " + CPrivateKey.errcode); sOrgData = ""; } // 서명값 base64 디코딩 nRet = CBase64.Decode(sSignData.getBytes(), sSignData.getBytes().length); if (nRet != 0) { WAFLogger.debug("base64디코드 에러내용(서명값) : " + CBase64.errmessage); WAFLogger.debug("base64디코드 에러코드 : " + CBase64.errcode); sOrgData = ""; } // 전자서명 검증 nRet=CVerifier.VerSignedData(CBase64.contentbuf, CBase64.contentlen); if(nRet != 0) { WAFLogger.debug("전자서명 검증 결과 : 실패") ; WAFLogger.debug("에러내용 : " + CVerifier.errmessage); WAFLogger.debug("에러코드 : " + CVerifier.errcode); sOrgData = ""; } // 원문 암호화값 base64 디코딩 nRet = CBase64.Decode(CVerifier.contentbuf, CVerifier.contentlen); if (nRet != 0) { WAFLogger.debug("base64디코드 에러내용(원문 암호화값) : " + CBase64.errmessage); WAFLogger.debug("base64디코드 에러코드 : " + CBase64.errcode); sOrgData = ""; } //인증서 복호화 nRet = decrypt.DecEnvelopedData(CPrivateKey.prikeybuf, CPrivateKey.prikeylen, Certfilebuf, nCertlen, CBase64.contentbuf, CBase64.contentlen); if (nRet != 0) { WAFLogger.debug("복호화 에러내용 : " + decrypt.errmessage); WAFLogger.debug("복호화 에러코드 : " + decrypt.errcode); sOrgData = ""; }else{ // sOrgData = new String(decrypt.contentbuf , "KSC5601"); // sOrgData = URLDecoder.decode(sOrgData); try{ sOrgData = new String(decrypt.contentbuf , "KSC5601"); System.out.println("============================================="); System.out.println(sOrgData); System.out.println("============================================="); sOrgData = URLDecoder.decode(sOrgData); } catch( Exception e){ sOrgData = new String(decrypt.contentbuf , "KSC5601"); } } } catch (FileNotFoundException e) { WAFLogger.error("[ERROR Config.decryptData()] :" + e.toString()); throw new FileNotFoundException("[ERROR Config.decryptData()] :" + e.toString()); } catch (IOException e) { WAFLogger.error("[ERROR Config.decryptData()] :" + e.toString()); throw new IOException("[ERROR Config.decryptData()] :" + e.toString()); } return sOrgData; } /** * 원문데이타 넣기 * @param verifier */ public void setOrgData(Verifier verifier) { try { this.sOrgData = new String(verifier.contentbuf, "KSC5601"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 원문데이타 가져오기 * @return */ public String getOrgData() { return this.sOrgData; } /** * DN값 가져오기 * @param verifier */ public void setDn(Certificate certificate) { this.sDn = certificate.subject; } /** * DN값 가져오기 * @return */ public String getDn() { return this.sDn; } /** * 서버 인증서 서명 * @return */ public String signCrosscert(String contHash) throws Exception { int nPrilen=0, nCertlen=0, nRet; InputStream inPri=null; InputStream inCert=null; //OutputStream out=null; byte[] Prifilebuf; byte[] Certfilebuf; Properties props = System.getProperties(); // get list of properties String file_separator = (String)(props.get("file.separator")); String current_dir = ""; String CertPath = ""; String Full_path = WAFConfig.get("waf.key.file.path"); //"D:\\project\\etec\\"; //storage.request.getRealPath(storage.request.getServletPath()); WAFLogger.debug("키저장소 : " + Full_path + "
"); /* if (file_separator.equals("\\")) { current_dir = Full_path.substring(0,Full_path.lastIndexOf("\\")+1); CertPath = current_dir; } else { current_dir = Full_path.substring(0,Full_path.lastIndexOf("/")+1); CertPath = current_dir ; } */ CertPath = Full_path; //current_dir = request.getServletPath().substring(0,request.getServletPath().lastIndexOf("/")+1); String SignedData = ""; //전자서명값 String sInput = contHash; WAFLogger.debug("키저장소 : " + current_dir + "
"); WAFLogger.debug("원문길이 : " + sInput.length() + "
"); try { inPri = new FileInputStream(new File(CertPath + "signPri.key")); inCert = new FileInputStream(new File(CertPath +"signCert.der")); } catch (FileNotFoundException e) { WAFLogger.error(e); return "FAIL"; } catch (IOException e) { WAFLogger.error(e); return "FAIL"; } try { nPrilen=inPri.available(); Prifilebuf=new byte[nPrilen]; nRet=inPri.read(Prifilebuf); System.out.print(nRet); // 개인키 추출 PrivateKey privateKey = new PrivateKey(); nRet=privateKey.DecryptPriKey(WAFConfig.get("waf.key.pwd"), Prifilebuf, nPrilen); if (nRet != 0) { System.out.print("에러메시지 : " + privateKey.errmessage + "
"); return privateKey.errmessage; } else { WAFLogger.debug("개인키 길이 : " + privateKey.prikeylen + "
"); //OutputStream out1 = null; //out1 = new FileOutputStream("C:\\pri.key.pri", true); //out1.write(privateKey.prikeybuf); //out1.close(); nCertlen=inCert.available(); Certfilebuf = new byte[nCertlen]; nRet=inCert.read(Certfilebuf); // 전자서명 Signer signer = new Signer(); nRet=signer.GetSignedData(privateKey.prikeybuf, privateKey.prikeylen, Certfilebuf, nCertlen, sInput.getBytes("KSC5601"), sInput.getBytes("KSC5601").length); if (nRet != 0) { System.out.print("에러메시지 : " + signer.errmessage + "
"); return signer.errmessage; } WAFLogger.debug("전자서명 성공(PKCS#7)
"); WAFLogger.debug("전자서명(바이너리) 길이 : " + signer.signedlen + "
"); // 바이너리 테이타 base64인코딩 Base64 CBase64 = new Base64(); //바이트 배열 //바이트 배열길이 nRet = CBase64.Encode(signer.signedbuf, signer.signedlen); if(nRet==0) { WAFLogger.debug("서명값 Base64 Encode 결과 : 성공
") ; SignedData = new String(CBase64.contentbuf); WAFLogger.debug("서명값 Base64 Decode 값 : " + SignedData + "
") ; } else { WAFLogger.debug("서명값 Base64 Decode 결과 : 실패
") ; WAFLogger.debug("에러내용 : " + signer.errmessage + "
"); WAFLogger.debug("에러코드 : " + CBase64.errcode + "
"); } } return SignedData; } catch(IOException e1) { WAFLogger.error(e1); WAFLogger.debug("Exception : " + e1.getMessage()); throw e1; } } }