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;
}
}
}