2013년 3월 20일 수요일

암호화/복호화


import java.security.*;
import javax.crypto.*;
public class SimpleExample {
    public static void main(String [] args) throws Exception {
        if( args.length != 1) {
            System.out.println("Usage : java SimpleExample text ");
            System.exit(1);
        }
        String text = args[0];
        System.out.println("Generating a DESded (TripleDES) key...");
        // Triple DES 생성
        KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
        keyGenerator.init(168); // 키의 크기를 168비트로 초기화
        Key key = keyGenerator.generateKey();
        System.out.println("키생성이 완료되었음");
        System.out.println("key=" + key);
        // Cipher를 생성, 사용할 키로 초기화
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte [] plainText = text.getBytes("UTF8");
        System.out.println("Plain Text : ");
        for (int i = 0; i < plainText.length ; i++) {
            System.out.print(plainText[i] + " ");
        }
        // 암호화 시작
        byte [] cipherText = cipher.doFinal(plainText);
        // 암호문서 출력
        System.out.println("\nCipher Text : ");
        for (int i = 0; i < cipherText.length ; i++) {
            System.out.print(cipherText[i] + " ");
        }
        //복호화 모드로서 다시 초기화
        cipher.init(Cipher.DECRYPT_MODE, key);
        //복호화 수행
        byte [] decryptedText = cipher.doFinal(cipherText);
        String output =  new String(decryptedText, "UTF8");
        System.out.println("\nDecrypted Text : " + output);
    }
}

MD5 암호화



import java.security.*;


public class MD5Password
  {
  public static String getEncodedPassword(String clearTextPassword)
               throws NoSuchAlgorithmException
    {
    MessageDigest md = MessageDigest.getInstance("MD5");

    md.update(clearTextPassword.getBytes());

    return HexString.bufferToHex(md.digest());
    }

  public static boolean testPassword(String clearTextTestPassword,
                     String encodedActualPassword)
                     throws NoSuchAlgorithmException
    {
    String encodedTestPassword = MD5Password.getEncodedPassword(
                      clearTextTestPassword);

    return (encodedTestPassword.equals(encodedActualPassword));
    }
  }


Download Page - JSP



<%
/**   ================================================================
      Mobicator
      ----------------------------------------------------------------
      @description {file} Parameter 지정한 Id 해당하는 file Download
                        * CAUTION: JSP File File Download하는 File이므로
                         임의로  '% >' '< %'사이를 띄우거나 CR/LF 줘서는 안된다.
      @param
            file Download File Id
      @include
            N/A
      @usage
            /download.jsp?file={file_id}
      @author pluto
      @date 2008. 02. 20
      ================================================================
*/
%><%@ page language="java" contentType="application/unknown; charset=UTF-8" pageEncoding="UTF-8"
%><%-- All of Import here
--%><%@page import="java.io.File"
%><%@page import="java.io.InputStream"
%><%@page import="java.io.OutputStream"
%><%@page import="java.io.FileInputStream"
%><%@page import="java.io.BufferedOutputStream"
%><%@page import="java.io.BufferedInputStream"
%><%@page import="java.io.UnsupportedEncodingException"
%><%!
      private int DEFAULT_BUFFER_SIZE                 = 2048;

      private String HEAD_CONTENT_TYPE                = "Content-Type";
      private String HEAD_CONTENT_DISPOSITION         = "Content-Disposition";
      private String HEAD_CONTENT_TRANSFER_ENCODE     = "Content-Transfer-Encoding";
      private String HEAD_PRAGMA                            = "Pragma";
      private String HEAD_EXPIRES                           = "Expires";
      private String HEAD_CONTENT_LENGTH              = "Content-Length";

      private String CONTENT_TYPE_MATTER              = "doesn/matter;";
      private String CONTENT_TYPE_OCTET               = "application/octet-stream;";
      private String CONTENT_TRANSFER_ENCODE          = "binary;";
      private String PRAGMA                                 = "no-cache;";
      private String EXPIRES                                = "-1";

      private String USER_AGENT                             = "USER-AGENT";
      private String ENCODING                               = "UTF-8";
      private String CHAR_SET                               = "charset=" + ENCODING + ";";
      private String FILE_NAME                              = "filename=";
      private String ATTACHMENT                             = "attachment;";
      private String LOCAL_PATH                             = "/localPath/";

      private String MSIE_4                                 = "MSIE 4";
      private String MSIE_5_5                               = "MSIE 5.5";
      private String FIRE_FOX                               = "Firefox";

      public String getFileName( String fileName, String ua ) throws UnsupportedEncodingException {
            if( ua.indexOf( FIRE_FOX ) >= 0 ) {
                  return fileName;
            } else {
                 return java.net.URLEncoder.encode( fileName, "UTF-8" ).replaceAll( "\\+", "%20" );
            }
      }
%><%
      InputStream                   inStream = null;
      OutputStream                  outStream = null;
      byte[]                              buffer = null;

      String                              docBase = getServletContext().getRealPath( "/" );
      String                              ua = request.getHeader( USER_AGENT );
      String                              id = request.getParameter( "file" );
      String                              url = request.getRequestURL().toString();
      File                          downloadFile = new File( LOCAL_PATH + id );
      String                              fileName = getFileName( downloadFile.getName(), ua );

      if( ua.indexOf( MSIE_4 ) >= 0 || ua.indexOf( MSIE_5_5 ) >= 0 ) {
            response.setHeader( HEAD_CONTENT_TYPE, CONTENT_TYPE_MATTER + CHAR_SET );
            response.setHeader( HEAD_CONTENT_DISPOSITION, FILE_NAME + fileName + ";" );
      } else {
            response.setHeader( HEAD_CONTENT_TYPE, CONTENT_TYPE_OCTET + CHAR_SET );
            response.setHeader( HEAD_CONTENT_DISPOSITION, ATTACHMENT + FILE_NAME + fileName + ";" );
      }
      response.setHeader( HEAD_CONTENT_TRANSFER_ENCODE, CONTENT_TRANSFER_ENCODE );
      response.setHeader( HEAD_PRAGMA, PRAGMA );
      response.setHeader( HEAD_EXPIRES, EXPIRES );
      response.setHeader( HEAD_CONTENT_LENGTH, String.valueOf( downloadFile.length() ) );

      if( downloadFile.isFile() ) {
            try {
                  inStream = new BufferedInputStream( new FileInputStream( downloadFile ) );
                  outStream = new BufferedOutputStream( response.getOutputStream() );
                  buffer = new byte[ DEFAULT_BUFFER_SIZE ];
                  int                           bufferSize = 0;
                  while( (bufferSize = inStream.read( buffer )) != -1 ) {
                        outStream.write( buffer, 0, bufferSize );
                        outStream.flush();
                  }
            } catch( Exception e ) {
                  e.printStackTrace();
            } finally {
                  if( inStream != null ) {
                        inStream.close();
                  }
            }
      }
%>

java.sql.SQLException: Access denied for user... Error 해결


해당 HOST에 대한 USER 접근 권한이 없어 발생하는 오류로 아래의 명령으로 해결할 수 있다.

mysql> grant all privileges on DATABASE.TABLE_NAME to USER@HOST_NAME identified by "PASSWD";

Java Project와 Java Web Project의 참조 Package

o Java Project
 * Package Name List
  - org.eclipse.core.resources.prefs
  - org.eclipse.jdt.core.prefs
  - org.eclipse.jdt.ui.prefs

 * .class File
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
 * .project File

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ProjectName</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
o Java Web(Dynamic) Project
* Package Name List
 - org.eclipse.jdt.core.prefs
 - org.eclipse.jst.common.project.facet.core.prefs
 - org.eclipse.wst.common.component
 - org.eclipse.wst.common.project.facet.core.xml

* .classpath File
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v5.5"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="output" path="WebContent/WEB-INF/classes"/>
</classpath>
* .project File

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ProjectName</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
</natures>
</projectDescription>

Google Web Toolkit


  • Sample code for this article
  • The Maven plugin for use with GWT
  • The Google-Web-Toolkit group on Google Groups
  • The GWT Team Blog
  • The GWT Home Page
  • Finder에서 숨김 파일 보기


    Terminal에서 아래 명령을 실행
    $ defaults write com.apple.Finder AppleShowAllFiles YES

    Mac용 Java Decompiler Eclipse Plug-in


    Mac용 Eclipse Plug-in으로 사용할 수 있는 Java Decompiler

    Eclipse의 "Install New Software" Menu를 이용해 아래 URL로 plug-in을 Install한다.

    URL:  http://java.decompiler.free.fr/jd-eclipse/update

    Potential resource leak: may not be closed

    본 오류는 선언한 Object에 Assign된 Resource가 어떤 경우에 정상적으로 Release(반환)되지 않을 수 있음을 경고하는 것이다.
    일반적인 경우 문제가 되지 않겠지만,
    예를 들어 두 개의 선언된 Object가 있고 그 Object 모두에 대해 Exception을 Throw하는 Method를 호출하는 경우를 예상해보자.
    그럼 그 두 Object의 Method에 대해 catch를 할 것이고
    finally Block에는 Release하는 Code가 들어갈 것이다.
    그런데 대개의 경우 Release하는 Code 또한 관련 Exception을 Throw하는 것이 일반적이다.
    따라서 Release Code에서 catch를 하게 될 것이고
    Code를 줄일 목적으로 두 개의 Release Code를 하나로 묶어 catch를 하게 된다면
    그 때 바로 이 경고를 보게 될 것이다.

    즉, 이는 아래의 Sample Code에서 처럼,
    finally Block 내 두 개의 Release Code 중 첫 번째 Code에서 Exception이 발생했을 경우
    나머지 하나(두 번째)의 Object에 대한 Release Code를 실행할 수 있을 것이란 보장을 할 수 없기 때문이다.
    왜냐하면, 첫 번째 Code에서 Exception이 발생하면 두 번째 Release Code를 실행하지 못 하고 catch Block으로 갈 것이기 때문이다.
    따라서 이를 알리기 위한 똑똑한 경고라 하겠다.

    "Potential resource leak: 'xxx' may not be closed"를 발생시키는 Code
    try {
    // do something with br and bw;
    } catch(Exception e) {
    e.printStackTrace();
    } finally {
    try {
    if(br != null) {
    br.close();
    br = null;
    }
    if(bw != null) {
    bw.close();
    bw = null;
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    옳은 Exception Handling...


    BufferedReader br = null;
    BufferedWriter bw = null;


    try {
    // do something with br and bw;
    catch(Exception e) {
    e.printStackTrace();
    finally {
    if(br != null) {
    try {
    br.close();
    br = null;
    catch (IOException e) {
    e.printStackTrace();
    }
    }
    if(bw != null) {
    try {
    bw.close();
    bw = null;
    catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    위 Code에서 보는 바와 같이 finally Block내 두 개의 Object Release를 위한 Code별로 Exception을 Handling하고 있다.


    2012년 6월 26일 화요일

    Adding a TCP/IP Route to the Routing Table



    2개 이상의 Ethernet Card나 노트북의 유선과 무선 등을 이용해 2개 이상의 Network을 사용할 경우가 있는데
    이때 보통은 OS 또는 사용자가 정한 우선순위에 따라 Routing된 Network을 사용하게 된다.
    그러나 경우에 따라서는 반드시 지정된 Network으로 Routing이 되어야할 필요가 있는데,
    예를 들어, 사용하고 있는 노트북의 유선과 무선을 통해 두 개의 서로 다른 Network을 사용하는 경우를 생각해 보자.


    아래 그림은 서로다른 두 개의 Network A, B를 표현한 것으로,
    A Network은 VPN망을 사용하며 Printer가 연결되어 있고, B Network은 광캐이블이 연결된 Modem으로 구성된 일반적인 인터넷 구성 Network으로
    이 곳에 할당된 Public IP는 방화벽을 갖는 제 3의 Network에 있는 서버로 접근할 수 있도록 Inbound가 열려있는 Network이라고 가정하자.


    그림의 Host#1과 같이 유선으로는 B Network에 연결되어 있고 무선으로는 A Network에 연결되어있고 유선의 Ethernet Card가 높은 우선순위를 같는다고 하자.
    이때 Host#1은 특별한 설정이 없다면 10.10.10.2로 Print 요청을 보내면 우선순위가 높은 B Network에서 10.10.10.2를 찾으려 할 것이고, B Network은 이 IP에 대한 Routing정보를 어떠한 Routing Table에도 가지고 있지 않으므로, 이 요청은 B Network에 Broadcasting되었다가 어떠한 응답도 받지 못한채 Time-out이 될 때까지 대기하다 결국 요청은 실패하게 된다.
    이럴때 특정 IP 대역에 대해 Routing되어야할 적절한 Network을 지정해 줌으로써
    필요한 요청을 처리할 수 있다.






    그럼 위의 예에서 처럼 A Network에 있는 Printer#1으로 요청이 전달될 수 있도록 설정하는 방법을 Unix-like Machine과 Windows Machine으로 구분해 알아보도록 하자.
    • Unix-like
    Syntax:
    route add [xnet|-host] target [netmask ] [gw Gw] dev
    route del [-net|-host] target [gw Gw] [netmask Nw] [[dev] If]
    route add default gw dev

    • Windows
    Syntax:
    route add xxx.xxx.xxx.xxx mask xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx metric xx if xx
    route add "network" mask "subnet mask" "gateway ip" matric "metric number" if "ethernet number"
    route add 157.0.0.0 mask 255.0.0.0  157.55.80.1 metric 3 if 2
                  ^destination    ^mask      ^gateway    metric^   ^Interface
    예를 들어 Network A, B를 모두 갖는 Host#1에서 Network A에 있는 Printer#1을 이용해 어떤 문서를 출력하고자 한다고 가정하자. 그러면 Subnet Mask가 255.255.255.0이고 10.10.10.0에 해당하는 IP를 갖는 Network A로 Routing될 수 있도록 설정해 주어야 하는데 그 방법은 아래와 같다.  이때 Network A에 연결된 무선 Ethernet Card의 번호는 15번(eth1)이고 Printer#1의 IP는 그림에서와 같이 10.10.10.2이고 Network A로의 Default Gateway는 192.168.0.1이라고 가정한다.

    Example:
    • Unix-like
    route add -net 10.10.10.0 netmask 255.255.255.0 gw 192.168.0.1 dev eth1
    • Windows
    route -p add 10.10.10.0 mask 255.255.255.0 192.168.0.1 if 15
    • -p : 영구적으로 설정해 이 Option을 사용하지 않을 때와 달리 Rebooting 후에도 유지된다.
    • 참고로, 본 명령을 실행하려면 Command창을 관리자 권한으로 실행해야한다.