암호화 모듈 변경 (전자정부프레임워크 -> 이씨플라자 제공 소스 Aria로 변경)

This commit is contained in:
KNKIM 2021-09-03 16:06:42 +09:00
parent 61b2b7717f
commit 303302c992
15 changed files with 1105 additions and 366 deletions

View File

@ -1,38 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v8.5"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v8.5"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

35
pom.xml
View File

@ -20,6 +20,8 @@
<spring.maven.artifact.version>4.3.16.RELEASE</spring.maven.artifact.version>
<egovframework.rte.version>3.8.0</egovframework.rte.version>
<spring-security.version>4.2.5.RELEASE</spring-security.version>
<slf4j.version>1.7.2</slf4j.version>
<log4j.version>2.11.0</log4j.version>
</properties>
<repositories>
@ -153,7 +155,31 @@
<artifactId>spring-expression</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
@ -368,13 +394,6 @@
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -1,171 +0,0 @@
/*
* eGovFrame OAuth
* Copyright The eGovFrame Open Community (http://open.egovframe.go.kr)).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author 이기하(슈퍼개발자K3)
*/
package egovframework.com.ext.oauth.web;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UserProfile;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.WebRequest;
//import egovframework.com.ext.oauth.service.EgovSignupService;
import egovframework.com.ext.oauth.service.OAuthConfig;
import egovframework.com.ext.oauth.service.OAuthLogin;
import egovframework.com.ext.oauth.service.OAuthUniversalUser;
import egovframework.com.ext.oauth.service.OAuthVO;
import egovframework.com.utl.fcc.service.EgovStringUtil;
/**
* 소셜 계정으로 일반회원 가입을 처리하는 컨트롤러 클래스
* @author 이기하
* @since 2014.10.08
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ----------- -------- ---------------------------
* 2014.10.08 이기하 최초 생성
* 2018.10.02 신용호 Facebook 관련 ProviderSignInUtils 초기화 수정
* </pre>
*/
@Controller
public class EgovSignupController {
private static final Logger LOGGER = LoggerFactory.getLogger(EgovSignupController.class);
// TODO 필요여부 확인할 DDDDDDDDDDDDDDDDDDDDDDDDD
// @Resource(name="signupService")
// private EgovSignupService signupService;
//private ConnectionRepository connectionRepository;
//private final ProviderSignInUtils providerSignInUtils;
// TODO 필요여부 확인할 DDDDDDDDDDDDDDDDDDDDD
@Inject
private OAuthVO naverAuthVO;
@Inject
private OAuthVO googleAuthVO;
@Inject
private OAuthVO kakaoAuthVO;
// TODO : 필요여부 확인할 DDDDDDDDDDDDDDDDDD
// @Inject
// public EgovSignupController(ConnectionFactoryLocator connectionFactoryLocator,UsersConnectionRepository connectionRepository) {
// //this.providerSignInUtils = new ProviderSignInUtils();
// this.providerSignInUtils = new ProviderSignInUtils(connectionFactoryLocator, connectionRepository);
// }
//
// @RequestMapping(value="/signup", method=RequestMethod.GET)
// public String signupForm(WebRequest request) throws Exception {
// Connection<?> connection = providerSignInUtils.getConnectionFromSession(request);
// if (connection != null) {
// UserProfile profile = connection.fetchUserProfile();
//
// String key = EgovStringUtil.remove(connection.getKey().toString(), ':');
// String account = signupService.signup(profile, request, key);
// if (account != null) {
// providerSignInUtils.doPostSignUp(key, request);
// return "redirect:/";
// }
// }
// return "redirect:/";
// }
@RequestMapping(value = "/uat/uia/oauthLoginUsr", method = RequestMethod.GET)
public String login(Model model) throws Exception {
LOGGER.debug("===>>> OAuth Login .....");
OAuthLogin naverLogin = new OAuthLogin(naverAuthVO);
LOGGER.debug("naverLogin.getOAuthURL() = "+naverLogin.getOAuthURL());
model.addAttribute("naver_url", naverLogin.getOAuthURL());
OAuthLogin googleLogin = new OAuthLogin(googleAuthVO);
LOGGER.debug("googleLogin.getOAuthURL() = "+googleLogin.getOAuthURL());
model.addAttribute("google_url", googleLogin.getOAuthURL());
OAuthLogin kakaoLogin = new OAuthLogin(kakaoAuthVO);
LOGGER.debug("kakaoLogin.getOAuthURL() = "+kakaoLogin.getOAuthURL());
model.addAttribute("kakao_url", kakaoLogin.getOAuthURL());
return "egovframework/com/uat/uia/EgovLoginUsrOauth";
}
@RequestMapping(value = "/auth/{oauthService}/callback",
method = { RequestMethod.GET, RequestMethod.POST})
public String oauthLoginCallback(@PathVariable String oauthService,
Model model, @RequestParam String code, HttpSession session) throws Exception {
LOGGER.debug("oauthLoginCallback: service={}", oauthService);
LOGGER.debug("===>>> code = "+ code);
OAuthVO oauthVO = null;
if (StringUtils.equals(OAuthConfig.GOOGLE_SERVICE_NAME, oauthService))
oauthVO = googleAuthVO;
else if (StringUtils.equals(OAuthConfig.NAVER_SERVICE_NAME, oauthService))
oauthVO = naverAuthVO;
else
oauthVO = kakaoAuthVO;
// 1. code를 이용해서 Access Token 받기
// 2. Access Token을 이용해서 사용자 제공정보 가져오기
OAuthLogin oauthLogin = new OAuthLogin(oauthVO);
OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시
LOGGER.debug("Profile ===>>" + oauthUser);
// ========================================================================
// 다음 부분은 업무의 목적에 맞게 커스텀 코드를 작성한다.
// 3. 해당 유저가 DB에 존재하는지 체크 (google, naver, kakao에서 전달받은 ID가 존재하는지 체크)
String resultDBInfo = ""; // DB 체크 결과
if ( oauthUser == null || resultDBInfo == null) {
// 미존재시 가입페이지로!!
model.addAttribute("message", "This user does not exist. Please sign up.");
} else {
// 존재시 로그인 처리
model.addAttribute("message", "OAuth Sign-in succeeded.");
}
return "egovframework/com/uat/uia/EgovLoginUsrOauthResult";
}
}

View File

@ -634,7 +634,7 @@ public class BoardController extends NlibCommonController
//-------------------------------
// 비밀번호 : SHA-256 암호화 처리되어 DB에 저장되며,
// 화면에 표출될 때는 Aria로 articleNo를 Salt값으로 하여 재암호화처리하고 BASE64로 다시 한번 인코딩하여 표출함
String encArticlePassword = StringUtil.encodeBase64(ariaCrypto.encode(shaArticlePassword, articleNo));
String encArticlePassword = StringUtil.encodeBase64(ariaCrypto.encode(shaArticlePassword));
model.addAttribute("encArticlePassword", encArticlePassword);
// 검색 정보
@ -680,7 +680,7 @@ public class BoardController extends NlibCommonController
// 비밀번호 : SHA-256 암호화 처리되어 DB에 저장되며,
// 화면에 표출될 때는 Aria로 articleNo를 Salt값으로 하여 재암호화처리하고 BASE64로 다시 한번 인코딩하여 표출함
String encArticlePassword = paramMap.get("encArticlePassword");
String checkArticlePassword = ariaCrypto.decode(StringUtil.decodeBase64(encArticlePassword), articleNo);
String checkArticlePassword = ariaCrypto.decode(StringUtil.decodeBase64(encArticlePassword));
String articlePassword = paramMap.get("articlePassword");
//-------------------------------

View File

@ -3,13 +3,11 @@ package nlib.cmm.crypto;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import egovframework.rte.fdl.cryptography.EgovPasswordEncoder;
import egovframework.rte.fdl.cryptography.impl.EgovARIACryptoServiceImpl;
import nlib.cmm.service.NlibProperty;
import nlib.sample.web.SampleEncoderController;
import nlib.util.StringUtil;
/**
@ -51,18 +49,40 @@ public class AriaCrypto {
* @return
*/
public static String encode(String value) {
log.info("encode : 암호화에 사용할 키 정보가 없으므로 기본키 정보를 사용합니다 : " + ARIA_DEFAULT_KEY);
return encode(value, ARIA_DEFAULT_KEY);
String ret = null;
try {
ret = AriaUtil.ariaEncrypt(value);
} catch(Exception e) {
log.error("ERROR at AriaCrypto.encode : " + e.toString());
e.printStackTrace();
ret = null;
}
return ret;
}
/**
* 기본키를 가지고 Egov 모듈을 사용하여 암호화한다.
*
* @param value
* @return
*/
public static String encodeEgov(String value) {
log.info("encode : 암호화에 사용할 키 정보가 없으므로 기본키 정보를 사용합니다 : " + ARIA_DEFAULT_KEY);
return encodeEgov(value, ARIA_DEFAULT_KEY);
}
/**
* 전달받은 key(사용자고유번호 혹은 메일주소 salt값) 암호화한다.
* 전달받은 key(사용자고유번호 혹은 메일주소 salt값) Egov 모듈을 사용하여 암호화한다.
*
* @param value
* @param key
* @return
*/
public static String encode(String value, String key) {
public static String encodeEgov(String value, String key) {
if(StringUtil.isEmpty(value)) {
log.error("encode : 암호화할 문자열 정보가 없습니다.");
@ -94,17 +114,38 @@ public class AriaCrypto {
* @return
*/
public static String decode(String value) {
String ret = null;
try {
ret = AriaUtil.ariaDecrypt(value);
} catch(Exception e) {
log.error("ERROR at AriaCrypto.decode : " + e.toString());
e.printStackTrace();
ret = null;
}
return ret;
}
/**
* 기본키를 가지고 Egov 모듈을 사용하여 복호화한다.
*
* @param value
* @return
*/
public static String decodeEgov(String value) {
log.info("decode : 복호화에 사용할 키 정보가 없으므로 기본키 정보를 사용합니다 : " + ARIA_DEFAULT_KEY);
return decode(value, ARIA_DEFAULT_KEY);
return decodeEgov(value, ARIA_DEFAULT_KEY);
}
/**
* 전달받은 key(사용자고유번호 혹은 메일주소 salt값) 복호화한다.
* 전달받은 key(사용자고유번호 혹은 메일주소 salt값) Egov 모듈을 사용하여 복호화한다.
* @param value
* @param key
* @return
*/
public static String decode(String value, String key) {
public static String decodeEgov(String value, String key) {
if(StringUtil.isEmpty(value)) {
log.error("decode : 복호화할 암호문자열 정보가 없습니다.");

View File

@ -0,0 +1,590 @@
//
// ARIA.java
//
// A pure Java implementation of ARIA
// following the official ARIA specification at
//
package nlib.cmm.crypto;
import java.io.PrintStream;
import java.security.InvalidKeyException;
public class AriaEngine {
private static final char[] HEX_DIGITS = {
'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
};
private static final int[][] KRK = {
{0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0},
{0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0},
{0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e}
};
private static final byte[] S1 = new byte[256];
private static final byte[] S2 = new byte[256];
private static final byte[] X1 = new byte[256];
private static final byte[] X2 = new byte[256];
private static final int[] TS1 = new int[256];
private static final int[] TS2 = new int[256];
private static final int[] TX1 = new int[256];
private static final int[] TX2 = new int[256];
private String publicKey = "CREDIF_MASTERKEY";
private String privateKey = "";
// Static initializer. For setting up the tables
static {
int[] exp = new int[256];
int[] log = new int[256];
exp[0] = 1;
for (int i=1; i < 256; i++) {
int j = (exp[i-1] << 1) ^ exp[i-1];
if ((j & 0x100) != 0) j ^= 0x11b;
exp[i] = j;
}
for (int i=1; i < 255; i++)
log[exp[i]] = i;
int[][] A = {
{1, 0, 0, 0, 1, 1, 1, 1},
{1, 1, 0, 0, 0, 1, 1, 1},
{1, 1, 1, 0, 0, 0, 1, 1},
{1, 1, 1, 1, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 1, 1, 1, 1, 1}
};
int[][] B = {
{0, 1, 0, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 0, 1},
{1, 1, 0, 1, 0, 1, 1, 1},
{1, 0, 0, 1, 1, 1, 0, 1},
{0, 0, 1, 0, 1, 1, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 1},
{0, 1, 0, 1, 1, 1, 0, 1},
{1, 1, 0, 1, 0, 0, 1, 1}
};
for (int i=0; i<256; i++) {
int t=0, p;
if (i==0)
p=0;
else
p=exp[255-log[i]];
for (int j=0; j<8; j++) {
int s=0;
for (int k=0; k<8; k++) {
if (((p>>>(7-k))&0x01)!=0)
s^=A[k][j];
}
t=(t<<1)^s;
}
t^=0x63;
S1[i]=(byte)t;
X1[t]=(byte)i;
}
for (int i = 0; i < 256; i++) {
int t = 0, p;
if (i==0)
p=0;
else
p=exp[(247*log[i])%255];
for (int j = 0; j < 8; j++) {
int s = 0;
for (int k = 0; k < 8; k++) {
if (((p >>> k) & 0x01) != 0)
s ^= B[7-j][k];
}
t = (t << 1) ^ s;
}
t^=0xe2;
S2[i] = (byte) t;
X2[t] = (byte) i;
}
for (int i = 0; i < 256; i++) {
TS1[i]=0x00010101*(S1[i]&0xff);
TS2[i]=0x01000101*(S2[i]&0xff);
TX1[i]=0x01010001*(X1[i]&0xff);
TX2[i]=0x01010100*(X2[i]&0xff);
}
}
private int keySize=0;
private int numberOfRounds=0;
private byte[] masterKey=null;
private int[] encRoundKeys=null, decRoundKeys=null;
public AriaEngine(int keySize) throws InvalidKeyException {
setKeySize(keySize);
}
/**
* Resets the class so that it can be reused for another master key.
*/
void reset() {
this.keySize=0;
this.numberOfRounds=0;
this.masterKey=null;
this.encRoundKeys=null;
this.decRoundKeys=null;
}
int getKeySize() {
return this.keySize;
}
void setKeySize(int keySize) throws InvalidKeyException {
this.reset();
if (keySize!=128 && keySize!=192 && keySize!=256)
throw new InvalidKeyException("keySize="+keySize);
this.keySize = keySize;
switch (keySize) {
case 128:
this.numberOfRounds = 12;
break;
case 192:
this.numberOfRounds = 14;
break;
case 256:
this.numberOfRounds = 16;
}
}
void setKey(byte[] masterKey) throws InvalidKeyException {
if (masterKey.length*8<keySize)
throw new InvalidKeyException("masterKey size="+masterKey.length);
this.decRoundKeys = null;
this.encRoundKeys = null;
this.masterKey = (byte[])masterKey.clone();
}
void setupEncRoundKeys() throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
if (this.encRoundKeys==null)
this.encRoundKeys = new int[4*(this.numberOfRounds+1)];
this.decRoundKeys = null;
doEncKeySetup(this.masterKey, this.encRoundKeys, this.keySize);
}
void setupDecRoundKeys() throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.encRoundKeys==null)
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
else
setupEncRoundKeys();
this.decRoundKeys = (int[])encRoundKeys.clone();
doDecKeySetup(this.masterKey, this.decRoundKeys, this.keySize);
}
void setupRoundKeys() throws InvalidKeyException {
setupDecRoundKeys();
}
private static void doCrypt(byte[] i, int ioffset, int[] rk, int nr, byte[] o, int ooffset) {
int t0, t1, t2, t3, j=0;
t0 = toInt(i[ 0+ioffset], i[ 1+ioffset], i[ 2+ioffset], i[ 3+ioffset]);
t1 = toInt(i[ 4+ioffset], i[ 5+ioffset], i[ 6+ioffset], i[ 7+ioffset]);
t2 = toInt(i[ 8+ioffset], i[ 9+ioffset], i[10+ioffset], i[11+ioffset]);
t3 = toInt(i[12+ioffset], i[13+ioffset], i[14+ioffset], i[15+ioffset]);
for (int r=1; r<nr/2; r++) {
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
t0=TX1[(t0>>>24)&0xff]^TX2[(t0>>>16)&0xff]^TS1[(t0>>>8)&0xff]^TS2[t0&0xff];
t1=TX1[(t1>>>24)&0xff]^TX2[(t1>>>16)&0xff]^TS1[(t1>>>8)&0xff]^TS2[t1&0xff];
t2=TX1[(t2>>>24)&0xff]^TX2[(t2>>>16)&0xff]^TS1[(t2>>>8)&0xff]^TS2[t2&0xff];
t3=TX1[(t3>>>24)&0xff]^TX2[(t3>>>16)&0xff]^TS1[(t3>>>8)&0xff]^TS2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t3=badc(t3); t0=cdab(t0); t1=dcba(t1);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
}
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
o[ 0+ooffset] = (byte)(X1[0xff&(t0>>>24)] ^ (rk[j ]>>>24));
o[ 1+ooffset] = (byte)(X2[0xff&(t0>>>16)] ^ (rk[j ]>>>16));
o[ 2+ooffset] = (byte)(S1[0xff&(t0>>> 8)] ^ (rk[j ]>>> 8));
o[ 3+ooffset] = (byte)(S2[0xff&(t0 )] ^ (rk[j ] ));
o[ 4+ooffset] = (byte)(X1[0xff&(t1>>>24)] ^ (rk[j+1]>>>24));
o[ 5+ooffset] = (byte)(X2[0xff&(t1>>>16)] ^ (rk[j+1]>>>16));
o[ 6+ooffset] = (byte)(S1[0xff&(t1>>> 8)] ^ (rk[j+1]>>> 8));
o[ 7+ooffset] = (byte)(S2[0xff&(t1 )] ^ (rk[j+1] ));
o[ 8+ooffset] = (byte)(X1[0xff&(t2>>>24)] ^ (rk[j+2]>>>24));
o[ 9+ooffset] = (byte)(X2[0xff&(t2>>>16)] ^ (rk[j+2]>>>16));
o[10+ooffset] = (byte)(S1[0xff&(t2>>> 8)] ^ (rk[j+2]>>> 8));
o[11+ooffset] = (byte)(S2[0xff&(t2 )] ^ (rk[j+2] ));
o[12+ooffset] = (byte)(X1[0xff&(t3>>>24)] ^ (rk[j+3]>>>24));
o[13+ooffset] = (byte)(X2[0xff&(t3>>>16)] ^ (rk[j+3]>>>16));
o[14+ooffset] = (byte)(S1[0xff&(t3>>> 8)] ^ (rk[j+3]>>> 8));
o[15+ooffset] = (byte)(S2[0xff&(t3 )] ^ (rk[j+3] ));
}
void encrypt(byte[] i, int ioffset, byte[] o, int ooffset) throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.encRoundKeys==null)
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
else
setupEncRoundKeys();
doCrypt(i, ioffset, this.encRoundKeys, this.numberOfRounds, o, ooffset);
}
byte[] encrypt(byte[] i, int ioffset) throws InvalidKeyException {
byte[] o = new byte[16];
this.encrypt(i, ioffset, o, 0);
return o;
}
public void decrypt(byte cipher[], byte plain[], int size)
throws InvalidKeyException {
int iLoop = size / 16;
int offset = 0;
for (int i = 0; i < iLoop; i++) {
decrypt(cipher, offset, plain, offset);
offset += 16;
}
}
void decrypt(byte[] i, int ioffset, byte[] o, int ooffset) throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.decRoundKeys==null)
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
else
setupDecRoundKeys();
doCrypt(i, ioffset, this.decRoundKeys, this.numberOfRounds, o, ooffset);
}
byte[] decrypt(byte[] i, int ioffset) throws InvalidKeyException {
byte[] o = new byte[16];
this.decrypt(i, ioffset, o, 0);
return o;
}
private static void doEncKeySetup(byte[] mk, int[] rk, int keyBits) {
int t0, t1, t2, t3, q, j=0;
int[] w0 = new int[4];
int[] w1 = new int[4];
int[] w2 = new int[4];
int[] w3 = new int[4];
w0[0] = toInt(mk[ 0], mk[ 1], mk[ 2], mk[ 3]);
w0[1] = toInt(mk[ 4], mk[ 5], mk[ 6], mk[ 7]);
w0[2] = toInt(mk[ 8], mk[ 9], mk[10], mk[11]);
w0[3] = toInt(mk[12], mk[13], mk[14], mk[15]);
q = (keyBits - 128) / 64;
t0=w0[0]^KRK[q][0]; t1=w0[1]^KRK[q][1];
t2=w0[2]^KRK[q][2]; t3=w0[3]^KRK[q][3];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
if (keyBits > 128) {
w1[0] = toInt(mk[16], mk[17], mk[18], mk[19]);
w1[1] = toInt(mk[20], mk[21], mk[22], mk[23]);
if (keyBits > 192) {
w1[2] = toInt(mk[24], mk[25], mk[26], mk[27]);
w1[3] = toInt(mk[28], mk[29], mk[30], mk[31]);
} else {
w1[2]=w1[3]=0;
}
} else {
w1[0]=w1[1]=w1[2]=w1[3]=0;
}
w1[0]^=t0; w1[1]^=t1; w1[2]^=t2; w1[3]^=t3;
t0=w1[0]; t1=w1[1]; t2=w1[2]; t3=w1[3];
q = (q==2)? 0 : (q+1);
t0^=KRK[q][0]; t1^=KRK[q][1]; t2^=KRK[q][2]; t3^=KRK[q][3];
t0=TX1[(t0>>>24)&0xff]^TX2[(t0>>>16)&0xff]^TS1[(t0>>>8)&0xff]^TS2[t0&0xff];
t1=TX1[(t1>>>24)&0xff]^TX2[(t1>>>16)&0xff]^TS1[(t1>>>8)&0xff]^TS2[t1&0xff];
t2=TX1[(t2>>>24)&0xff]^TX2[(t2>>>16)&0xff]^TS1[(t2>>>8)&0xff]^TS2[t2&0xff];
t3=TX1[(t3>>>24)&0xff]^TX2[(t3>>>16)&0xff]^TS1[(t3>>>8)&0xff]^TS2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t3=badc(t3); t0=cdab(t0); t1=dcba(t1);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t0^=w0[0]; t1^=w0[1]; t2^=w0[2]; t3^=w0[3];
w2[0]=t0; w2[1]=t1; w2[2]=t2; w2[3]=t3;
q = (q==2)? 0 : (q+1);
t0^=KRK[q][0]; t1^=KRK[q][1]; t2^=KRK[q][2]; t3^=KRK[q][3];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
w3[0]=t0^w1[0]; w3[1]=t1^w1[1]; w3[2]=t2^w1[2]; w3[3]=t3^w1[3];
gsrk(w0, w1, 19, rk, j); j+=4;
gsrk(w1, w2, 19, rk, j); j+=4;
gsrk(w2, w3, 19, rk, j); j+=4;
gsrk(w3, w0, 19, rk, j); j+=4;
gsrk(w0, w1, 31, rk, j); j+=4;
gsrk(w1, w2, 31, rk, j); j+=4;
gsrk(w2, w3, 31, rk, j); j+=4;
gsrk(w3, w0, 31, rk, j); j+=4;
gsrk(w0, w1, 67, rk, j); j+=4;
gsrk(w1, w2, 67, rk, j); j+=4;
gsrk(w2, w3, 67, rk, j); j+=4;
gsrk(w3, w0, 67, rk, j); j+=4;
gsrk(w0, w1, 97, rk, j); j+=4;
if (keyBits > 128) {
gsrk(w1, w2, 97, rk, j); j+=4;
gsrk(w2, w3, 97, rk, j); j+=4;
}
if (keyBits > 192) {
gsrk(w3, w0, 97, rk, j); j+=4;
gsrk(w0, w1, 109, rk, j);
}
}
/**
* Main bulk of the decryption key setup method. Here we assume that
* the int array rk already contains the encryption round keys.
* @param mk the master key
* @param rk the array which contains the encryption round keys at the
* beginning of the method execution. At the end of method execution
* this will hold the decryption round keys.
* @param keyBits the length of the master key
* @return
*/
private static void doDecKeySetup(byte[] mk, int[] rk, int keyBits) {
int a=0, z;
int[] t = new int[4];
z=32+keyBits/8;
swapBlocks(rk, 0, z);
a+=4; z-=4;
for (; a<z; a+=4, z-=4)
swapAndDiffuse(rk, a, z, t);
diff(rk, a, t, 0);
rk[a]=t[0]; rk[a+1]=t[1]; rk[a+2]=t[2]; rk[a+3]=t[3];
}
private static int toInt(byte b0, byte b1, byte b2, byte b3) {
return (b0&0xff)<<24 ^ (b1&0xff)<<16 ^ (b2&0xff)<<8 ^ b3&0xff;
}
private static void toByteArray(int i, byte[] b, int offset) {
b[offset ] = (byte)(i>>>24);
b[offset+1] = (byte)(i>>>16);
b[offset+2] = (byte)(i>>> 8);
b[offset+3] = (byte)(i );
}
private static int m(int t) {
return 0x00010101*((t>>>24)&0xff) ^ 0x01000101*((t>>>16)&0xff) ^
0x01010001*((t>>>8)&0xff) ^ 0x01010100*(t&0xff);
}
private static final int badc(int t) {
return ((t<<8)&0xff00ff00) ^ ((t>>>8)&0x00ff00ff);
}
private static final int cdab(int t) {
return ((t<<16)&0xffff0000) ^ ((t>>>16)&0x0000ffff);
}
private static final int dcba(int t) {
return (t&0x000000ff)<<24 ^ (t&0x0000ff00)<<8 ^ (t&0x00ff0000)>>>8 ^ (t&0xff000000)>>>24;
}
private static final void gsrk(int[] x, int[] y, int rot, int[] rk, int offset) {
int q=4-(rot/32), r=rot%32, s=32-r;
rk[offset] = x[0] ^ y[(q )%4]>>>r ^ y[(q+3)%4]<<s;
rk[offset+1] = x[1] ^ y[(q+1)%4]>>>r ^ y[(q )%4]<<s;
rk[offset+2] = x[2] ^ y[(q+2)%4]>>>r ^ y[(q+1)%4]<<s;
rk[offset+3] = x[3] ^ y[(q+3)%4]>>>r ^ y[(q+2)%4]<<s;
}
private static final void diff(int[] i, int offset1, int[] o, int offset2) {
int t0, t1, t2, t3;
t0=m(i[offset1]); t1=m(i[offset1+1]); t2=m(i[offset1+2]); t3=m(i[offset1+3]);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
o[offset2]=t0; o[offset2+1]=t1; o[offset2+2]=t2; o[offset2+3]=t3;
}
private static final void swapBlocks(int[] arr, int offset1, int offset2) {
int t;
for (int i=0; i<4; i++) {
t = arr[offset1+i];
arr[offset1+i] = arr[offset2+i];
arr[offset2+i] = t;
}
}
private static final void swapAndDiffuse(int[] arr, int offset1, int offset2, int[] tmp) {
diff(arr, offset1, tmp, 0);
diff(arr, offset2, arr, offset1);
arr[offset2]=tmp[0]; arr[offset2+1]=tmp[1];
arr[offset2+2]=tmp[2]; arr[offset2+3]=tmp[3];
}
private static void byteToHex(PrintStream out, byte b) {
char[] buf = {
HEX_DIGITS[(b >>> 4) & 0x0F],
HEX_DIGITS[ b & 0x0F]
};
out.print(new String(buf));
}
private static void intToHex(PrintStream out, int i) {
byte[] b = new byte[4];
toByteArray(i, b, 0);
byteToHex(out, b[0]);
byteToHex(out, b[1]);
byteToHex(out, b[2]);
byteToHex(out, b[3]);
}
private static void printRoundKeys(PrintStream out, int[] roundKeys) {
for (int i=0; i<roundKeys.length; ) { out.print("* ");
intToHex(out, roundKeys[i++]); out.print(" ");
intToHex(out, roundKeys[i++]); out.print(" ");
intToHex(out, roundKeys[i++]); out.print(" ");
intToHex(out, roundKeys[i++]); out.print(" \n");
}
}
public int getBufferSize(int size) {
if (size % 16 != 0)
size = (size / 16 + 1) * 16;
return size;
}
public void encrypt(byte plain[], byte cipher[], int size)throws InvalidKeyException {
int len = getBufferSize(size);
int iLoop = len / 16;
int iMod = size % 16;
int iCopySize = 16;
int offset = 0;
byte in[] = new byte[16];
for (int i = 0; i < iLoop; i++) {
if (i >= iLoop - 1)
if (iMod == 0)
iCopySize = 16;
else
iCopySize = iMod;
for (int j = 0; j < 16; j++)
in[j] = 0;
System.arraycopy(plain, offset, in, 0, iCopySize);
encrypt(in, 0, cipher, offset);
offset += iCopySize;
}
}
/* hex to byte[] convert */
public static byte[] hexToByteArray(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
byte[] ba = new byte[hex.length() / 2];
for (int i = 0; i < ba.length; i++) {
ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
return ba;
}
/* byte to hexa convert */
public static String byteArrayToHex(byte[] ba) {
if (ba == null || ba.length == 0) {
return null;
}
StringBuffer sb = new StringBuffer(ba.length * 2);
String hexNumber;
for (int x = 0; x < ba.length; x++) {
hexNumber = "0" + Integer.toHexString(0xff & ba[x]);
sb.append(hexNumber.substring(hexNumber.length() - 2));
}
return sb.toString();
}
public AriaEngine(int keySize, String privateKey)throws InvalidKeyException {
this.keySize = 0;
numberOfRounds = 0;
masterKey = null;
encRoundKeys = null;
decRoundKeys = null;
setKeySize(keySize);
byte[] mk = new byte[32];
this.privateKey = privateKey;
byte[] p1Key = this.publicKey.getBytes();
System.arraycopy(p1Key, 0, mk, 0, p1Key.length);
this.setKey(mk);
this.setupRoundKeys();
byte[] p2Key = new byte[32];
byte[] mk2 = new byte[32];
byte[] privateKeyByte = privateKey.getBytes();
if (privateKeyByte.length > 32) {
System.arraycopy(privateKeyByte, 0, mk2, 0, 32);
} else {
System.arraycopy(privateKeyByte, 0, mk2, 0, privateKeyByte.length);
}
byte[] makeKey = new byte[32];
this.encrypt(mk2, makeKey, mk2.length);
this.setKey(makeKey);
this.setupRoundKeys();
}
public static void main(String[] args) throws InvalidKeyException {
}
}

View File

@ -0,0 +1,355 @@
/**
* 전자정부 제공 ARIAUTIL
* ARIAUtil
*/
package nlib.cmm.crypto;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import nlib.cmm.service.NlibProperty;
public class AriaUtil {
public static final String PRIVATE_KEY = NlibProperty.getProperty("crypto.aria.defaultKey");
public static String ariaEncrypt(String str, String privateKey)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes().length];
p = str.getBytes();
int len = str.getBytes().length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return AriaEngine.byteArrayToHex(c).toUpperCase();
}
/**
* @param privateKey
* @param src
* @param dest
* @throws IOException
* @throws InvalidKeyException
* @throws UnsupportedEncodingException
*/
public static void ariaFileEncrypt(String privateKey, String src, String dest)
throws IOException, InvalidKeyException, UnsupportedEncodingException {
File f = new File(src);
FileInputStream fis = new FileInputStream(src);
long length = f.length();
byte[] b = new byte[(int)length];
try {
int offset = 0;
int numRead = 0;
while (offset < b.length && (numRead=fis.read(b, offset, b.length-offset)) >= 0) {
offset += numRead;
}
if (offset < b.length) {
throw new IOException(f.getName());
}
} finally{
fis.close();
}
AriaEngine instance = new AriaEngine(256, privateKey);
int len = b.length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
byte[] c = new byte[len];
System.arraycopy(b, 0, c, 0, b.length);
instance.encrypt(b, c, b.length);
FileOutputStream fos = new FileOutputStream(dest);
try {
fos.write(c);
} catch (IOException e) {
} finally {
try {
fos.close();
} catch (IOException e) {}
}
}
/*
*Aria 복호화
*/
public static String ariaDecrypt(String strHex, String privateKey)
throws InvalidKeyException, UnsupportedEncodingException {
if (strHex==null || strHex.equals("")) return "";
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = AriaEngine.hexToByteArray(strHex);
p = new byte[c.length];
instance.decrypt(c, p, p.length);
StringBuffer buf = new StringBuffer();
buf.append(new String(p));
return buf.toString().trim();
}
public static void ariaFileDecrypt(String privateKey, String src, String dest)
throws IOException, InvalidKeyException, UnsupportedEncodingException {
File f = new File(src);
FileInputStream fis = new FileInputStream(src);
long length = f.length();
byte[] b = new byte[(int)length];
try {
int offset = 0;
int numRead = 0;
while (offset < b.length && (numRead=fis.read(b, offset, b.length-offset)) >= 0) {
offset += numRead;
}
if (offset < b.length) {
throw new IOException(f.getName());
}
} finally{
fis.close();
}
AriaEngine instance = new AriaEngine(256, privateKey);
int len = b.length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
byte[] c = new byte[len];
System.arraycopy(b, 0, c, 0, b.length);
instance.decrypt(b, c, b.length);
FileOutputStream fos = new FileOutputStream(dest);
try {
fos.write(c);
} catch (IOException e) {
} finally {
try {
fos.close();
} catch (IOException e) {}
}
}
private static String makeMasterKey(String str) {
String appendStr = "Naravision KebiPortal Solution";
StringBuffer buf = new StringBuffer();
buf.append(str).append(appendStr);
return buf.substring(0,32);
}
/*
*Aria 기본 복호화
*/
public static String ariaDecrypt(String strHex)
throws InvalidKeyException, UnsupportedEncodingException {
String originalData = strHex;
if (strHex==null || strHex.equals("")) return "";
StringBuffer buf = null;
try {
String privateKey = PRIVATE_KEY;
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = hexToByteArray(strHex);
p = new byte[c.length];
instance.decrypt(c, p, p.length);
buf = new StringBuffer();
buf.append(new String(p));
return buf.toString().trim();
} catch (Exception e) {
e.printStackTrace();
return originalData;
}
}
/*
*aria 기본 암호화
*/
public static String ariaEncrypt(String str)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
String privateKey = PRIVATE_KEY;
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes().length];
p = str.getBytes();
int len = str.getBytes().length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return byteArrayToHex(c).toUpperCase();
}
/*
*캐릭터셋 변경 암호화
*/
public static String ariaCharEncrypt(String str, String charset)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
String privateKey = PRIVATE_KEY;
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes(charset).length];
p = str.getBytes(charset);
int len = str.getBytes(charset).length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return byteArrayToHex(c).toUpperCase();
}
/*
*캐릭터셋 변경 암호화
*(서버타입설정 열람서버 : read, 등록관리서버 : regi)
*/
public static String ariaCharEncrypt(String str, String charset, String server)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
String privateKey = "";
if(server.equals("regi")) privateKey = PRIVATE_KEY;
else privateKey = PRIVATE_KEY;
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes(charset).length];
p = str.getBytes(charset);
int len = str.getBytes(charset).length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return byteArrayToHex(c).toUpperCase();
}
/*
*Aria 캐릭터셋 변경 복호화
*/
public static String ariaCharDecrypt(String strHex, String charset)
throws InvalidKeyException, UnsupportedEncodingException {
if (strHex==null || strHex.equals("")) return "";
String privateKey = PRIVATE_KEY;
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = hexToByteArray(strHex);
p = new byte[c.length];
instance.decrypt(c, p, p.length);
StringBuffer buf = new StringBuffer();
buf.append(new String(p,charset));
return buf.toString().trim();
}
/*
*Aria 캐릭터셋 변경 복호화
*(서버타입설정 열람서버 : read, 등록관리서버 : regi)
*/
public static String ariaCharDecrypt(String strHex, String charset, String server)
throws InvalidKeyException, UnsupportedEncodingException {
if (strHex==null || strHex.equals("")) return "";
String privateKey = "";
if(server.equals("regi")) privateKey = PRIVATE_KEY;
else privateKey = PRIVATE_KEY;
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = hexToByteArray(strHex);
p = new byte[c.length];
instance.decrypt(c, p, p.length);
StringBuffer buf = new StringBuffer();
buf.append(new String(p,charset));
return buf.toString().trim();
}
// hex to byte[]
public static byte[] hexToByteArray(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
byte[] ba = new byte[hex.length() / 2];
try {
for (int i = 0; i < ba.length; i++) {
ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
}catch(NumberFormatException e){
//
}catch(Exception e) {
//
}
return ba;
}
// byte[] to hex
public static String byteArrayToHex(byte[] ba) {
if (ba == null || ba.length == 0) {
return null;
}
StringBuffer sb = new StringBuffer(ba.length * 2);
String hexNumber;
for (int x = 0; x < ba.length; x++) {
hexNumber = "0" + Integer.toHexString(0xff & ba[x]);
sb.append(hexNumber.substring(hexNumber.length() - 2));
}
return sb.toString();
}
}

View File

@ -1,102 +0,0 @@
package nlib.cmm.snslogin;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
public class NaverLoginBO {
/* 인증 요청문을 구성하는 파라미터 */
//client_id: 애플리케이션 등록 발급받은 클라이언트 아이디
//response_type: 인증 과정에 대한 구분값. code로 값이 고정돼 있습니다.
//redirect_uri: 네이버 로그인 인증의 결과를 전달받을 콜백 URL(URL 인코딩). 애플리케이션을 등록할 Callback URL에 설정한 정보입니다.
//state: 애플리케이션이 생성한 상태 토큰
private final static String CLIENT_ID = "jefkoYhSfrQ3TtZz5mTp";
private final static String CLIENT_SECRET = "E2qAGaLEaG";
private static String REDIRECT_URI = "";
private final static String SESSION_STATE = "oauth_state";
/* 프로필 조회 API URL */
private final static String PROFILE_API_URL = "https://openapi.naver.com/v1/nid/me";
public void setRedirect_url(String REDIRECT_URI) {
this.REDIRECT_URI = REDIRECT_URI;
}
/* 네이버 아이디로 인증 URL 생성 Method */
public String getAuthorizationUrl(HttpSession session) {
/* 세션 유효성 검증을 위하여 난수를 생성 */
String state = generateRandomString();
/* 생성한 난수 값을 session에 저장 */
setSession(session,state);
System.out.println(getSession(session));
/* Scribe에서 제공하는 인증 URL 생성 기능을 이용하여 네아로 인증 URL 생성 */
OAuth20Service oauthService = new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(REDIRECT_URI)
.state(state) //앞서 생성한 난수값을 인증 URL생성시 사용함
.build(NaverLoginApi.instance());
return oauthService.getAuthorizationUrl();
}
/* 네이버아이디로 Callback 처리 및 AccessToken 획득 Method */
public OAuth2AccessToken getAccessToken(HttpSession session, String code, String state) throws IOException{
/* Callback으로 전달받은 세선검증용 난수값과 세션에 저장되어있는 값이 일치하는지 확인 */
String sessionState = getSession(session);
if(StringUtils.pathEquals(sessionState, state)){
OAuth20Service oauthService = new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(REDIRECT_URI)
.state(state)
.build(NaverLoginApi.instance());
/* Scribe에서 제공하는 AccessToken 획득 기능으로 네아로 Access Token을 획득 */
OAuth2AccessToken accessToken = oauthService.getAccessToken(code);
return accessToken;
}
return null;
}
/* 세션 유효성 검증을 위한 난수 생성기 */
private String generateRandomString() {
return UUID.randomUUID().toString();
}
/* http session에 데이터 저장 */
private void setSession(HttpSession session,String state){
session.setAttribute(SESSION_STATE, state);
}
/* http session에서 데이터 가져오기 */
private String getSession(HttpSession session){
return (String) session.getAttribute(SESSION_STATE);
}
/* Access Token을 이용하여 네이버 사용자 프로필 API를 호출 */
public String getUserProfile(OAuth2AccessToken oauthToken) throws IOException{
OAuth20Service oauthService =new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(REDIRECT_URI).build(NaverLoginApi.instance());
OAuthRequest request = new OAuthRequest(Verb.GET, PROFILE_API_URL, oauthService);
oauthService.signRequest(oauthToken, request);
Response response = request.send();
return response.getBody();
}
}

View File

@ -14,6 +14,7 @@ import egovframework.rte.fdl.cryptography.EgovEnvCryptoService;
import egovframework.rte.fdl.cryptography.EgovPasswordEncoder;
import egovframework.rte.fdl.cryptography.impl.EgovARIACryptoServiceImpl;
import nlib.cmm.crypto.AriaCrypto;
import nlib.cmm.service.NlibProperty;
import nlib.util.StringUtil;
/**
@ -61,46 +62,49 @@ public class SampleEncoderController {
public String getSampleInfoForm(ModelMap model
, @RequestParam(required=false) String hash
, @RequestParam(required=false) String plainText
, @RequestParam(required=false) String key
, @RequestParam(required=false) String encodedText
) throws Exception {
String msg = null;
String encodedText = null;
String decodedText = null;
if(StringUtil.isEmpty(hash)) {
msg = "암호화 알고리즘을 선택하여 주시기 바랍니다.";
} else if(StringUtil.isEmpty(plainText)) {
msg = "암호화할 문자열을 입력하여 주시기 바랍니다.";
} else {
} else if(StringUtil.isNotEmpty(plainText)) {
// 암호처리
log.debug("암호화 처리 시작 =" + plainText + "=");
if("sha-256".equals(hash)) {
if("sha-256".equalsIgnoreCase(hash)) {
encodedText = egovPasswordEncoder.encryptPassword(plainText);
} else if("aria".equals(hash)) {
if(StringUtil.isEmpty(key)) encodedText = ariaCrypto.encode(plainText);
else encodedText = ariaCrypto.encode(plainText, key);
encodedText = ariaCrypto.encode(plainText);
log.debug(" Aria plainText=" + plainText);
log.debug(" Aria encodedText=" + encodedText);
if(StringUtil.isEmpty(key)) decodedText = ariaCrypto.decode(encodedText);
else decodedText = ariaCrypto.decode(encodedText, key);
decodedText = ariaCrypto.decode(encodedText);
log.debug(" Aria after decoding, decodedText=" + decodedText);
} else {
msg = "암호화 알고리즘이 적합하지 않습니다.";
}
} else if("aria".equalsIgnoreCase(hash) && StringUtil.isNotEmpty(encodedText)) {
// 복호처리
decodedText = ariaCrypto.decode(encodedText);
log.debug(" Aria after decoding, decodedText=" + decodedText);
} else {
msg = "암호화할 문자열을 입력하여 주시기 바랍니다.";
}
model.addAttribute("msg", msg);
model.addAttribute("hash", hash);
model.addAttribute("hash", StringUtil.getString(hash, "aria"));
model.addAttribute("plainText", plainText);
model.addAttribute("encodedText", encodedText);
model.addAttribute("decodedText", decodedText);
model.addAttribute("key", key);
model.addAttribute("key", NlibProperty.getProperty("crypto.aria.defaultKey"));
return "nlib/sample/getSampleEncoder";
}

View File

@ -6,6 +6,7 @@ import java.util.HashMap;
import org.springframework.stereotype.Repository;
import egovframework.com.cmm.service.impl.EgovComAbstractDAO;
import nlib.cmm.crypto.AriaCrypto;
import nlib.restful.service.DataApiReqVO;
import nlib.restful.service.DataApiResVO;
import nlib.user.service.NlibLoginVO;
@ -22,7 +23,19 @@ public class LoginDAO extends EgovComAbstractDAO {
}
public NlibLoginVO selectLoginUserInfo(NlibLoginVO nLoginParamVO) {
return (NlibLoginVO) selectOne("LoginDAO.selectLoginUserInfo", nLoginParamVO);
NlibLoginVO nlibLoginVO = selectOne("LoginDAO.selectLoginUserInfo", nLoginParamVO);
// 개인정보 암호화 내용 복호화 처리
if(nlibLoginVO != null) {
nlibLoginVO.setMobileNo(AriaCrypto.decode(nlibLoginVO.getMobileNo()));
nlibLoginVO.setEmail(AriaCrypto.decode(nlibLoginVO.getEmail()));
nlibLoginVO.setZipCode(AriaCrypto.decode(nlibLoginVO.getZipCode()));
nlibLoginVO.setAddress(AriaCrypto.decode(nlibLoginVO.getAddress()));
nlibLoginVO.setAddressDetail(AriaCrypto.decode(nlibLoginVO.getAddressDetail()));
nlibLoginVO.setBirthday(AriaCrypto.decode(nlibLoginVO.getBirthday()));
}
return (NlibLoginVO) nlibLoginVO;
}
public void insertLoginLog(NlibLoginVO userVO) {

View File

@ -63,7 +63,6 @@ import nlib.cmm.service.NlibProperty;
import nlib.cmm.session.SessionConfig;
import nlib.cmm.snslogin.GoogleOAuthResponse;
import nlib.cmm.snslogin.KakaoController;
import nlib.cmm.snslogin.NaverLoginBO;
import nlib.info.service.InformService;
import nlib.mail.EmailSender;
import nlib.mail.service.EmailVO;
@ -126,15 +125,6 @@ public class MemberController {
@Resource(name = "egovEnvPasswordEncoderService")
EgovPasswordEncoder egovPasswordEncoder;
/* NaverLoginBO */
private NaverLoginBO naverLoginBO;
private String apiResult = null;
@Autowired
private void setNaverLoginBO(NaverLoginBO naverLoginBO) {
this.naverLoginBO = naverLoginBO;
}
@Autowired
private EmailSender emailSender;

View File

@ -65,8 +65,6 @@
<bean id="antPathMater" class="org.springframework.util.AntPathMatcher" />
<bean id="defaultTraceHandler" class="egovframework.rte.fdl.cmmn.trace.handler.DefaultTraceHandler" />
<bean id="naverLoginBO" class="nlib.cmm.snslogin.NaverLoginBO" />
<!-- MULTIPART RESOLVERS -->
<!-- regular spring resolver -->
<bean id="spring.RegularCommonsMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

View File

@ -29,7 +29,7 @@
<appender-ref ref="console"/>
</logger>
<Logger name="org.springframework" level="INFO" additivity="false">
<Logger name="org.springframework" level="DEBUG" additivity="false">
<AppenderRef ref="console" />
</Logger>
<Root level="DEBUG">

View File

@ -55,16 +55,15 @@
<h2>${pageTitle} </h2>
msg : ${msg} <br />
hash : <input name="hash" id="hash" value="${hash}" /> ("sha-256" 또는 "aria" 입력) <br />
key : ${key} (hash 알고리즘이 aria인 경우) <br />
plainText : <input name="plainText" id="plainText" value="${plainText}" /> <br />
encodedText : <input name="encodedText" id="encodedText" value="${encodedText}" /> <br />
decodedText : <input name="decodedText" id="decodedText" value="${decodedText}" /> <br />
key : <input name="key" id="key" value="${key}" /> (hash 알고리즘이 aria인 경우 입력 필수) <br />
decodedText : ${decodedText} <br />
<div style="clear:both;">&nbsp;</div>
<!-- 하단 버튼 -->
<div class="btn">
<input type="submit" value="암호화 처리" />
<input type="submit" value="암/복호화 실행" />
</div>
</div>

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>nlib</display-name>
<filter>