출처 : http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=60392&sca=%BA%B8%BE%C8&page=2

freeSSHd Download : http://www.freesshd.com

2000년대 접어들면서 리눅스에서는 암호화 통신인 ssh 사용이 일반화 되었습니다.
그리고 ssh 를 이용하여 ftp 대신 sftp 서비스를 이용하기도 합니다.
저 역시 대부분의 서버작업을 ssh 를 이용하며 ftp 대신 sftp 를 이용합니다.

그런데 윈도우에서는 서버작업시 터미널을 주로 이용하는데 문제는 ftp 였습니다.
그래서 혹시나 sftp 를 지원하는 프로그램이 없나 찾아보게 되었습니다.
윈도우용 ssh 클라이언트 프로그램으로는 대표적으로 putty(ssh) 나 winscp(sftp) 등이 있지만
윈도우 ssh Server 용 프로그램은 본적이 없었던거 같습니다.

구글링을 해보니.. cygwin 으로 openssh 를 동작시키는 방법이 있었지만
http://pigtail.net/LRP/printsrv/cygwin-sshd.html
귀차니즘과 어느정도 아시는 분들이나 문제없이 설치할듯 하고 해서 계속 찾아보니..
몇가지 프로그램을 발견했지만 대부분 유료가 많았습니다. 그러다 freeSSHd 라는 프로그램을 찾게되었고
그 프로그램을 이용하여 쉽게 구축할수 있더군요.

다음은 freeSSHd 를 이용하여 설치 및 설정을 하는 방법입니다.

테스트환경 : 윈도우 XP 프로페셔널
필요 환경 : NT 계열
freeSSHd Download : http://www.freesshd.com

다운로드에 가시면 하시면 2개의 설치 실행화일을 받으실수 있습니다.
freeSSHd.exe 는 ssh server 를 설치하는 install 화일이고 freeUserImport.exe 는 윈도우 계정을
ssh 서버로 접근가능하게 컨버팅해주는 util 입니다.

우선 freeSSHd.exe 를 실행합니다.
설치중에 어려움은 없을거고 설치 중간에 시스템 서비스로 등록하겠느냐고 나오는데 그건 여러분의 판단에
맏기겠습니다. 저같은경우는 등록해서 사용했습니다.

이제 설치가 완료되고 freeSSHd 셋팅을 할 차례입니다.
트레이에 못보던 아이콘이 생기고 클릭하면 freeSSHd 아래와 같이 셋팅창이 뜰겁니다.


※ 관리자 권한이 있는 사용자로 서버를 시작해야 한다.


1. Server satatus
Telnet Server 와 SSH Server 의 실행 과 중지를 하는곳입니다.

사용자 삽입 이미지



2. Telnet
텔넷 서버의 설정을 하는경우 설정합니다. 그러나 텔넷은 권장하지 않습니다.
텔넷을 사용할거라면 굳이 freeSSHd를 설치할 필요가 없죠.

사용자 삽입 이미지



3. SSH
Listen address 에서 특정 IP를 지정할수도 있습니다.
Max number of connections 설정은 최대 접속갯수를 설정합니다. 0은 제한이 없다는 것입니다.
Idle timeout 은 입력이 없으면 얼마후에 접속을 서버쪽에서 종료시키는 기능입니다. 0은 제한이 없습니다.
Command shell 은 SSH 접속시 사용할 명령어 실행하기 위한 인터페이스이고 리눅스에서는 shell 이죠.
그외 옵션은 아래와 같이 설정하고....
RSA , DSA 설정은 기본값으로 두고.. 다음

사용자 삽입 이미지


로그인 Fail 이 나면서 로그인이 안되는 버그가 있는 경우 Use new console engine 체크 항목을 해제하고 feeeSSHd unload 후 재시작하면 된다.


4. Authentication
ssh 인증을 어떤식으로 할것이냐는 것입니다.
패스워드 방식과 공개키 방식이 있습니다.
저는 두가지 경우를 모두 선택했습니다. 여기서 Allowed 와 Required 는 차이가 없습니다.
공개키 생성을 이용하기 위해서는 puttygen.exe 를 이용하시면 됩니다.

RSA로만 사용하는 경우에는 Password authentication 은 Disabled 선택하고, Public key authentication 항목을 Allowed 또는 Required로 선택한다.


puttygen.exe 다운로드

공개키 인증 방법은 접속하는 Client에서 RSA로 개인키/공개키를 생성 후 Server 에 자신의 공개키를 등록하여 아이디만 가지고 로그인을 하는 방법이다.

1. puttygen을 실행시키고 SSH-2 RSA / 2048 bit 선택 후 Generate 버튼을 클릭한 후 프로그레스바 밑 빈 공간에 마우스를 계속 움직여서 key pair 를 생성한다.
2. 키 생성이 완료되면 Public key for pasting into OpenSSH authorized_keys file 항목에 공개키가 표시되는데 그 부분을 드래그 하여 복사한 후 사용자 계정 id와 동일한 파일명으로 저장한다. (확장자 없이)
3. Key passphrase 항목에 비밀번호를 입력한다. (비밀번호 없이 해도 된다)
3-1. Save private key 버튼을 클릭하여 private key 파일도 저장한다. (보통 파일명은 상관없지만 사용자ID.ppk 로 저장)
3-2. Java 에서 (JSch) library로 접속하는 경우 OpenSSH key 파일을 사용하므로 메뉴 중 Conversions > Export OpenSSH key 를 실행하여 사용자ID.pem / 사용자ID.key 등 파일명으로 저장한다.

위 puttygen 을 실행하여 만든 공개키 파일만 모아둔 폴더를 아래 feeeSSHd > Authentication 탭의 Public key folder 를 해당 폴더로 지정한다.

사용자 삽입 이미지


1. 파일질라 (Filezilla)에서 개인키/공개키로 접속하는 경우 파일질라 메뉴 편집 > 설정에서 연결 > SFTP 항목을 선택하고 키 파일 추가 버튼을 클릭 후 위에서 생성한 개인키 (*.ppk) 파일을 선택하고 암호 입력 후 암호화되지 않은 개인키 파일을 별도로 저장한다.
2. 파일질라에서 접속 시 로그온 유형은 인터랙티브를 선택하고 사용자 ID만 입력하여 로그인하면 된다.



5. Encryption
어떤 암호화 알고리즘을 사용할것인가를 선택합니다.

사용자 삽입 이미지



6. Tunneling
freeSSHd 를 통해 터널링을 지원할것인가의 여부를 설정합니다.
실제 원격에서 putty 등을 통해 터널링을 이용할수있습니다. putty 설정을 통해 외부접속하는 방법은
인터넷에 ssh 터널링으로 검색해보면 될듯하고 스쿨에도 꽤 자료가 있습니다.

사용자 삽입 이미지



7. SFTP
sftp 접속시 홈디렉토리를 설정합니다.
여러가지 sftp 프로그램이 있지만 개인적으로는 winscp 를 추천합니다.
winscp 다운로드

사용자 삽입 이미지



8. Automatic updates
업데이트 설정입니다.

사용자 삽입 이미지



9. Online users
현재 접속해 있는 User 리스트를 출력합니다.
해당유저를 두번클릭하면 Disconnect 버튼이 활성화 되며 해당 유저의 접속을 강제로 종료시킬수 있습니다.

사용자 삽입 이미지



10. Logging
아래와 같이 체크하면 사용자들의 접속 기록을 확인할수 있습니다.

사용자 삽입 이미지



11. Host restrictions
접속 제한 IP들을 설정하는 곳입니다.
tcp_wrapper 와 같은 보안정책을 실행합니다.
Allow only these IP addresses : 전체를 막고 지정한 특정 IP의 접속을 허용합니다.
Refuse these IP addresses : 전체를 풀고 지정한 특정 IP의 접속을 차단합니다.

사용자 삽입 이미지



12 Users
현재 등록된 User를 등록, 수정, 삭제 할수 있습니다.
Add 를 클릭하게 되면 아래와 같이 새창이 뜹니다.
Login  : ID입력
Authorization : 인증은 윈도인증, 패스워드, 공개키인증방식을 선택할수 있습니다.
패스워드 방식을 선택하면 패스워드 입력창이 활성화 됩니다.

사용자 삽입 이미지


RSA (개인키, 공개키)로 로그인하는 경우에는 Authorization 항목을 Public key (SSH only) 항목을 선택한다.


여기까지 설정이 되었다면 freeSSHd 의 셋팅이 모두 끝났습니다.
하지만 일반적인 경우 접속이 되지 않습니다. 그건 윈도우의 방화벽 때문입니다.
대부분의 분들은 잘 아실거라 생각하지만 혹시 잘모르시는 분들도 있다고 보고 윈도우 방화벽에서
22번 포트를 푸는 방법을 설명하자면...
제어판 => Windows 방화벽 => 고급탭 선택 후 설정하려는 연결설정을 선택한후 설정을 클릭
=> 고급설정창이 뜨고 추가 버튼을 클릭한후 아래의 이미지에 나와있는것처럼 설정을 하시면됩니다.

사용자 삽입 이미지



쩝 설명을 적는다는게 이미지 캡쳐하다보니 시간이 꽤 걸리네요..


===============================================================================================================================


* 설치 후 간단 사용법

1. Server status 탭에서 Telnet / SSH 영역의 Click here to start it. 클릭.
    "The specified address is already in use" 메시지가 나올 경우 해당 서비스 탭 선택 후 Port 변경해야 함

2. Users 탭 > Add 버튼 클릭
    Login : 사용자ID
    Authorization : Password stored as SHA1 hash 선택
    Password : 비밀번호
    User can use : 모두 선택

3. 접속 시 Putty 사용 (Aromnet은 로그인 안됨)


===============================================================================================================================



freeFTPd 설치

다운로드 : http://www.freesshd.com

1. 설치 후 freeFTPd 실행

2. Users > Add 버튼 클릭
        Login : 사용자 아이디
        Authorization : Password stored as SHA1 hash
        Password : 비밀번호
        Home directory : $SERVERROOT

3. SFTP
        Listen address : 기본값
        Port : 포트번호
        SFTP root directory : FTP 루트 디렉토리 설정





참고 : http://comptb.cects.com/1264-install-configure-ssh-on-windows


OpenSSH 다운로드 : http://sshwindows.sourceforge.net/


1. OpenSSH 다운로드 및 설치

2. 포트 변경 시 OpenSSH\etc\sshd_config 을 열어 아래처럼 변경

 #Port 22 ==> Port 원하는포트


3. cmd 창

c:\OpenSSH>mkgroup -l >> ..\etc\group
c:\OpenSSH>mkpasswd -l -u 윈도우사용자아이디 >> ..\etc\passwd
c:\OpenSSH>net start opensshd


================================================================================================================
================================================================================================================

출처 : 대전국제IT교육센터 정성재 강사
         http://se.uzoogom.com/134

1. ssh에 대하여
ssh는 Secure shell의 약자로 원격 머신에 로긴하여 그 안에 있는 명령들을 실행하는 프로그램이다.
기본적으로 사용법은 telnet과 유사하지만, telnet은 클라이언트와 서버간의 데이터전송시 일반텍스
트형태로 패킷을 전달하여 패킷의 내용을 유출당할 수 있지만, ssh는 패킷전송시 암호화시키므로 안
전하게 전송할 수 있다.
현재 ssh는 ssh2와 ssh1 두 가지 프로토콜이 있는데, ssh2는 ssh1을 개선한 것으로 호환은 되지만
기본적으로 호환성을 포함하고 있는 것이 아니다. ssh2서버 혼자서는 ssh1 연결을 관리할 수 없으므
로 ssh1 서버가 반드시 있어야 한다.
ssh1과 ssh2의 차이점을 기술적으로 보면 SSH2는 이중-암호화 RSA키 교환을 비롯하여 다양한 키-교
환 방법을 지원한다.


2. SSH설치하기
(1) 개요: 리눅스에서 사용하는 ssh는 두가지가 있다. 하나는 원 제작처인 www.ssh.com에서 제작한
          것과 www.openssh.org가 제작한 것이 있다. 대부분의 배포판에서 openssh에서 제작한 것을
          기본으로 지원하므로 openssh를 사용하도록 한다.
(2) 구성: SSH의 기본 구성은 SSH 서버와 SSH클라이언트로 구분된다. SSH로 접속을 하려면 SSH서버
          설치되어 있어야 하며, 클라이언트에서도 SSH가 지원되는 프로그램을 이용하여 접속해야
         한다.
(3) 설치: 현재 대부분의 배포판 리눅스에 Openssh가 기본으로 설치되어 있으므로 설치부분은 일단
          생략하도록 한다.

3. OpenSSH를 이용하여 ssh서버 설정하기
(1) 서버설정하기
   1) 설명: 서버관련 주 설정파일은 /etc/ssh/sshd_config 이다. 보통 기본 설정파일 그대로 사용해
           도 상관없지만 그룹이나 사용자들을 제한하려면 몇가지 지시자를 건드려야 한다.
   2) 환경설정(sshd_config)파일의 주요항목 분석
   #       $OpenBSD: sshd_config,v 1.34 2001/02/24 10:37:26 deraadt Exp $

   # This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin

   # This is the sshd server system-wide configuration file.  See sshd(8)
   # for more information.

   Port 22                      // ssh가 사용하는 포트를 지정

   Protocol 2,1                 // openssh는 프로토콜 버전을 원하는 대로 선택할 수 있다. SSH는
                                //SSH1과 SSH2가 있는데 현재와 같이 설정하면 SSH1, SSH2 모두
                                //접속이 가능하다.

   #ListenAddress 0.0.0.0       // sshd 데몬이 귀를 기울일 주소이다. 0.0.0.0은 모든 곳을 말한
   #ListenAddress ::            //다.

   HostKey /etc/ssh/ssh_host_key        // SSH1의 호스트키 위치를 지정한다.

   HostKey /etc/ssh/ssh_host_rsa_key    // SSH2의 RSA암호화방식의 호스트키 위치를 지정한다.

   HostKey /etc/ssh/ssh_host_dsa_key    // SSH2의 DSA암호화방식의 호스트키 위치를 지정한다.

   ServerKeyBits 768                    // 서버 키의 비트수를 정의한다. 최소값은 512이고, 기본
                                        //값은 768이다.

   LoginGraceTime 600                   // 유저가 로그인에 실패했을 경우 서버가 연결을 끊는
                                        //시간이다. 값이 0이면 제한이 없다.

   KeyRegenerationInterval 3600         // 서버의 키는 한번 접속이 이루어진 뒤에 자동적으로
                                        //다시 만들어진다. 다시 만드는 목적은 나중에 호스트의
                                        //세션에 있는 키를 캡처해서 암호를 해독하거나 훔친키를
                                        //사용하지 못하도록 하기 위함이다. 값이 0이면 키는 다
                                        //시 만들어지지 않는다 .기본값은 3600초이다.

   PermitRootLogin yes                  // root 로그인 허용여부를 결정하는 것이다. yes, no, wi
                                        //thout-password를 사용할 수 있다. 현재 yes는 직접
                                        //root로 접속이 가능하다. 이것을 허용하지 않으려면 no
                                        //나 without-password로 바꾼다.
   #
   # Don't read ~/.rhosts and ~/.shosts files
   IgnoreRhosts yes                     // .rhosts 파일을 무시할 것이냐는 설정이다. 기본값은
                                        //.rhosts파일을 무시한다.

   # Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
   #IgnoreUserKnownHosts yes
   StrictModes yes                       // 로그인을 허용하기 전에 파일모드, 사용자 홈디렉토리
                                         //소유권, 원격 호스트의 파일들을 SSH데몬이 체크할 수
                                         //있도록 해주는 설정이다.

   X11Forwarding yes                    // 원격에서 X11 포워딩을 허용하는 것이다. 이 옵션을
                                        //yes로 설정하면 xhost보다 안전한 방법으로 원격에 있는
                                        //X프로그램을 사용할 수 있다.

   X11DisplayOffset 10                  // X11 포워딩될 때 디스플레이 번호를 지정해준다.

   PrintMotd yes                        // SSH로그인시에 /etc/motd파일의 내용을 프린트되도록
                                        //설정한다.

   KeepAlive yes                        // 클라이언트의 접속이 끊어졌는지 체크를 위해 서버가
                                        //일정시간 메시지를 전달한다.

   # Logging
   SyslogFacility AUTHPRIV              // syslog관련 facility코드이다.

   LogLevel INFO                        // 로그레벨을 지정한다. 기본값은 INFO이며, 그 외의 값
                                        //으로 QUIET(기록하지 않음), FATAL(치명적인 오류),
                                        //ERROR, VERBOSE, DEBUGS 등이 있다.

   #obsoletes QuietMode and FascistLogging

   RhostsAuthentication no              // rhost관련 인증허가여부를 지정한다.
   #
   # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
   RhostsRSAAuthentication no           // rhost나 /etc/hosts.equiv파일이 있으면 이것을 사용해
                                        //인증을 한다. 이것은 보안상 좋지 않은 방법이므로 기본
                                        //값은 no이다.
   #
   RSAAuthentication yes                // RSA인증을 사용한다.

   # To disable tunneled clear text passwords, change to no here!
   PasswordAuthentication yes           // 패스워드 인증을 허용한다. 이 옵션은 프로토콜 버전 1
                                        //과 2 모두 적용된다.

   PermitEmptyPasswords no              // 패스워드 인증할 때 서버가 비어있는 패스워드를 인정
                                        //하는 것이다. 기본값은 no이다.

   # Comment to enable s/key passwords or PAM interactive authentication
   # NB. Neither of these are compiled in by default. Please read the
   # notes in the sshd(8) manpage before enabling this on a PAM system.
   ChallengeResponseAuthentication no

   # To change Kerberos options
   #KerberosAuthentication no
   #KerberosOrLocalPasswd yes
   #AFSTokenPassing no
   #KerberosTicketCleanup no

   # Kerberos TGT Passing does only work with the AFS kaserver
   #KerberosTgtPassing yes

   #CheckMail yes
   #UseLogin no

   #MaxStartups 10:30:60
   #Banner /etc/issue.net
   #ReverseMappingCheck yes

   Subsystem       sftp    /usr/libexec/openssh/sftp-server
   // sftp는 프로토콜 버전 2에서 사용되는 것으로 ssh와 같이 ftp의 보안을 강화하기 위해 사용되
   //는 보안 ftp프로그램이다. sftp서버를 사용하기 위한 항목이다.

(2) 클라이언트 설정하기
   1) 설명: 클라이언트의 전체유저 설정파일은 /etc/ssh/ssh_config로 설정할 수 있다. Host지시자
           를 사용하여 접속할 서버마다 다른 옵션을 사용할 수 있다. SSH서버에 접속하는데 있어서
           꼭 필요한 설정은 아니다.
   2) 주요환경 설정파일(ssh_config) 분석
     #       $OpenBSD: ssh_config,v 1.9 2001/03/10 12:53:51 deraadt Exp $

     # This is ssh client systemwide configuration file.  See ssh(1) for more
     # information.  This file provides defaults for users, and the values can
     # be changed in per-user configuration files or on the command line.

     # Configuration data is parsed as follows:  // 클라이언트 설정파일은 3가지 방법으로 설정
     #  1. command line options                  // command line options
     #  2. user-specific file                    // 유저별 설정파일 지정($HOME/.ssh/config)
     #  3. system-wide file                      // 시스템 전체 설정 파일(/etc/ssh/ssh_config)
     # Any configuration value is only changed the first time it is set.
     # Thus, host-specific definitions should be at the beginning of the
     # configuration file, and defaults at the end.

     # Site-wide defaults for various options

     # Host *                     // 모든 호스트에 연결할 수 있다.

     #   ForwardAgent no          // 인증에이전트의 연결을 원격 호스트에 포워드할 수 있다.
     #   ForwardX11 no            // X11 커넥션이 자동으로 된다. 매번 서버에 연결할 때 command
                                  //line에서 -X옵션없이 기본적으로 X포워딩기능을 사용할 수
                                  //있다.
     #   RhostsAuthentication no
     #   RhostsRSAAuthentication yes
     #   RSAAuthentication yes
     #   PasswordAuthentication yes
     #   FallBackToRsh no
     #   UseRsh no
     #   BatchMode no
     #   CheckHostIP yes               // 이 부분이 yes가 되어 있으면 접속할 때마다 리모트 서
                                       //버의 IP주소를 know_hosts파일과 대조해본다. 이것은
                                       //DNS Spoofing에 의해 호스트키의 변경을 알 수 있다.
     #   StrictHostKeyChecking yes
     #   IdentityFile ~/.ssh/identity  // 사용자의 RSA인증 identity를 읽는다. 기본적으로 사용
                                       //자의 홈디렉토리에 $HOME/.ssh/identity에 저장되어 있
                                       //다.

     #   IdentityFile ~/.ssh/id_dsa    // 사용자의 DSA인증 identity를 읽는다. 기본적으로 사용
                                       //홈디렉토리의 $HOME/.ssh/id_dsa에 있다.
     #   IdentityFile ~/.ssh/id_rsa1
     #   IdentityFile ~/.ssh/id_rsa2
     #   Port 22
     #   Protocol 2,1
     #   Cipher blowfish               // 프로토콜 버전1에서 세션을 암호화하기 위한 암호알고리
                                       //즘을 지정한다. blowfish, 3des를 지정할 수 있다.
     #   EscapeChar ~
     Host *
             ForwardX11 yes
             Protocol 2,1
     // 모든 호스트에 접속할 때 ssh2와 ssh1을 사용하며 X11 포워딩을 허가한다.
   3) 사용예
    ㄱ. Host *.mybestone.com
        Protocol 1
         => mybestone.com 서버에 접속할 때는 ssh1 프로토콜을 사용한다.
    ㄴ. Host kldp.org
        Protocol 2
        Compression yes
        CompressionLevel 9
         => kldp.org에 접속할 때는 ssh2와 압축 옵션을 사용한다.

4. 클라이언트에서 SSH 사용하기
(1) 리눅스클라이언트에서 서버로 접속하기
   1) 설명: 리눅스에서 리눅스로 접속한다면 별도의 설정이나 프로그램의 설치없이 가능하다. 대부
           분의 배포판은 openssh가 설치되어 있다. 윈도우에서 리눅스서버로 접속한다면 ssh클라이
           언트를 설치해야 한다.
   2) 리눅스 클라이언트에서 리눅스 서버로 접속하기
    ㄱ. 접속하는 방법:
      a. ssh 계정명@도메인명
      b. ssh -l 계정 도메인명
    ㄴ. 사용예
      a. ssh
posein@mybestone.com
      b. ssh -l posein mybestone.com
    ㄷ. 접속
       [posein@www posein]$ ssh
posein@mybestone.com
       The authenticity of host 'mybestone.com (203.247.40.252)' can't be established.
       RSA key fingerprint is 89:41:93:58:5c:6d:bb:01:84:cb:3d:81:68:80:56:7b.
       Are you sure you want to continue connecting (yes/no)? yes
         => 처음 ssh로 해당 서버에 접속하면 나타나는 메시지로 접속할 서버의 호스트키가
           ~/.ssh/known_hosts(ssh2인 경우에는 known_hosts2)파일에 저장된다. yes로 대답한다.
       Warning: Permanently added 'mybestone.com,203.247.40.252' (RSA) to the list of known
       hosts.
      
posein@mybestone.com's password:
         => yes라고 대답하면 원래 서버의 패스워드를 물어오고, 패스워드를 입력하면 텔넷과 동일
           한 작업을 할 수 있다.
(2) 윈도우에서 리눅스 서버로 접속하기
    => 윈도우에서 ssh를 사용하려면 ssh클라이언트 프로그램의 설치가 필요하다. 대표적인 프로그
      램으로 SecureCRT가 있다. 상용으로 성능이 매우 우수하다. 관련사이트는 http://www.vandyke.
      com이다.

5. 클라이언트에서 SSH서버로 접속하기
(1) 리눅스클라이언트에서 접속하기
   [posein@neuro posein]$ ssh
posein@mybestone.com
   The authenticity of host 'mybestone.com (203.247.40.252)' can't be established.
   RSA key fingerprint is a8:69:69:83:67:8b:50:27:41:ad:b8:e9:0d:b2:a8:88.
   Are you sure you want to continue connecting (yes/no)? yes  // yes라고 입력
   Warning: Permanently added 'mybestone.com,203.247.40.252' (RSA) to the list of .
  
posein@mybestone.com's password:         // 해당 서버의 패스워드를 입력한다.
   [posein@mybestone posein]$
    => 접속되었다.
(2) 윈도우클라이언트에서 서버에 접속하기
   1) 설명: 윈도우에서는 ssh를 이용하려면 별도의 전용 프로그램이 필요하다. http://www.openssh.
           org/windows.html에 가면 윈도우용 클라이언트 프로그램의 목록을 확인할 수 있다. 그러
           나 이 페이지에 있는 프로그램들은 대부분 ssh1만 지원한다. 여기서는 상용프로그램인
           SecureCRT라는 프로그램으로 해본다.
   2) 사용예
    ㄱ. SecureCRT를 선택한다.
    ㄴ. 'Quick Connect'아이콘을 선택한다.
    ㄷ. 'Quick Connect'메뉴에서
       Protocol ssh1
       Hostname 접속하고자하는_도메인
       Port 22
       Username 사용자
       를 입력하고 [connect]를 누른다.
    ㄹ. 처음 접속하면 'New Host Key'라는 창이 뜨는데 [Accept & Save]를 클릭한다.
    ㅁ. 'Enter Password'라는 창이 나오면 사용자패스워드를 입력하고 [ok]를 누른다.


6. 인증키를 이용하여 SSH서버로 접속하기
(1) 개요: SSH서버로 접속할 때 일반적으로는 패스워드를 입력하여 접속하지만 인증키를 이용하여
          접속할 수도 있다. 이 방법을 사용하면 로그인할 때마다 암호를 직접 입력하지 않고 생성
          된 인증키로만 로그인할 수 있다.
(2) 사용예
   1) 인증키를 만들기: ssh-keygen명령을 이용한다.
     [posein@www posein]$ ssh-keygen -t rsa    // RSA 암호화방법으로 인증키를 생성한다.
                                               //Protocol 1 버전용 rsa1와 Protocol 2 버전용
                                               //rsa, dsa 를 -t옵션을 사용하여 선택할 수 있다.
     Generating public/private rsa key pair.
     Enter file in which to save the key (/home/posein/.ssh/id_rsa):
      => 키가 저장될 곳과 파일명을 물어보는데 디폴트로 그냥 엔터를 넘어가도 된다. 넘어가면
        다음과 같이 인증키 암호를 물어온다.
     Created directory '/home/posein/.ssh'.               // 관련 디렉토리를 생성한다.
     Enter passphrase (empty for no passphrase):
      => 원하는 암호를 두번 입력한다.
     Your identification has been saved in /home/posein/.ssh/id_rsa.
     Your public key has been saved in /home/posein/.ssh/id_rsa.pub.
     The key fingerprint is:
     7b:60:56:eb:82:d2:43:40:48:a6:d0:8e:f4:7a:8c:f1
posein@xxx.com
      => ~/.ssh 디렉토리에 키가 생성된다. 참고로 인증키 생성시 인증키 암호를 입력하지 않으면
       ssh 접속시 암호를 입력하지 않아도 접속할 수 있다. 그러나 보안상 위험하므로 피하도록
       한다.
   2) 퍼블릭 키 사용하기
     ㄱ. 설명: 인증키를 생성하면 ~/.ssh 디렉토리안에 한쌍의 키(예를 들면 id_rsa  id_rsa.pub)가
              생성되어 있다. 여기서 퍼블릭키인 id_rsa.pub을 접속할 리모트 서버에 ~/.ssh디렉토
              리에 authorized_keys라는 이름으로 복사한다.
     ㄴ. 사용예
        [posein@neuro posein]$ scp ~/.ssh/id_rsa.pub
posein@mybestone.com:.ssh/authorized_keys
       
posein@mybestone.com's password:             // 해당 서버의 패스워드를 입력한다.
        id_rsa.pub           100% |*************************************************|   235       00:00
   3) 접속하기
     [posein@neuro posein]$ ssh
posein@mybestone.com
      => 만약 인증키생성시에 패스워드를 입력하지 않으면 패스워드없이 즉시 로그인된다.

7. SSH관련 유틸리티
(1) scp(secure copy)
   1) 설명: 원격지의 서버에 있는 파일을 ssh인증과 암호화된 기법을 이용하여 복사하거나 복사해
           올 수 있도록 해준다. 전체적인 사용법은 복사명령인 cp와 유사하다.
   2) 사용법
     scp [option] 복사하고자하는_파일명 사용자아이디@원격지주소:파일명
      => 원격지주소의 파일을 복사하고자 할때는 반대로 지정하면 된다.
   3) option: 대체적으로 cp명령의 옵션과 유사하다.
     -r : 특정디렉토리의 하위디렉토리까지 모두 복사해준다.
   4) 사용예
    ㄱ. scp a.txt
posein@mybestone.com:test
         => 로컬에 있는 a.txt를 원격지서버에 test라는 이름으로 복사한다. 만약 test가 디렉토리
           이며 test라는 디렉토리안에 a.txt라는 이름으로 복사된다.
    ㄴ. scp
posein@mybestone.com:pds/sample.c .
         => 원격지서버의 posein이라는 사용자의 홈디렉토리에서 ~/pds/sample.c를 현재 디렉토리에
           복사한다.
   5) 응용예: 개인 홈디렉토리의 .ssh/config 파일에 접속하고자하는 SSH서버에 관한 정보를 입력
             하면 /etc/hosts파일의 역할처럼 간단히 입력만으로도 접속이 가능하다.
     [posein@neuro posein]$ cat ~/.ssh/config
     Host *bestone                 // 접속하고자하는 서버의 간단한 이름을 지정한다.
     HostName www.mybestone.com    // 실제 호스트네임을 기록한다.
     User posein                   // 서버 계정을 적는다.
     ForwardAgent yes              // 인증대리인이 포워드가 되도록 지정한다.
     [posein@neuro posein]$ scp passwd.txt bestone:.
      => 현재 디렉토리의 passwd.txt를 bestone(www.mybestone.com의 posein이라는 사용자의 홈디렉
        토리)의 지정된 장소에 복사한다.
(2) sftp
   1) 설명: 원격지 서버에 파일을 전송할 때 신뢰할 수 있는 암호화된 기법을 이용하여 전송하거나
           전송받는다. 전체적인 사용법은 ftp명령과 유사하다.
   2) 사용법
     sftp 사용자아이디@원격지주소
   3) 사용예
     sftp
posein@mybestone.com

 

출처 : http://ygang.tistory.com/109

기본적으로 JavaScript 코드는 자신이 로드된 도메인만 통신이 가능하고, 크로스 도메인(다른 도메인)과는 통신할 수 없다. 이것은 동일 출처 정책이라고 한다. 이것은 AJAX 통신에도 그대로 적용된다. 보안 관점에서 동일 출처 정책은 악의적인 JavaScript 코드가 다른 도메인의 데이터에 대한 무단 액세스를 할 수 없도록 한다는 점에서는 매우 효과적이다.

이 정책은 두 가지 형태의 웹앱에서는 장애물이 된다.

첫번째는 여러가지 Open API에 접근해서 클라이언트 매시업 기능을 필요로 하는 웹액에서는 장애물이 된다.

두번째는 웹앱을 네이트브앱으로 만들 경우 기기의 로컬에서 로딩된 자바스크립트는 외부 서버에서 엑세스 할 수 없다. 

 

  <script type="text/javascript">
    $(document).bind("mobileninit",function(){
      $.support.cors =true;
      $.mobile.allowCrossDomainPages = true;
    });
 </script>

 

$.support.cors-true 는 jQuery의 $.ajax() 메소드가 크로스 도메인 페이지를 로드할 수 있도록 해준다. 그리고 $.mobile.allowCrossDomainPage=true 는 jQuery Mobile API가 크로스 도메인 페이지를 로드할 수 있도록 해 준다.

jQuery Mobile 웹액을 네이티브앱으로 변활할 경우 주의할 점은 시작 HTML(홈페이지)에 기술된 다른 페이지로의 링크 경로를 크로스 도메인 절대 경로로 변경해야 한다.

XStream : http://xstream.codehaus.org/download.html


XStream Maven

<dependency>
      <groupId>com.thoughtworks.xstream</groupId>
      <artifactId>xstream</artifactId>
      <version>1.4.4</version>
</dependency> 



Source

 package iwa.xml;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.junit.Test;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

public class MapConverterTest {

 @Test
 public void marshal() throws Exception {
  Map<String,Object> map = new HashMap<String,Object>();
        map.put("name","chris");
        map.put("island","faranga");
        Map<String,Object> map2 = new HashMap<String,Object>();
        map2.put("test", "테스트");
        map2.put("code", "1");
        map.put("tests", map2);
        Map<String,Object> map3 = new HashMap<String,Object>();
        map3.put("national", "korea");
        map3.put("dev", "kkk");
        map2.put("devList", map3);

        XStream x = new XStream();
        x.alias("root", Map.class);
        x.registerConverter(new MapEntryConverter());
       
        String xml = x.toXML(map);
        System.out.println(xml);
 }
 
 @Test
 public void unmarshal() throws Exception {
  String xml = "<root><tests><test>테스트</test><code>1</code><devList><dev>kkk</dev><national>korea</national></devList></tests><name>chris</name><island>faranga</island></root>";
  XStream x = new XStream();
  x.autodetectAnnotations(true);
  x.alias("root", HashMap.class);
  x.registerConverter(new MapEntryConverter());
  InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
  HashMap<String, Object> o = (HashMap<String, Object>)(x.fromXML(is));
  System.out.println(o);
 }
 
 public static class MapEntryConverter implements Converter {
      
  public boolean canConvert(Class clazz) {
            return AbstractMap.class.isAssignableFrom(clazz);
        }

        public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
            AbstractMap map = (AbstractMap) value;
            for (Object obj : map.entrySet()) {
                Entry entry = (Entry) obj;
                Object entryValue = entry.getValue();
               
                if(entryValue instanceof Map) {
                 writer.startNode(entry.getKey().toString());
                 marshal(entry.getValue(), writer, context);
                 writer.endNode();
                 continue;
                }
               
                writer.startNode(entry.getKey().toString());
                writer.setValue(entryValue.toString());
                writer.endNode();
            }
        }
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
         Map<String, Object> map = new HashMap<String, Object>();

            while(reader.hasMoreChildren()) {
                reader.moveDown();
                if(reader.hasMoreChildren()) {
                 Map<String, Object> childMap = new HashMap<String, Object>();
                 map.put(reader.getNodeName(), childMap);
                 unmarshalHierarchical(reader, context, childMap);
                 reader.moveUp();
                 continue;
                }
                map.put(reader.getNodeName(), reader.getValue());
                reader.moveUp();
            }
            return map;
        }
       
        private void unmarshalHierarchical(HierarchicalStreamReader reader, UnmarshallingContext context, Map<String, Object> map) {
            while(reader.hasMoreChildren()) {
                reader.moveDown();
                if(reader.hasMoreChildren()) {
                 Map<String, Object> childMap = new HashMap<String, Object>();
                 map.put(reader.getNodeName(), childMap);
                 unmarshalHierarchical(reader, context, childMap);
                 reader.moveUp();
                 continue;
                }
                map.put(reader.getNodeName(), reader.getValue());
                reader.moveUp();
            }
        }
 }
 
}


================================================================================================================================================
================================================================================================================================================

package test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.junit.Test;

import test.model.AppModel;

//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(locations = { "classpath:../config/spring/egov/context-*.xml", "classpath:../config/spring/iwa/*.xml"})
public class TestXml {
 
 
 
 @Test
 public void test1() throws Exception {
  JAXBContext context = null;
  List<AppModel> list = null;
  Marshaller marshaller = null;
  
  context = JAXBContext.newInstance(AppModel.class);
  list = new ArrayList<AppModel>();
  AppModel app = new AppModel();
  app.setAppId("1");
  app.setAppNm("앱1");
  list.add(app);
  
  AppModel app2 = new AppModel();
  app2.setAppId("2");
  app2.setAppNm("앱2");
  list.add(app2);
  
  marshaller = context.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
  marshaller.marshal(app2, System.out);
 }
 
 
 @Test
 public void test2() throws Exception {
  Map<String,Object> userData = new HashMap<String,Object>();
  Map<String,String> nameStruct = new HashMap<String,String>();
  nameStruct.put("first", "Joe");
  nameStruct.put("last", "Sixpack");
  userData.put("name", nameStruct);
  userData.put("gender", "MALE");
  userData.put("verified", Boolean.FALSE);
  userData.put("userImage", "Rm9vYmFyIQ==");
  
  JAXBContext jc = JAXBContext.newInstance(Map.class);
  Marshaller marshaller = jc.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  marshaller.marshal(userData, System.out);
 }
 
 
 
 
 
 /*
 private String rootNodeName = "itemList";
 
 @SuppressWarnings("unchecked")
 public List<Map<String, Object>> fromXML(String xmlData) throws Exception {
  XStream xStream = new XStream(new DomDriver("UTF-8"));
  Mapper mapper = xStream.getMapper();
  xStream.alias(rootNodeName, List.class);
  xStream.registerConverter(new MapConverter(mapper));
  return (List<Map<String, Object>>) xStream .fromXML(xmlData);
 }
 
 public String toXML(List<Map<String, Object>> mapList) {
  XStream xStream = new XStream(new DomDriver("UTF-8"));
  Mapper mapper = xStream.getMapper();
  xStream.alias(rootNodeName, List.class);
  xStream.registerConverter(new MapConverter(mapper));
  return xStream.toXML(mapList);
 }
 
 public String toXML(Map<String, Object> map) {
  XStream xStream = new XStream(new DomDriver("UTF-8"));
  Mapper mapper = xStream.getMapper();
  xStream.alias(rootNodeName, Map.class);
  xStream.registerConverter(new MapConverter(mapper));
  return xStream.toXML(map);
 }
 
 public static class MapConverter extends AbstractCollectionConverter implements Converter {
  *//**
   * Map 객체가 될 Node 명
   *//*
  private String nodeName = "itemInfo";

  public MapConverter(Mapper mapper) {
   super(mapper);
  }

  *//**
   * Converting 가능한 샘플인지 판단
   *//*
  @Override
  public boolean canConvert(Class type) {
   boolean flag = type.equals(java.util.ArrayList.class);
   return flag;
  }

  *//** Map을 XML로 변환하는 규칙 *//*
  @Override
  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
   List<Map<String, Object>> list = (List<Map<String, Object>>) source;
   for(int inx=0; inx<list.size(); inx++) {
    Map<String, Object> data = list.get(inx);
    writer.startNode(nodeName);
    for (Object obj : data.entrySet()) {
     Entry<String, Object> ety = (Entry<String, Object>)obj;
     writer.startNode(ety.getKey().toString());
     writer.setValue(ety.getValue().toString());
     writer.endNode();
    }
    writer.endNode();
   }
  }

  *//** XML을 List<Map>으로 변환하는 규칙 *//*
  @Override
  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
   List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
   Map<String, Object> element = null;
   for (; reader.hasMoreChildren(); reader.moveUp()) {
    reader.moveDown();
    element = new HashMap<String, Object>();
    for (; reader.hasMoreChildren(); reader.moveUp()) {
     reader.moveDown();
     String tempValue = reader.getValue();
     String tempKey = reader.getNodeName();
     
     if (tempValue != null) {
      tempValue = tempValue.trim().replaceAll("\n", "");
     }
     element.put(tempKey, tempValue);
    }
    resultList.add(element);
   } 
   return resultList;
  }
  
 }
 */
}




 


출처 : https://minwoohi.tistory.com/42

데이터 설계 및 표준화 작업할 때 논리 모델 작성 후 표준 용어 사전, 표준 도메인 사전에 따라  칼럼명, 데이터 타입을 엑셀에 입력한다. ERWIN에서 엑셀 파일을 통해 칼럼명 맵핑을 쉽게 할 수 있다.

ERWIN 파일 작성할 때 논리/물리 변환 가능한 타입으로 생성

속성명을 다음과 같이 작성한다.

속성명에 해당하는 칼럼명을 오른쪽 열에 입력

다른이름으로 저장해 CSV 파일 형식으로 저장. CSV 형식으로 변환할 수 없는 문자가 섞여있다는 식의 팝업 나타나면 확인 클릭해 생성.
▶ ERWIN 또한 한글 경로를 인식하지 못한다. 반드시 영어로 파일명 작성 후 저장

ERWIN - TOOLS -NAMES - Edit Naming Standards 클릭. 칼럼명 작명에 대한 규칙을 CSV 파일로 등록

GLOSSARY 탭에서 IMPORT 클릭 이후 생성한 CSV 파일 열기

다음과 같이 속성, 칼럼명을 가져오는 것 확인할 수 있다. 위 저장 버튼 클릭

Naming Standard Files 뜻하는 nsm 확장자로 파일 저장

생성한 파일을 등록시키는 절차.
Tools - Names - Model Naming Options 클릭

General 탭에 Use File 라디오버튼 체크 - Browse 클릭해 생성한 nsm 파일 등록

Name Mapping에 Attribute to Column 체크 후 OK

Logical을 Physical로 바꿔주면 다음과 같이 자동 매핑된 칼럼명이 ERD에 출력됨을 확인할 수 있다.
실무에서 수천개 이상의 속성을 사용하게 될 때 굉장히 유용할 것이다.


================================================================================================================



출처 : http://blog.naver.com/remebers/50095401683

보통 Logical 에서 한글명으로 작업을 하고 나면, Physical도 한글명으로 되어 있다.

하지만, 모델링 작업 한 것을 DBMS로 보내주려면 Physical을 영문명으로 변경해 줘야 한다.

 

ERwin에서는 NSM이라는 기능을 이용하여 영문명으로 변경해줄 수 있다.

 

1. 아래의 그림과 같이, ERwin 메뉴의 Tools > Names > Edit Naming Standards 를 클릭한다

 

 

 

2. 아래의 그림처럼 맨 밑의 Glossary 탭으로 이동한다.

    - Word/Words에는 한글명

    - Abbreviation 에는 영문 Full Name Or 약어

    - Alternate Abbreviation 에는 약어 Or 약어의 약어

  를 입력한다.

 

3. File > Save 클릭하면, *.nsm 으로 저장된다.

 

4. ERwin 에서는 낱단어 조합이 가능하다.

    - 예를들어, 부서가 dept이고, 코드가 code라고 정의 돼있으면, 부서코드라는 항목이 없더라도,

     부서와 코드가 조합하여, Column 명이 부서코드가 있으면 낱단어 조합이 되어 Deptcode 라고

     입력된다.

 

5. 낱단어 조합을 원치 않으면, Match whole words only에 체크하며 된다.

    - Export 누르면 엑셀형식인 CSV File인 *.csv 와, *.txt 형태로 export 할 수 있다.

    - import 는 csv 형식이나 txt로 작업한 문서를 nsm으로 import 할 수 있다.

 

 

6. 이렇게 만든 nsm 파일을 Tools > Names > Model Naming Options 에서 적용시켜 줄 수 있다.

 

 

7. General 탭에서 그림과 같이 Use File 로 선택하고, Browse를 클릭 한 다음, 저장 해 놓은 nsm 파일을 불러온다.

 

8. Name Mapping 탭으로 가서 그림과 같이 Use Gloss 부분에 Entity to Table, Attribute to Column에 체크한다.

 

9. 적용 하고 OK 누르면 Physical 영역에는 영문명으로 되어 있는 것을 확인 할 수 있다. 

 


ant : http://ant.apache.org
ant manual : http://ant.apache.org/manual/index.html

scp manual : http://ant.apache.org/manual/Tasks/scp.html
sshexec manual : http://ant.apache.org/manual/Tasks/sshexec.html

* scp library : http://www.jcraft.com/jsch/
    - 2/3 가량 스크롤을 내리다 보면 Download 있음


* 이클립스에서 ant를 동작시킬 경우
  - Windows > Preferences > Ant > Runtime > Classpath > Global Entries 에 scp 사이트에서 다운받은 jar를 추가


* 사용예

 <?xml version="1.0" encoding="UTF-8"?>
<project name="ad_engine" default="all" basedir=".">
 
 <property name="server.host" value="아이피"/>
 <property name="server.port" value="포트"/>
 <property name="server.username" value="사용자아이디"/>
 <property name="server.password" value="사용자비밀번호">
 
 <target name="all" depends="copy,reboot"/>
 
 <target name="copy">
  <echo>copy</echo>
  <scp file="target/ad_engine.jar" todir="${server.username}:${server.password}@${server.host}:/home/obigo/opt/AdEngine/libs" port="${server.port}" trust="true"></scp>
 </target>
 
 <target name="reboot">
  <echo>reboot</echo>
  <sshexec host="${server.host}" port="${server.port}" trust="true" username="${server.username}" password="${server.password}" command="cd opt/AdEngine; bin/stop.sh; bin/boot.sh start" timeout="10000" failonerror="false" />
 </target>
 
</project>


* Jenkins Ant library에 scp 추가
    - jenkins설치폴더/tools/hudson.tasks.Ant_AntInstallation/ant_버전/lib




 

출처 : http://divestudy.tistory.com/17

Eclipse에서 run configuration을 적용하여 프로그램을 실행할 경우 더럽게 귀찮다.


그래서 단축키를 지정해주고 싶었는데 단축키 따윈 없음.


그러다가 찾은 방법임.


엄청 간단함. 은 아니고 생각보단 간단함.


먼저 Help > install new software 선택 후 주소창에 입력 후 work with 에  아래 주소 입력 후 설치

http://puremvcnotificationviewer.googlecode.com/svn/trunk/PracticallyMacroGoogleUpdateSite



설치 완료 되었으면


1. Window > preference 선택 후 "Practically Macro Options"  섹션을 확장하고 Editor Macro Definitor 선택

(귀찮이면 검색창에 "Editor Macro Definitor" 입력)


2. new 버튼 누르고


3. dlg 생기면 오른쪽 리스트에서 Editor Macro script 누르고 가운데 add-> 버튼 누름 그러면 editor 창이 뜸.


4. 기본으로 써있는 텍스트 지우고

 

//Scripts are beanshell format (see http://www.beanshell.org/)
 
//variable               type
//styledText             the org.eclipse.swt.custom.StyledText instance for the current editor
//console                write output to the macro console via console.write(String), .writeln(String), .write(Exception)
//findTarget             the instance of org.eclipse.jface.text.IFindReplaceTarget
import org.eclipse.swt.custom.StyledText;
import org.eclipse.jface.text.IFindReplaceTarget;
 
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.ui.DebugUITools;
    try
    {
      // Terminate process if it already exists from a previous launch
      org.eclipse.debug.core.ILaunch[] allLaunches=DebugPlugin.getDefault().getLaunchManager().getLaunches();
      for (ILaunch l : allLaunches)
      {             
        if (l.getLaunchConfiguration().getName().equals("configuration 이름 입력"))
        {
          console.write("terminating launch: " );
          console.writeln(l.getLaunchConfiguration().getName());
          l.terminate();
          break;
        }
      }
 
        org.eclipse.debug.core.ILaunchConfiguration[] allConfigurations=DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations();
        for (ILaunchConfiguration config : allConfigurations) {
            if (config.getName().equals("configuration 이름 입력"))
            {
                DebugUITools.launch(config, "debug or run");
                break;
            }
        }
    } catch (CoreException e) {
        e.printStackTrace();
    }
    finally{}


 

"20번과 31번째 줄에서 "configuration 이름 입력" 이부분에 configuration 이름을 입력하면 됨. 

33번째 줄의 "Debug or Run" 에는 상황에 맞게 debug 또는 run을 입력하고 OK 버튼을 누르면 됨


5. 아래 Macro info에 이름을 적어주고 (이름은 나중에 확인해야 하므로 가급적 알아보기 쉬운걸로 하는걸 권장)

id 입력 id는 중복만 안되면 되니깐 아무거나 사용하면됨.


6. 다시 한번 OK 버튼을 눌러서 preference 창을 닫는다. 


7. 다시 Window > preference 선택하여 preference 창을 연다.


8. General 섹션의 keys 를 누른다. type filter text에서 key로 검색해도 됨.


9 가운데 command들 중에서 5번에서 적어준 이름을 찾은 후 선택


10. 왼쪽 아래에 Binding 에 원하는 바로가키 키를 누른다. 


11 ok 버튼을 누른다.


그럼 끝!!!!

참고 : http://blog.naver.com/PostView.nhn?blogId=ugigi&logNo=70058661623
         http://blog.naver.com/xxrcn11/20135603375
         http://blog.daum.net/wetet/1813

CryptTest.java

 package iwa.crypt;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;

public class CryptTest {

 public static final int bufSize = 1024;

 // 파일 암호화

 public void encryptFile(String in, String out) throws Exception {
  Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  ObjectInputStream ois = new ObjectInputStream(new FileInputStream("PublicKey.ser"));
  PublicKey publicKey = (PublicKey) ois.readObject();
  ois.close();
  cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  FileInputStream fis = new FileInputStream(in);
  FileOutputStream fos = new FileOutputStream(out);
  CipherOutputStream cos = new CipherOutputStream(fos, cipher);
  byte[] buffer = new byte[bufSize];
  int length;
  while ((length = fis.read(buffer)) != -1)
   cos.write(buffer, 0, length);
  fis.close();
  fos.close();
 }

 // 파일 복호화
 public void decryptFile(String in, String out) throws Exception {
  Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  ObjectInputStream ois = new ObjectInputStream(new FileInputStream("PrivateKey.ser"));
  PrivateKey privateKey = (PrivateKey) ois.readObject();
  ois.close();
  cipher.init(Cipher.DECRYPT_MODE, privateKey);
  FileInputStream fis = new FileInputStream(in);
  FileOutputStream fos = new FileOutputStream(out);
  CipherOutputStream cos = new CipherOutputStream(fos, cipher);
  byte[] buffer = new byte[bufSize];
  int length;
  while ((length = fis.read(buffer)) != -1)
   cos.write(buffer, 0, length);
  fis.close();
  fos.close();
 }

 // 키 생성
 public void genKey() throws Exception {
  KeyPairGenerator key = KeyPairGenerator.getInstance("RSA");
  key.initialize(1024);
  KeyPair kp = key.genKeyPair();
  PrivateKey privateKey = kp.getPrivate();
  PublicKey publicKey = kp.getPublic();
  ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("PrivateKey.ser"));
  out.writeObject(privateKey);
  out.close();
  out = new ObjectOutputStream(new FileOutputStream("PublicKey.ser"));
  out.writeObject(publicKey);
  out.close();
 }

 public static void main(String[] args) {
  CryptTest c = new CryptTest();
  try {
   // 키 생성
   c.genKey();
   // 파일 암호화
   c.encryptFile("a.txt", "b.txt");
   // 파일 복호화
   c.decryptFile("b.txt", "c.txt");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

}


출처 : http://likebnb.tistory.com/97
참고 : http://helloworld.naver.com/helloworld/197937

최근에 자바 애플릿을 만들 일이 있었다.
프로그램을 열심히 작성하고 에러 없이 컴파일까지 완료하였다.
그런데 JAR로 압축하여 웹서버로 배포하여 테스트를 하는데 다음과 같이 에러를 내뿜고 동작하질 않았다.

원인은 아래 그림의 Caused by로 시작되는 줄에 나타난 것 처럼 인증되지 않는 JAR의 실행이 인증예외를 발생시킨 탓이다.
그도 그럴 것이 Java Applet은 로컬 PC로 다운로드 되어 실행되는 것으로 로컬 PC의 자원에 대한 접근이 가능하기 때문에
이를 아무런 제약 없이 실행하게 둘 수 없다는 보안 규칙 때문이다.

java.security.cert.CertificateException: Certificate has been denied at...





 

그렇다면 결론은? 그렇다. 개발된 JAR를 보안 인증서로 서명하여 배포하면 된다.

그래서 오늘 함께 알아 볼 내용은 개발 및 테스트를 위한 과정에서 임시 인증서를 이용하여 테스트를 위한 서명된 JAR를 만들어 보는 
것이다. 이를 위해 JAVA 개발킷에 함께 딸려 온 keytool과 jarsigner라는 유틸리티가 필요하다.



1. 제일 먼저 키저장소를 새로 생성한다.

keytool -genkey -keystore likebnb.keystore -alias likebnb







2. 생성된 키저장소를 자가인증(self certificate)한다.

keytool -selfcert -alias likebnb -keystore likebnb.keystore






3. 인증된 키저장소를 확인한다.

 keytool -list -keystore likebnb.keystore







4. 키저장소를 이용하여 JAR에 서명을 한다.

 jarsigner -keystore likebnb.keystore test.jar likebnb






5. 서명된 JAR와 그렇지 않은 원본 JAR는 다음과 같이 파일의 크기가 다름을 알 수 있다.





이상과 같이 JAR를 인증서로 서명하여 웹에서 사용할 수 있도록 하는 방법을 알아 보았다. 추가로 ant 등을 이용하여 컴파일을 하기
위해서는 아래 구문과 같이 build.xml 파일을 수정해 주어야 한다.

  <target name="signjar">
    <signjar alias="likebnb" jar="build/jars/test.jar"
     keystore="../likebnb.keystore" storepass="my.password" />
    <delete dir="build/classes"/>
  </target>



이상의 방법은 어디까지나 테스트를 목적으로 하는 임시 인증서 및 서명이므로 실제로 배포할 때에는 공인인증기관에서 발급 받은
인증서를 가지고 서명해야 하는 것은 두말할 것 없는 일이다. 어쨌든 개발하고 있는 애플릿을 테스트 해보기 위해선 알아두면 좋겠다.


===============================================================================================================
===============================================================================================================


출처 : http://kdarkdev.tistory.com/238

// http://docs.oracle.com/cd/E19900-01/820-0849/ablra/index.html
// key 생성, 확인, jar파일에 사인하기 예제
// 옵션설명 ->
/*
 - genkey : 키를 생성한다
 - alias : 키저장소 별칭
 - keyalg : 암호화 알고리즘 방식 (아래는 RSA암호화 방식의 공개키쌍 생성)
 - keystore : 키의 저장파일 (해당경로로 key가 생성된다)
 - storetype : 키저장소 방식, 기본으로 제공되는 JKS가 있고 JCEKS라는 저장소도 있다 JCEKS는 3DES방식을 적용하기때문에 좀더 안전하다고 한다.
 - validity : 유효기간. 아래는 100년으로 설정
 - dname : 추가정보 입력
 -
*/
// KEY 생성
keytool -genkey -alias testkeyname -keyalg RSA -keystore d:/signkeystore.ks -storetype JCEKS -validity 36500  -dname "cn=test, ou=test, o=test, c=KR" -keypass 123456 -storepass 123456

//KEY 삭제
keytool -delete  -alias testkeyname -storetype JCEKS -keystore d:/signkeystore.ks -storepass 123456

//KEY List확인
keytool -list -v -keystore d:/signkeystore.ks -storepass 123456 -storetype JCEKS

//JAR sign
jarsigner -keystore d:/signkeystore.ks -storetype JCEKS -storepass 123456 -keypass 123456 d:/applet.jar testkeyname 


===============================================================================================================
===============================================================================================================


출처 : http://mesque.tistory.com/16

http://blog.ejbca.org/2008/02/converting-keystores-between-jks-and.html 

JKS 타입은 안드로이드 마켓등록에 사용 되는 인증서 타입

keytool 의 경로는 일반적으로 C:\Program Files\Java\jdk\bin 이다. 

JKSP12
keytool -importkeystore -srckeystore JKS인증서 -srcstoretype JKS -deststoretype PKCS12
 -destkeystore P12인증서 

P12JKS
keytool -importkeystore -srckeystore P12인증서 -srcstoretype PKCS12 -deststoretype JKS -destkeystore JKS인증서  

JKS인증서 ( ex> D:\keystore, D:\keystore.jks ) 
P12인증서 ( ex> D:\keystore.p12 ) 

p.s : 프로그램 파일에서 destkeystore를 생성할 경우 오류가 발생 할 수 있으므로,

D:\keystore.p12 등으로 출력 경로를 한다


===============================================================================================================
===============================================================================================================

출처 : http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&detail=1&pageno=0&wid=1262&rssMode=1&wtype=0


.keystore 파일에 저장된 개인키 추출방법과 인증기관으로부터 온 공개키를 합친 pfx 파일 만드는 방법

(제목 참 길군요. ^^)

2년 전에 아래와 같은 일이 있었습니다.

JKS(Java Key Store)에 저장된 인증서를 ActiveX 코드 서명에 사용하는 방법
; http://www.sysnet.pe.kr/2/0/882


그런데, 이제 그 인증서가 만료가 되었고 마침 Verisign 측에서의 키관리 정책 변경(2048bit)으로 인해 기존 .key 파일을 사용할 수 없어 사내에서 인증서 담당하시는 분이 새롭게 키를 생성해서 발급을 받았습니다.

문제는, 지난 번과 같이 협업을 하려고 했는데, 해당 방법을 설명한 웹 문서가 없어져 버린 것입니다.

Convert the Java JKS key-store to Microsoft PFX format
; http://www.crionics.com/products/opensource/faq/signFree.htm


그래서, 일단 자바의 ".keystore" 파일을 다음과 같은 이야기와 함께 통째로 저한테 보내주었습니다.

  1. 회사정보를 바탕으로 keystore 파일 생성
  2. keystore 파일로부터 제가 보내드린 csr 생성
  3. verisign으로부터 받은 cer을 keystore 파일에 반영


자... 그럼 위의 이야기를 길게 풀어써보겠습니다.

1번 단계에서 생성된 keystore 안에는 개인키/공개키가 함께 담겨 있습니다. 단지 그 누구도 알아주지 않는 키 정보라는 것만 차이가 있을 뿐 PKI 암호화에는 장애없이 사용할 수 있습니다. 문제는, 제가 배포하는 공개키가 실제로 저한테서 왔다는 것을 다른 사람들이 어떻게 신뢰할 수 있을까 하는 점입니다. 누구나 인증서를 만들때 "회사정보"는 임의로 만들 수 있기 때문에 그 부분은 아무런 의미가 없습니다.

이런 문제를 해결하기 위해 "인증기관"이 있는 것입니다. 우리는 그 인증기관에게 위의 2번 단계를 거쳐서 우리가 가진 "공개키"를 보내게 됩니다. 참고로, 이 과정에서 '개인키'를 보내는 것이 아닙니다. 인증 기관조차도 우리의 개인키가 어떤 건지는 알아선/유출되어선 안됩니다.

마지막으로 3번 단계를 거쳐서 "인증기관"은 자신들의 개인키로 우리의 공개키를 '서명'하고 그 서명된 '공개키 파일' (보통은 Base64 인코딩된 텍스트)을 보내줍니다. Verisign 의 경우 이 파일은 다음과 같은 형식으로 된 텍스트 내용을 메일로 전달해 줍니다.

-----BEGIN CERTIFICATE-----
MIIE4zCCA8ugAwIBAgIQEJ8dqq+4MxWmtkpu7YLYFjANBgkqhkiG9w0BAQUFADCB
...[생략]...
lZ5gwQ3kd61SRXy6I9uXU79fteLDHxNhmqynIKLCh9vg2Rwp9diGLiA0dtEmpJIv
/cX9tj7/6mEVgkha9/KCCcS7Ez7QygYxbepftABY+UtSJF3q+N1Rc8wYlVhw9jiM
c+yBNWmdiQ==
-----END CERTIFICATE-----


즉, 3번 단계의 "받은 cer" 파일이 의미하는 것이 바로 위의 "BEGIN/END CERTIFICATE" 입니다. 이렇게 받은 공개키 인증서 정보를 .keystore 파일에 반영하면 이제서야 제대로 된 개인키/공개키를 가지게 되는 것입니다.

엄밀히, ActiveX 나 Applet 의 경우 '응용 프로그램 서명'작업을 거치는 것은 '공개키'와는 무관합니다. 왜냐하면, '서명'작업은 개인키로 하기 때문입니다. 즉, 굳이 Verisign과 같은 인증기관의 개입없이도 1번 단계에 생성한 개인키만으로도 ActiveX 나 Applet 의 서명이 가능합니다.

"서명되어 생성된 Signature" 는 '공개키'로만 유일하게 검증(Verification)을 거칠 수 있습니다. 그래서 편의상 ActiveX/Applet DLL 파일내에 '공개키'를 'signature'와 함께 포함시켜서 배포를 하는데 이렇게 해서 최종 생성된 파일이야 말로 "서명된 파일"이 되는 것입니다. 인증기관이 필요한 유일한 이유는, 포함된 공개키가 실제 그 '회사 정보로 생성된 공개키'인지를 확인하는 데 필요한 것 뿐입니다.




여기까지 이해를 하셨으면, .keystore 파일에 우리가 원하는 '개인키'가 있음을 알 수 있습니다. 그리고 저한테는 지금 동료 개발자가 보내준 ".keystore" 파일이 있으니 keytool.exe 를 잘 사용하면 문제를 해결할 수 있을 것 같습니다. 검색해 보니 다행히 아래와 같이 답이 나옵니다.

How do I list / export private keys from a keystore?
; http://stackoverflow.com/questions/150167/how-do-i-list-export-private-keys-from-a-keystore


명령어 실행 형식은 다음과 같습니다.

keytool.exe -importkeystore -srcstoretype [Keystore 형식] -srckeystore [Keystore 경로] -deststoretype [개인키 파일 인코딩 형식] -destkeystore [개인키 담을 파일 경로]


인자중에 하나로 쓰이는 "Source Keystore 형식(-srcstoretype)"을 어떻게 알 수 있을까요?

지난 번 글에서 설명한 데로 직접 .keystore 파일에 대고 다음과 같이 -list 명령어를 내려보면 알 수 있습니다.

* .keystore 파일이 D:\settings 폴더에 있는 상황.
* [keystore암호]는 해당 ".keystore" 파일을 생성한 담당자에게 물어보면 알 수 있습니다.

C:\temp>keytool -list -storepass [keystore암호] -keystore d:\settings\.keystore
Keystore 유형: JKS
Keystore 공급자: SUN

Keystore에는 1 항목이 포함되어 있습니다.

jennifersoft, 2012. 3. 7, PrivateKeyEntry,
인증서 지문(MD5): 0F:8D:26:B3:DE:47:63:D2:89:74:63:45:B2:1F:55:54


그럼, 제 경우에 이런 식으로 명령어를 내리면 되겠군요. ^^

C:\temp>keytool.exe -importkeystore -srcstoretype JKS -srckeystore d:\settings\.keystore -deststoretype PKCS12 -destkeystore d:\settings\keys.pk12.der
대상 키 저장소 암호 입력:      <-- 새로 생성되는 keys.pk12.der 파일에 대한 암호 입력
새 암호를 다시 입력하십시오:   <-- 확인
소스 키 저장소 암호 입력:      <-- 이전 .keystore 에 접근하는 암호 입력
별칭 jennifersoft에 대한 항목을 성공적으로 가져왔습니다.
가져오기 명령 완료:  1개 항목을 성공적으로 가져왔습니다. 0개 항목은 실패했거나
취소되었습니다.


이렇게 생성된 der 파일을 openssl.exe 도구를 사용해서 pem 파일로 변경해 줄 수 있습니다. openssl 은 다음의 사이트에서 소스 코드를 구할 수 있지만,

openssl
; http://www.openssl.org/source/


바이너리 배포는 하지 않으므로 빌드된 exe 파일은 다음의 사이트에서 구할 수 있습니다.

Win32 OpenSSL
; http://www.slproweb.com/products/Win32OpenSSL.html

Win32 OpenSSL v1.0.0g Light
; http://www.slproweb.com/download/Win32OpenSSL_Light-1_0_0g.exe


그래서, 이렇게 명령어를 내려주면 pem 파일을 얻을 수 있습니다.

C:\temp>openssl.exe pkcs12 -in c:\temp\keys.pk12.der -nodes -out c:\temp\private.rsa.pem
WARNING: can't open config file: C::\temp\openssl.cfg
Enter Import Password:  <-- keytool.exe 에서 입력했던 "대상 키 저장소 암호"를 입력
MAC verified OK


생성된 private.rsa.pem 파일을 보면 "---BEGIN PRIVATE KEY--- / ---END PRIVATE KEY---" 쌍의 텍스트를 확인할 수 있습니다. 바로 우리가 그토록 원했던 '개인키'가 있다는 것입니다. ^^ 또한 원본이었던 ".keystore" 파일에 자바 개발자가 Verisign 의 서명을 받은 인증서를 반영해 두었기 때문에 pem 파일내에 보면 우리의 공개키 뿐만 아니라 verisign 측의 공개키도 함께 있는 "BEGIN/END CERTIFICATE" 쌍을 볼 수 있습니다.

그런데, 이제부터의 단계가 좀 애매합니다. private/public key를 모두 가지고 있기 때문에 pfx 파일로 바로 변환할 수 있을 것 같은데, 이 방법을 잘 모르겠습니다. 또한 pem 파일은 윈도우 인증서 관리자에서 직접 import 를 지원하지 않습니다. 어떻게 해서든지 pfx 로 변환해야 하는데요. 음... 잘 모르겠습니다. 예전 방법을 써야지. ^^




이전에 해본 대로 pem 파일에서 private 키만을 담은 pvk 파일을 가져올 수 있습니다.

pem-key-file 을 pvk-file 로 변환하는 것은 다음의 pvk.exe 를 사용하시면 됩니다.

PVK file information.
; http://www.drh-consultancy.demon.co.uk/pvk.html

Win32 binary
; http://www.drh-consultancy.demon.co.uk/pvktool.zip

소스 코드
; http://www.drh-consultancy.demon.co.uk/pvksrc.tgz.bin


위의 pvk.exe 를 이용해서 다음과 같이 pem 파일을 pvk 파일로 변환할 수 있습니다.

C:\temp>d:\tools\cert\pvk.exe -in c:\temp\private.rsa.pem -topvk -strong -out c:\temp\private.key
Enter Password:             <-- private.key 파일을 보호할 암호 입력
Verifying - Enter Password: <-- 암호 입력 확인


이렇게 개인키만 소지한 파일을 만들었으니, 이제 verisign의 서명을 받은 우리의 공개키 파일이 필요한데요. 이것 역시 .keystore 에서 구할 수 있습니다. (아니면 아마도 private.rsa.pem 파일에서 얻는 방법도 있을 것입니다.)

하지만 그럴 필요없이, Verisign 측에서 보낸 메일에 보면 "BEGIN CERTIFICATE / END CERTIFICATE" 로 둘러쌓인 텍스트를 그냥 cer 파일로 저장해도 됩니다.

[예제 test.cer]

-----BEGIN CERTIFICATE-----
MIIE4zCCA8ugAwIBAgIQEJ8dqq+4MxWmtkpu7YLYFjANBgkqhkiG9w0BAQUFADCB
...[생략]...
lZ5gwQ3kd61SRXy6I9uXU79fteLDHxNhmqynIKLCh9vg2Rwp9diGLiA0dtEmpJIv
/cX9tj7/6mEVgkha9/KCCcS7Ez7QygYxbepftABY+UtSJF3q+N1Rc8wYlVhw9jiM
c+yBNWmdiQ==
-----END CERTIFICATE-----


이렇게 개인키/공개키를 구했으니 모든 준비작업은 끝났습니다. "인증서 관련(CER, PVK, SPC, PFX) 파일 만드는 방법"에서 설명한 데로 따르면 됩니다. 그리하여 cert2spc 를 이용해서 spc 파일을 만들고,

c:\temp>cert2spc.exe c:\temp\test.cer c:\temp\test.spc
Succeeded


마지막으로 pvkimprt.exe 도구를 이용해서 spc 파일과 key 정보로부터 pfx 파일로 만들 수 있습니다. 그래서, 다음과 같이 명령을 내리면,

c:\temp>pvkimprt.exe -pfx c:\temp\test.spc c:\temp\private.key


암호를 묻는 창이 나옵니다.

jks_to_pfx_1.png

pvk.exe 를 이용하여 private.key 를 만들 때 입력했던 암호를 넣고 계속하면 이어서 본격적인 '인증서 가져오기' 마법사 단계로 넘어갑니다.

jks_to_pfx_2.png

확인을 누르면, 아래 화면 처럼 개인키를 내보낼 수 있는 유형으로 보관할 지 결정합니다. (이것은 회사 정책에 따라 달라질 수 있지만, 여기서는 편의상 "yes"를 선택하겠습니다.) 이에 대한 차이는 "인증서 관리 - 내보내기/가져오기" 글을 참고하세요.

jks_to_pfx_3.png

그 다음은 기본값으로 두고 진행합니다.

jks_to_pfx_4.png

이제 새롭게 생성될 pfx 파일에 '개인키'를 가지게 되므로 이를 보호하기 위해 암호를 다시 입력합니다. (이전과 다른 새로운 암호를 입력해도 됩니다.)

jks_to_pfx_5.png

확인을 누르면 pfx 파일을 저장할 파일명을 지정할 수 있고,

jks_to_pfx_6.png

마지막으로 정보를 확인하고 "Finish" 버튼을 누르면 정상적으로 pfx 파일이 생성됩니다.

휴~~~ 끝입니다. 친근한 pfx 파일이 생성되었으니, 이제 뭐든 ^^ 원하는 데로 작업을 하시면 됩니다.

+ Recent posts