반응형

출처 : http://visualvm.java.net/eclipse-launcher.html


1. 설치방법
   - 위 사이트에서 Visualvm 파일을 다운받아서 이클립스 설치 디렉토리에 압축을 푼다.

2. 환경구성
    - 그림을 보면서 하면됨.


    - JDK 홈 디렉토리의 VisualVM을 사용함(JRE는 아님!, 반드시 JDK가 필요)
    - 위의 경로의 VIsualVM이 실행가능해야 함.

3. 사용법
    - 위의 Application Configuration 설정을 해줌
    - 실행 런처를 VisualVM Launcher로 변경함.
    - VIsualVM 자동 시작되는 구성으로 어플리케이션이 실행과 디버그가 생성된다.

추가로...

Default Launch를 변경하면

모두 모니터링 가능하다..

설정화면 !

참고로 visual VM을 (위의 지정된 경로에있는)

실행하면 바로 모니터링 됨 !

반응형
반응형

소스 혹... 잊어 버릴까봐

첨부함.

반응형

'Language > JSP' 카테고리의 다른 글

로딩된 CLASS 정보 보기  (0) 2011.03.10
JSP WEB shell  (0) 2010.05.10
JSP 파일 읽기  (0) 2009.12.03
웹 상에서 바로 엑셀로 저장하기  (0) 2009.03.06
반응형

## AWR REPORT SETTING ##
1. 특정 기간 동안의 Database level성능 @$ORACLE_HOME/rdbms/admin/awrrpt.sql

2. Database ID와 Instance ID를 지정후 성능 Report 작성 [AWR을 Export/Import 후 다수의 Database에 대한 통계
   자료가 존재시 혹은 RAC 환경 등에서 , Database ID 와 Instance ID 지정이 필요시]
   @ORACLE_HOME/rdbms/admin/awrrpti.sql
   
3. 특정 SQL문에 대한 성능 Report작성 : SQL_ID 값을 입력해야 한다.[1,2에서 주요 Top을 차지하는 SQL문에 대한 특정기간 동안의 Reporting]
   @awrsqrpt.sql
   
4. 특정 SQL문에 대한 성능 Report작성[특정 Database 혹은 Instance에 대해서, : 마찬가지로 SQL_ID 값을 입력해야 한다.]
   @awrsqrpi.sql
    성능 비교 자료
    
5. 두개의 특정 시간 사이의 생성[H/W 변경, Application 변경등 Database 성능에 영향을 줄수 있는 작업 전/후 비교시 사용]
   @awrddrpt.sql
   
6. 두개의 특정 시간 사이의 성능 비교 자료 생성[특정 Database 혹은 Instance 에 대해서]
   @awrddrpi.sql
SQL> select snap_interval, retention from dba_hist_wr_control;

--> SNAP_INTERVAL : 스냅샷 주기 , RETENTION : 보관주기

SQL> BEGIN
       dbms_workloadd_repository.modify_snapshot_settings(interval=>20,retention=>2*24*60);
       
       ----- interval=>20 스냅샷주기를 20분단위로 하겠다.
       ----- 보관주기를 2일로 하겠다.
       );
       END;
SQL> EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS (
     RETENTION => 0,
     INTERVAL => 0,
     DBID => -- SELECT DBID FROM V$DATABASE);
            
SQL> select snap_interval, retention from dba_hist_wr_control;

# SYS 스키마의 SYSAUX 테이블스페이스 내에 저장되어 있으며, WRM$_* 또는 WRH$_* 의 네임 포맷을 갖습니다.
  WRM$_* 테이블은 수집 대상 데이타베이스 및 스냅샵에 관련한 메타데이타 정보를, WRH$_* 테이블은 실제
  수집된 통계 정보를 저장하는데 사용됩니다.(WRH$_*의 H는 "HISTORICAL",WRM$_*의 M은 "METADATA"의 약자를 의미합니다.)
#################################################################################################################
  
## 타임 모델 (Time Model) ##

ORACLE 10G는 여러가지 자원에 관련한 실제 사용 시간을 확인하기 위한 타임 모델(time model)을 구현하고 있습니다. 전체
시스템 관련 소요 시간 통계는 V$SYS_TIME_MODEL 뷰에 저장됩니다. V$SYS_TIME_MODEL 뷰에 대한 쿼리 결과의 예가 아래와 같습니다.

SQL> SELECT STAT_NAME, VALUE FROM V$SYS_TIME_MODEL;

STAT_NAME    VALUE
---------  ---------
DB time    791943871  --> 인스턴스 시작 후 DB 사용 누적치

위에서 DB TIME 이라는 통계정보는 인스턴스 시작 이후 데이타베이스가 사용한 시간의 누적치를 의미합니다.
샘플 작업을 실행한 다음 다시 뷰를 조회했을 때 표시되는 DB TIME 의 값과 이전 값의 차이가 해당 작업을 위해
데이타베이스가 사용한 시간이 됩니다. 
시스템 / 데이타베이스 레벨이 아닌 세션 레벨의 통계를 원한다면 V$SESS_TIME_MODEL 뷰를 이용할 수 있습니다.
V$SESS_TIME_MODEL 뷰는 현재 연결 중인 ACTIVE/INACTIVE 세션들의 통계를 제공합니다.
세션의 SID 값을 지정해서 개별 세션의 통계를 확인할 수 있습니다.
  
또 새롭게 추가된 Active Session History(ASH)는 AWR과 마찬가지로 향후 분석 작업을 위해 세션 성능통계를 버퍼에 저장합니다.
V$ACTIVE_SESSION_HISTORY 등을 통해 조회된다는 사실입니다. 데이타는 1초 단위로 수집되며, 엑티브 세션만이
수집 대상이 됩니다. 버퍼는 순환적인 형태로 관리되며, 저장 메모리 용량이 가득 차는경우 오래된 데이타부터 순서대로 삭제됩니다.
이벤트를 위해 대기 중인 세션의 수가 얼마나 되는지 확인하려면 아래와 같이 조회하면 됩니다.

SQL> SELECT session_id||','||session_serial# SID, n.name, wait_time, time_waited
     FROM v$active_session_history a, v$event_name n
     WHERE n.event# = a.event#;
     
SID             NAME                    WAIT_TIME   TIME_WAITED
------   -----------------             ----------  -------------
166,1    log file parallel write            0           288
166,1    log file parallel write            0           223
161,1    control file sequential read       0         39401
166,1    log file parallel write            0         30367
146,271  null event                         0          2712
167,1    db file parallel write             0           385
  
위 쿼리는 이벤트 별로 대기하는 데 얼마나 많은 시간이 사용되었는지를 알려줍니다. 특정 wait 
이벤트에 대한 드릴다운을 수행할 때에도 ASH 뷰를 이용할 수 있습니다. 예를 들어, 세션 중 하나가
buffer busy wait상태에 있는 경우 정확히 어떤 세그먼트에  wait 이벤트가 발생했는지 확인하는 것이 가능합니다.
이때 ASH 뷰의 CURRENT_OBJ# 컬럼과 DBA_OBJECTS 뷰를 조인하면 문제가 되는 세그먼트를 확인할 수 있다.

ASH 뷰는 그 밖에도 병렬 쿼리 서버 세션에 대한 기록을 저장하고 있으므로, 병렬 쿼리의 WAIT 이벤트를 진단하는 데 유용하게 사용된다.
레코드가 병렬 쿼리의 slave process로서 활용되는 경우, coordinator server sesion 의 SID 는 QCC_SESSION_ID 컬럼으로 확인할 수 있다.
SQL_ID 컬럼은 WAIT 이벤트를 발생시킨 SQL구문의 ID 를 의미하며, 이 컬럼과 V$SQL 뷰를 조인하여 문제를 발생시킨 SQL구문을 찾아낼 수 있다.
CLIENT_ID 컬럼은 웹 어플리케이션과 같은 공유 사용자 환경에서 클라이언트를 확인하는 데 유용하며, 이값은 DBMS_SESSION.SET_INDENTIFIER를 
통해 설정이 가능하다.

## SNAPSHOT 찍기 ##
SQL> SELECT SYSDATE FROM DUAL;
SQL> SELECT SNAP_ID, BEGIN_INTERVAL_TIME BEGIN, END_INTERVAL_TIME END FROM SYS.DBA_HIST_SNAPSHOT; --> 스냅샵 아이디를 본다.
SQL> EXECUTE DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT; --> 수동으로 스냅샷을 찍는다.
SQL> SELECT SNAP_ID, BEGIN_INTERVAL_TIME BEGIN, END_INTERVAL_TIME END FROM SYS.DBA_HIST_SNAPSHOT; --> 스냅샵 아이디를 본다.
SQL> EXEC DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE(10,15): --> SNAPSHOT ID를 범위로 지정해서 삭제한다.
SQL> SELECT SNAP_ID, STARTUP_TIME FROM DBA_HIST_SNAPSHOT ORDER BY 1,2; --> 정렬해서 스냅샵 아이디를 본다.


## SNAPSHOT을 ID를 묶어서 이름을 지정한다. ##
SQL> SELECT DBID, BASELINE_ID, BASELINE_NAME, START_SNAP_ID, END_SNAP_ID FROM DBA_HIST_BASELINE;
SQL> EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_BASELINE(17,20,'TEST_BASE_1');
SQL> SELECT DBID, BASELINE_ID, BASELINE_NAME, START_SNAP_ID, END_SNAP_ID FROM DBA_HIST_BASELINE;
SQL> EXEC DBMS_WORKLOAD_REPOSITORY.DROP_BASELINE('TEST_BASE_1');

 

### SQL QUERY ADVISOR ###
SQL> CONN sys/<password> AS SYSDBA
SQL> GRANT ADVISOR TO scott; ?? scott 유저에게 advisor 권한 부여
SQL> CONN scott/tiger
SQL> SELECT ename from emp e
WHERE job = 'SALESMAN'
AND comm not in (SELECT comm FROM emp
WHERE ename=e.ename AND comm is not null); ?? 문제의 쿼리
선택된 레코드가 없습니다.

SQL> DECLARE
2 l_task_id varchar2(30);
3 l_sql varchar2(2000);
4 BEGIN
5 l_sql := 'select ename from emp e where job = :job and comm not in
6 (select comm from emp where ename=e.ename and comm is not null)';
7 l_task_id := dbms_sqltune.create_tuning_task ( ?? dbms_sqltune 패키지를 사용.
8 sql_text => l_sql,
9 user_name => 'SCOTT', ?? [주의] 유저명은 대문자로 해야함.
10 scope => 'COMPREHENSIVE',
11 time_limit => 120,
12 task_name => 'sql_advisor_test14' ?? 테스크 이름
13 );
14 dbms_sqltune.execute_tuning_task ('sql_advisor_test14'); ?? 튜닝 테스크 실행
15 END;
16 /
PL/SQL 처리가 정상적으로 완료되었습니다.

SQL> set serveroutput on size 999999
SQL> set long 999999
SQL> select dbms_sqltune.report_tuning_task ('sql_advisor_test14') from dual; ?? 생성된 테스크 보고서 보기

 

http://cafe.naver.com/prodba

 출처 : 

반응형
반응형


원문 : http://blog.pages.kr/518

/etc/shadow

username:passwd:lastchg:min:max:warn:inactive:expire

1) username : 2자에서 8자의 문자로 구성되며 숫자와 조합할 수 있다. 주의 할것은 username에는 underline 과 space 문자는 사용될 수 없다.
2) passwd :  암호는 암호화 되어 들어간다.
3) lastchg : 1970년 1월 1일 부터 마지막으로 암호를 수정한 날짜까지의 날수
4) min : 암호의 수정을 해야 하는 가장 적은 날 수 범위
5) max : 암호의 수정을 해야 하는 가장 많은 날 수 범위
6) warm : 암호를 바꿔야 한다는 경고 메시지를 몇일 전에 user에게 알려 주는 날수의 범위
7) inactive : 사용자 계정이 닫히기 전 활성화 할 수 있는 날 수 
8) expire : 사용자 계정이 만료될 때까지의 정확한 날짜 수


여기서 max와 wam 필드에 알맞은 수를 넣으면..
ex)  user1:password:11254:1:2:1:::
이러면 암호는 1일 전에 바꿀 수 없으며 반듯이 2일 전에는 바꿔야 한다는 뜻이고 1일 전부터 2일 까지 경고 메시지를 user에게 보내주라는 뜻입니다.
메시지에 대한 내용은
- 로그인을 하면 
     Your password will expore in 2 days"
- 패스워드를 1일 전에 바꾸려고 하면
     "Passwd(SYSTEM):Sorry:less than 1 day since the last change (권한이 거부됨)
- 2일이 지나서 로그인을 하면
     "Choose a new password"
     "Enterlogin password"
     "new password"


- 존더리퍼 - 

존더리퍼는 Solar Designer가 개발한 Unix 계열 password crack tool 이다..
무료 도구이며, UNIX 계열 크래킹 도구 이지만 DOS, Win9x,nt 200 등의 플랫폼도 지원한다.

속도를 높이기 위해 Intel MMX 기술이나 AMD K6 프로세서의 특수기능들을 이용한 최적화된 코드를 집어 넣기도 하였다.

http://www.openwall.com/john/ 에서 개발버전, 안정버전 , linux용 windows 용 등을 다운 받을 수 있다고한다.


2. 패스워드 파일

존더리퍼를 이용하려면 리눅스의 /etc/shadow 와 같은 패스워드 파일이 있어야 한다. 
/etc/shadow 파일의 일부를 보면 다음과 같이 생겼음을 알 수 있다.

level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524
(해커스쿨 레벨8의 레벨9의 패스워드)

콜론(:)으로 각 필드를 구별해주며 색칠된 부분이 레벨9의 패스워드가 암호화된 부분이다.
바로 이부분을 존더리퍼가 해독하여 패스워드를 보여주는것이다.

3. 크래킹 과정( win 용)

리눅스에서 얻어낸 shadow 파일을 윈도우즈로 복사해 존더 리퍼의 압축을 해제한 폴더 안의 run에 넣는다.
command창을 실행 시킨 후 shadow 파일을 윈도우즈로 복사해 존더리퍼의 압축을 해제한 폴더 안의 run 폴 
 더에 넣는다. 

ex)
c:\jojn1701\run> john-mmx pass.txt
c:\jojn1701\run> john-mmx -showpass.txt

-------------------------------------------------------------------------------------------

 출처 : http://tmdgus.tistory.com/143

 

 

-------------------------------------------------------------------------------------------

아주아주 유명한 Password Crack Tool을 소개하겠다.

 

바로 "존 더 리퍼(John the Ripper  Copyright (c) 1996-98 by Solar Designer)" 다.

 

존 더 리퍼는 Unix 계열의 시스템에서 사용자 계정의 Password를 암호화하여 저장한 "Shadow" 파일을 크랙하는데 주로 이용되었는데, 요즘에는 Windows 계열의 사용자 계정 Password를 크랙 하는데도 이용한다.

 

Unix 계열 시스템의 shadow 파일을 살짝 들여다 보면 아래와 같은 문자들이 나열되어 있다.

 


root:EMrs1Kz5cQ0/A:12405::::::
daemon:NP:6445::::::
listen:*LK*:::::::
nobody:NP:6445::::::
noaccess:NP:6445::::::
nobody4:NP:6445::::::
YeChan:6J8Cp/wjud.Ws:12405::::::
webservd:*LK*:::::::
ywson:*LK*:::::::
iscan:*LK*:::::::
weblogic:V0.N.LSc7E1B6:12611::::::


 

각 필드의 구분은 콜론(:)으로 되어 있고 계정이름, UID, PID, Password, Home Directory 등등.. 맨 앞의 영문이 계정이름(ID)이고 바로 다음에 나오는 요상한 문자열이 암호화된 Password 다. John은 바로 이 암호화된 스트링(문자열)을 해독하여 Password가 무엇인지를 보여준다.

 

Unix에서는 Shadow 파일을 이용하기 때문에 그냥 john 명령어만 사용하면 끝이다. 그런데 윈도우시스템은 조금 다르다. Shadow 파일같은 그런게 없다.

 

Windows 시스템은 PWDump 라는 프로그램을 이용하여 Unix의 Shadow 파일과 같은 형식으로 만들어줘야 한다.

 

사용법은 아주 간단하다.

 


C:\>pwdump3  211.xxx.xxx.xxx


 

이게 끝이다. 그러면 위의 그림과 같은 메시지가 뜨면서 Unix의 Shadow 파일 형식으로 가져온다.

 

명령어 끝에 리다이렉션 ">" 을 사용하여 원하는 파일명으로 만들어주면 훨씬 편하겠다.

 


C:\>pwdump3  211.xxx.xxx.xxx  >  PWD.txt


 

PWDump 프로그램을 이용하여 만든 파일을 열어보면 아래와 같은 문자열이 보인다.

 


GuaRDiaN:500:NO PASSWORD*********************:F1E37A8123F967125C3A8CE7E382AC0E:::
Guest:501:NO PASSWORD*********************:NO PASSWORD*********************:::
TEST:1006:B757BF5C0D87772FAAD3B435B51404EE:7CE21F17C0AEE7FB9CEBA532D0546AD6:::


 

자세히 보면 Unix의 Shadow 파일과 같은 형식이다. 콜론(:)으로 구분되어 있다.

역시 맨 앞이 계정이름(ID)이고 그다음이 UID, 그리고 암호화된 Password 이다.

 

그런데 암호화된 Password가 상당히 길다. 앞에 32자, 뒤에 32자로 총 64글자로 되어 있다.

 


TEST:1006:B757BF5C0D87772FAAD3B435B51404EE:7CE21F17C0AEE7FB9CEBA532D0546AD6:::


 

Unix는 8글자의 계정암호를 기본으로 제공하고, Windows 는 14글자의 계정암호를 제공한다.

(그런데 테스트를 해 본 결과, Windows에서는 암호 길이가 제한되어 있지 않았다!! 필자는 96글자의 암호를 사용했었다-_-; 아마도 암호화할 수 있는 길이가 14글자인가 보다..음)

 

아무튼 그건 그렇고. 여기서 주목해야 할것이 두가지가 있다.

 

먼저, 위의 암호화된 문자열을 보자. 콜론으로 구분해서 두 그룹이 있는데 그중에 앞의 그룹을 잘보면, 17번째 ~ 32번째 문자가 AAD3B435B51404EE 이렇게 되어 있다.

 

만일 이렇게 17번째 ~ 32번째 문자가 위와 같이 나와있다면, 그 계정의 암호길이는 8글자 이하라는 뜻이다!!

 

또한 "NO PASSWORD" 는 물론 암호가 없다는 뜻이다. 그런데 잼있는것이 있다.

 

위의 계정들은 필자가 사용하는 컴퓨터의 계정들인데 GuaRDiaN 계정이 바로 최고관리자 계정, 즉 필자가 사용하는 계정이고 암호가 분명히 설정되어 있다! 그런데도 NO PASSWORD 라고 찍혀있다. 어찌된 걸까?

 

Windows 는 최대 14글자의 계정암호를 제공한다고 말했었다. 그러나 14글자가 넘어 버리면, 위와 같이 NO PASSWORD 라고 나온다. 때문에 John The Ripper는 아에 크랙을 시도하지도 않고 그냥 넘겨버린다. 보안상 아주 좋다. ㅎ.

 

암호는 양쪽 필드에 전부 NO PASSWORD 라고 되어 있어야만 실제로 암호가 없는 것이다.

 

이제 John The Ripper 를 돌려서 암호를 알아내보자.

 

역시 명령어도 아주 쉽다.

 


C:\>john  PWD.txt


 

뒤의 파일은 Unix의 Shadow 파일이나 Windows의 PWDump 파일을 입력하면 된다.

위의 명령어를 입력하면 그림처럼 아무것도 보이지는 않는다. 만일 암호 크랙이 어디까지 진행되는지 보고 싶다면 아무 키나 누르면 된다.

 

 

키를 누를때 마다 위의 메시지를 뿌려준다. trying: 이라는 부분이 문자열을 어디까지 조합하고 있는지 알려주는 부분이다.

 


C:\>john  -show  PWD.txt


 

-show 옵션은 현재까지 크랙된 Password를 보여주는 옵션이다. 역시 리다이렉션을 이용하여 파일로 저장하면 되겠다.

 


C:\>john  -show  PWD.txt  >  PWD_Crack.txt


 

 

위는 -show 옵션으로 크랙 결과를 본 것이다.

 

TEST 계정의 암호가 1234 라고 알려주고 있다. 뒤의 1006 은 위에서 말한 UID 이다. 헷갈리지 말자.

Guardian 계정은 NO PASSWORD라고 되어 있어서 아에 크랙을 시도하지도 않았다. Guardian 계정의 암호는 21글자이다.

 

 

암호가 길면 길수록, 특수문자 및 숫자 조합이 많으면 많을 수록 john The Ripper의 크랙 시간은 오래 걸린다. 그러나 언젠가는 크랙되기 때문에 안심할 수가 없다.

 

단 몇가지의 설정으로 크랙을 예방할 수 있다. Windows 에서는 특수문자를 반드시 포함시키고 15글자 이상의 암호를 사용하자. 자신이 좋아하는 노래가사의 일부분이나, 시 어구 등의 외우기 쉬운 문장을 암호로 사용하면 아주 좋다. 그리고 Windows 에서 PWDump 가 성공하려면 ADMIN$가 공유되어 있어야 하기 때문에 이 ADMIN$ 공유를 삭제해 주면 안전해진다. (공유 삭제 방법은 [Windows] - 폴더 공유 보안 설정 ① 을 참고하자.)

 

Unix에서는 Shadow 파일의 권한을 400 으로 하면 되겠다.

 

-------------------------------------------------------------------------------------------


출처 : http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=10302&docId=68400630&qb=66as64iF7IqkIHNoYWRvdw==&enc=utf8&section=kin&rank=1&search_sort=0&spq=0&pid=gmRkxz331xosssl1zRsssv--232164&sid=ThUR3ffpFE4AADJ-JLk

 /etc/shadow와 존더리퍼(John the Ripper)|작성자 길땡

반응형

'Private' 카테고리의 다른 글

2012 피셔 프라이스 뉴 러닝홈  (0) 2011.11.16
OPENSSL 패스워드 변경  (0) 2011.10.20
ssl crack  (0) 2011.09.27
Aircrack-ng is an 802.11 WEP and WPA/WPA2-PSK key cracking program.  (1) 2011.09.09
퇴직 연금  (0) 2011.01.11
반응형
ssl 암호 걸린것 크랙 시키기...

openssl 을 통한 복호화...

crt는 pem 파일을 확장자만 바꾼것임...

openssl enc -d -des3 -in test.crt -out test.txt

뭐.. 암호를 알면 바로 테스트가 가능하겠지만...

bad...

쩝...

출처 : http://neophob.com/2007/10/ssh-private-key-cracker/

크랙커... ssl cracker

너무 많이 알려주면 보안 취약 -_-ㅋ





john-mmx 관련
출처 : http://www.openwall.com/john/


반응형

'Private' 카테고리의 다른 글

OPENSSL 패스워드 변경  (0) 2011.10.20
존 더 리퍼 john-mmx  (1) 2011.09.28
Aircrack-ng is an 802.11 WEP and WPA/WPA2-PSK key cracking program.  (1) 2011.09.09
퇴직 연금  (0) 2011.01.11
산모가 자신의 태반 먹는다?  (0) 2010.02.27
반응형


!! 바이러스 백신들은 모두 종료한후 설치해야 함 !

데몬 로딩 -> setup 더블 클릭 -> install 클릭 -> i accept 체크 및  next 클릭 -> next 클릭 ->
finish 클릭 -> 할리온 vst 인스톨 -> i accept 체크 및 next 클릭 -> next ->  install 클릭 ->
finish 클릭 -> install 창이 나오면 install 클릭 -> finish 클릭 ->
install 나오면 같은방법으노 클릭 -> finish 클릭 -> cubase update 화면 -> update 클릭 ->
ok 클릭 -> 동글이 설치 화면 next 클릭 -> install  클릭  설치 -> finish 클릭 ->
검은 화면 뜰때 아무키나 누름 -> 인증 -> 큐베이스 첫화면에서 cancel 클릭 ->
레지스트리 창 뜸 -> Already registred 클릭
 -> 즐겁게 큐베이스 함 ^_^

반응형

'UTILITY' 카테고리의 다른 글

IBM 자바 다운로드 주소  (0) 2011.12.05
FogBugZ  (0) 2011.11.17
handone new 핸드온 새로운 ..  (0) 2011.08.19
ERD 관련 프로그램 들...  (0) 2011.08.19
registry first aid platinum v 8.1  (1) 2011.08.08
반응형
반응형

'Private' 카테고리의 다른 글

OPENSSL 패스워드 변경  (0) 2011.10.20
존 더 리퍼 john-mmx  (1) 2011.09.28
ssl crack  (0) 2011.09.27
퇴직 연금  (0) 2011.01.11
산모가 자신의 태반 먹는다?  (0) 2010.02.27
반응형
반응형

'유용한 링크 모음' 카테고리의 다른 글

무료 QR 코드 생성 사이트  (0) 2020.02.07
해킹 관련 랭킹 사이트  (0) 2011.08.23
할인 쿠폰 사이트  (0) 2010.08.27
드로잉 사이트  (0) 2010.02.08
반응형

 

출처 : http://blog.kangwoo.kr/49

인터넷 뱅킹을 하시는 분이라면 대부분 공인인증서를 가지고 있다. 이 공인인증서를 가지고 전자서명을 해보도록하자(전혀 쓸데없는 일이긴 하다 ^^;)
필자의 경우 yessign에서 발급한 은행용 공인인증서를 가지고 있는데 그 경로는 C:\NPKI\yessign\USER\아래폴더... 에 위치해 있다.
그 디렉토리에 보면 CaPubs, signCert.der, signPri.key 세 파일이 존재한다.
CaPubs은 무슨 파일인지 잘 모르겠다. signCert.der는 공인 인증서 파일이고, signPri.key는 개인키 파일이다.
(der은 인증서 저장시 바이너르 형태로 저장하기 위한 포맷이고, pem은 문자열로 표현가능한 데이터로 인코딩(BASE64같은..)한 포맷이다.)
한국정보보호진흥원(http://www.rootca.or.kr/kcac.html)의 기술규격을 참조해보면, 현재 사용하는 공인인증서는 RFC3280을 준수하여, 전자서명인증체계에서 사용하는 정수2를 갖는 X.509 v3을 사용하고 있다고 한다.

1. 공개키 가져오기.
- 자바에서 X.590를 지원해주니 간단히 사용해보자.

01 package test.security;
02
03 import java.io.File;
04 import java.io.FileInputStream;
05 import java.io.IOException;
06 import java.security.cert.CertificateFactory;
07 import java.security.cert.X509Certificate;
08
09 public class CertificateTest1 {
10
11 public static void main(String[] args) throws Exception {
12 X509Certificate cert = null;
13 FileInputStream fis = null;
14 try {
15 fis = new FileInputStream(new File("C:/signCert.der"));
16 CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
17 cert = (X509Certificate) certificateFactory.generateCertificate(fis);
18 } finally {
19 if (fis != null) try {fis.close();} catch(IOException ie) {}
20 }
21 System.out.println(cert);
22 System.out.println("-----------------");
23 System.out.println(cert.getPublicKey());
24 }
25 }

실행해보면 아래처럼 인증서에 대한 정보를 볼 수 있을것이다.(보안 관계상 많은 부분을 생략하겠다.)

[
[
Version: V3
Subject: CN=누굴까(RangWoo)0000000000000000, OU=XXX, OU=personalXXX, O=yessign, C=kr
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

Key: Sun RSA public key, 1024 bits
... 생략 ...
[7]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[accessMethod: 1.3.6.1.5.5.7.48.1
accessLocation: URIName: http://ocsp.yessign.org:4612]
]
... 생략 ...
Sun RSA public key, 1024 bits
modulus: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
public exponent: 00000

당연히, V3 버젼을 사용하고 서명 알고리즘은 SHA1withRSA을 사용한다. SHA1withRSA 옆에 보면 OID란 놈이 있다.
OID란 Object IDentifier의 약어로서 객체식별체계정도로 이해하면 되겠다. 즉, OID의 값이 1.2.840.113549.1.1.5이면 SHA1withRSA란 의미이다.
http://www.oid-info.com/ 사이트에 가서 1.2.840.113549.1.1.5 값을 입력하면 아래와 같은 값을 얻을 수 있다.

그리고 중간쯤에 ocsp(Online Certificate Status Protocol)라고 실시간으로 인증서 유효성 검증을 할수 있는 정보도 나온다.
좀더 내려가보면 공개키부분이 나오는데, 이놈이 우리가 사용할 부분이다. cert.getPublicKey() 메소드를 이용하면 직접 공개키를 가져올 수 있다.

2. 개인키 가져오기
- 공개키는 거의 날로 먹었는데, 개인키란 놈은 만만하지가 않다.
- 기본적으로(?)는 PKCS#8를 이용해서 개인키를 저장하는데, 국내 공인인증서에 사용하는 개인키 파일는 암호화(?)해서 저장한다.
PKCS#5(Password-Based Cryptography Standard)의 PBKDF1(Password-Based Key Derivation Function), PBES1(Password-Based Encryption Scheme)를 이용한다는 것이다.
여기까지는 별 문제가 없는데, 데이터 암호화를 할때 국내에서만 사용하는 SEED란 블럭암호화 알고리즘를 사용한다는것이다.
즉, 기본적으로 제공이 안되므로 직접 구현을 해야한다.
뭔소리인지 이해가 안가면 한국정보보호진흥원(http://www.rootca.or.kr/)의 암호 알고리즘 규격(KCAC.TS.ENC)를 한번 읽어보자. (사실 읽어봐도 이해가 안가지만... ^^;)
간단히 설명을 하자면, PBES(Password-Based Encryption Scheme) 즉 패스워드 기반의 키 암호화 기법을 사용하겠다는 것이다. 암호화 할때 필요한게 비밀키이다. 이 키는 해당 알고리즘에 맞는 바이트 배열로 보통 사용을 하는데, 이것을 사람이 쉽게 인식할 수 있는 패스워드로 사용하겠다는것이다.
뭐 필자처럼 무식하게 "hello123".getBytes(); 를 사용해서 키로 사용할 수 있지만, 모양새가 안좋아보인다는것이다. 그래서 "hello123" 문자열을 가공해서 멋진(?) 키로 만들어 사용한다는 것이다.
이 가공하는 함수가 PBKDF(Password-Based Key Derivation Function)이다. 그리고 이 함수를 이용해서 비밀키를 생성해서 암호화/복화하는 하는 구조를 PBES라고 한다.
자바에서 기본적으로 "PBEWithMD5AndDES", "PBEWithSHA1AndDESede" 등의 알고리즘을 제공해준다.
Security.getProviders(); 메소드를 이용해서, Provider 정보를 출력해보면 지원하는 알고리즘을 알 수 있다.
01 package test.security;
02
03 import java.security.Provider;
04 import java.security.Security;
05
06 public class ProviderInfo {
07
08 public static void main(String[] args) {
09 Provider[] providers = Security.getProviders();
10 for (int i = 0; i < providers.length; i++) {
11 String name = providers[i].getName();
12 String info = providers[i].getInfo();
13 double version = providers[i].getVersion();
14 System.out.println("--------------------------------------------------");
15 System.out.println("name: " + name);
16 System.out.println("info: " + info);
17 System.out.println("version: " + version);
18
19 for (Object key : providers[i].keySet()) {
20 System.out.println(key + "\t"+ providers[i].getProperty((String)key));
21 }
22 }
23 }
24 }

그런데 불행히도 "PBEWithSHA1AndSeed"같은 알고리즘은 없는거 같다. 어떻게 해야할까? 당연히 삽~을 들어야한다.(아~~ 또 무덤을 파는구나 ㅠㅠ)
일단 파일의 구조를 파악해서 필요한 정보를 읽어와야한다.(ASN. 1으로 인코딩되어있다.)
다행히도 PKCS#8로 정의하고 있는 구조를 읽을 수 있는 EncryptedPrivateKeyInfo 클래스가 존재해서 한결 쉽게 작업을 할 수 있다
EncryptedPrivateKeyInfo 클래스를 사용해서 정보를 읽어오자. 사용하는 알고리즘을 출력해 보자.
01 // 1. 개인키 파일 읽어오기
02 byte[] encodedKey = null;
03 FileInputStream fis = null;
04 ByteArrayOutputStream bos = null;
05 try {
06 fis = new FileInputStream(new File("C:/signPri.key"));
07 bos = new ByteArrayOutputStream();
08 byte[] buffer = new byte[1024];
09 int read = -1;
10 while ((read = fis.read(buffer)) != -1) {
11 bos.write(buffer, 0, read);
12 }
13 encodedKey = bos.toByteArray();
14 } finally {
15 if (bos != null) try {bos.close();} catch(IOException ie) {}
16 if (fis != null) try {fis.close();} catch(IOException ie) {}
17 }
18
19 System.out.println("EncodedKey : " + ByteUtils.toHexString(encodedKey));
20
21 // 2. 개인카 파일 분석하기
22 EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(encodedKey);
23 System.out.println(encryptedPrivateKeyInfo);
24 System.out.println(encryptedPrivateKeyInfo.getAlgName());

필자의 경우 "1.2.410.200004.1.15"란 값을 얻을 수 있었다. 나머지 파라메터 정보는 불행히도 제공을 안해줘서 직접 처리해야한다.
"1.2.410.200004.1.15" 어디서 많이 본 형식이다. 그렇다. OID이다. 사이트(http://www.oid-info.com/)가서 조회를 해보자.
"Key Generation with SHA1 and Encryption with SEED CBC mode" 란다.

한국정보보호진흥원(http://www.rootca.or.kr/)의 암호 알고리즘 규격(KCAC.TS.ENC)에서도 해당 OID에 대한 정보를 알 수 있다.

즉, 두 번째 방법이라는 것인데, DK의 값을 이용해서 해쉬값을 만든다음 그 값을 IV(초기화 벡터)로 사용하라는 것이다.
여기서 DK란 PBKDF를 사용해서 만든 추출키를 의미한다. 그렇다면 먼저 추출키를 만들어보자.

위의 설명대로 해당 함수를 구현해보자.
salt와 iteration count가 필요하다.
salt는 공인인증서를 발급할때마다 랜덤하게 생성되는것으로, 블특정다수의 사전(Dictionary) 공격을 방지하는 역할을 한다.(21-28바이트 사이의 8바이트를 사용함)
iteration count는 비밀키 생성을 위해 해쉬함수를 몇번 반복할 것인가를 나타낸다. (31-32바이트 사이의 2바이트를 사용함)
1 byte[] salt = new byte[8];
2 System.arraycopy(encodedKey, 20, salt, 0, 8);
3 System.out.println("salt : " + ByteUtils.toHexString(salt));
4 byte[] cBytes = new byte[4];
5 System.arraycopy(encodedKey, 30, cBytes, 2, 2);
6 int iterationCount = ByteUtils.toInt(cBytes);
7 System.out.println("iterationCount : " + ByteUtils.toHexString(cBytes));
8 System.out.println("iterationCount : " + iterationCount);

그럼 PBKDF1을 구현해보자. RFC2898(http://www.ietf.org/rfc/rfc2898.txt)을 보면 아래처럼 설명이 나와있다.
5.1 PBKDF1

   PBKDF1 applies a hash function, which shall be MD2 [6], MD5 [19] or
   SHA-1 [18], to derive keys. The length of the derived key is bounded
   by the length of the hash function output, which is 16 octets for MD2
   and MD5 and 20 octets for SHA-1. PBKDF1 is compatible with the key
   derivation process in PKCS #5 v1.5.

   PBKDF1 is recommended only for compatibility with existing
   applications since the keys it produces may not be large enough for
   some applications.

   PBKDF1 (P, S, c, dkLen)

   Options:        Hash       underlying hash function

   Input:          P          password, an octet string
                   S          salt, an eight-octet string
                   c          iteration count, a positive integer
                   dkLen      intended length in octets of derived key,
                              a positive integer, at most 16 for MD2 or
                              MD5 and 20 for SHA-1

   Output:         DK         derived key, a dkLen-octet string

   Steps:

      1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output
         "derived key too long" and stop.

      2. Apply the underlying hash function Hash for c iterations to the
         concatenation of the password P and the salt S, then extract
         the first dkLen octets to produce a derived key DK:

                   T_1 = Hash (P || S) ,
                   T_2 = Hash (T_1) ,
                   ...
                   T_c = Hash (T_{c-1}) ,
                   DK = Tc<0..dkLen-1>

      3. Output the derived key DK.
설명대로 구현해주자. 피곤한 관계상 SHA1을 사용해서 20바이트의 추출키만을 반환하도록 만들었다.
01 public static byte[] pbkdf1(String password, byte[] salt, int iterationCount) throws NoSuchAlgorithmException {
02 byte[] dk = new byte[20];
03 MessageDigest md = MessageDigest.getInstance("SHA1");
04 md.update(password.getBytes());
05 md.update(salt);
06 dk = md.digest();
07 for (int i = 1; i < iterationCount; i++) {
08 dk = md.digest(dk);
09 }
10 return dk;
11 }
12 }

해당 함수를 사용해서 추출키(DK) 초기화 벡터(IV)를 만들어 보자.
01 String password = "password";
02
03 // 추출키(DK) 생성
04 byte[] dk = pbkdf1(password, salt, iterationCount);
05 System.out.println("dk : " + ByteUtils.toHexString(dk));
06
07 // 생성된 추출키(DK)에서 처음 16바이트를 암호화 키(K)로 정의한다.
08 byte[] keyData = new byte[16];
09 System.arraycopy(dk, 0, keyData, 0, 16);
10
11 // 추출키(DK)에서 암호화 키(K)를 제외한 나머지 4바이트를 SHA-1
12 // 으로 해쉬하여 20바이트의 값(DIV)을 생성하고, 그 중 처음 16바이트를 초기
13 // 벡터(IV)로 정의한다.
14 byte[] div = new byte[20];
15 byte[] tmp4Bytes = new byte[4];
16 System.arraycopy(dk, 16, tmp4Bytes, 0, 4);
17 div = SHA1Utils.getHash(tmp4Bytes);
18 System.out.println("div : " + ByteUtils.toHexString(div));
19 byte[] iv = new byte[16];
20 System.arraycopy(div, 0, iv, 0, 16);
21 System.out.println("iv : " + ByteUtils.toHexString(iv));

당연히 password 변수에는 공인인증서 암호를 입력해야한다. 안그러면 에러가 난다.
이제 고지가 눈앞에 보인다. 남은것은 SEED를 이용해서 복화만 하면 되는것이다. SEED 구현 + CBC 운용모드 구현을 직접하려면 정신적인 데미지가 커질 수 있으므로, 만들어놓은것을 가져다 쓰겠다.
Bouncy Castle Crypto APIs(http://www.bouncycastle.org/)를 감사하는 마음으로 가져다 쓰자.
%JAVA_HOME%/jre/lib/ext에 해당 jar파일을 복사한 다음, %JAVA_HOME%/jre/lib/security/java.security 파일에
security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider
을 추가해서 사용할 수 있지만, 귀찮은 관계로 그냥(?) 사용하겠다.
1 // 3. SEED로 복호화하기
2 BouncyCastleProvider provider = new BouncyCastleProvider();
3 Cipher cipher = Cipher.getInstance("SEED/CBC/PKCS5Padding", provider);
4 Key key = new SecretKeySpec(keyData, "SEED");
5 cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
6 byte[] output = cipher.doFinal(encryptedPrivateKeyInfo.getEncryptedData());

이젠 해당 데이터로 개인키를 생성만 해주면 된다.
1 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(output);
2 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
3 RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)keyFactory.generatePrivate(keySpec);
4 System.out.println(privateKey);
패스워드를 일치여부는 PBES에서 정의한 패딩이 존재하는지 여부로 판단한다. 만약 잘못된 패스워드라면
Exception in thread "main" javax.crypto.BadPaddingException: pad block corrupted
같은 에러가 발생할것이다.


그럼 마지막으로 공인인증서의 공개키와 개인키를 가지고 어제 해본 전자서명을 한번 해보자.
001 package test.security;
002
003 import java.io.ByteArrayOutputStream;
004 import java.io.File;
005 import java.io.FileInputStream;
006 import java.io.IOException;
007 import java.security.Key;
008 import java.security.KeyFactory;
009 import java.security.MessageDigest;
010 import java.security.NoSuchAlgorithmException;
011 import java.security.PrivateKey;
012 import java.security.PublicKey;
013 import java.security.Signature;
014 import java.security.cert.CertificateFactory;
015 import java.security.cert.X509Certificate;
016 import java.security.interfaces.RSAPrivateCrtKey;
017 import java.security.spec.PKCS8EncodedKeySpec;
018
019 import javax.crypto.Cipher;
020 import javax.crypto.EncryptedPrivateKeyInfo;
021 import javax.crypto.spec.IvParameterSpec;
022 import javax.crypto.spec.SecretKeySpec;
023
024 import kr.kangwoo.util.ByteUtils;
025
026 import org.bouncycastle.jce.provider.BouncyCastleProvider;
027
028 import com.jarusoft.util.security.SHA1Utils;
029
030 public class CertificateTest {
031
032 public static void main(String[] args) throws Exception {
033 String msg = "하늘에는 달이 없고, 땅에는 바람이 없습니다.\n사람들은 소리가 없고, 나는 마음이 없습니다.\n\n우주는 죽음인가요.\n인생은 잠인가요.";
034 PublicKey publicKey = getPublicKey("C:/signCert.der");
035 PrivateKey privateKey = getPrivateKey("C:/signPri.key");
036
037 // 전자서명하기
038 Signature signatureA = Signature.getInstance("SHA1withRSA");
039 signatureA.initSign(privateKey);
040 signatureA.update(msg.getBytes());
041 byte[] sign = signatureA.sign();
042 System.out.println("signature : " + ByteUtils.toHexString(sign));
043
044 // 전사서명 검증하기
045 String msgB = msg;
046 Signature signatureB = Signature.getInstance("SHA1withRSA");
047 signatureB.initVerify(publicKey);
048 signatureB.update(msgB.getBytes());
049 boolean verifty = signatureB.verify(sign);
050 System.out.println("검증 결과 : " + verifty);
051 }
052
053 public static PublicKey getPublicKey(String file) throws Exception {
054 X509Certificate cert = null;
055 FileInputStream fis = null;
056 try {
057 fis = new FileInputStream(new File(file));
058 CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
059 cert = (X509Certificate) certificateFactory.generateCertificate(fis);
060 } finally {
061 if (fis != null) try {fis.close();} catch(IOException ie) {}
062 }
063 System.out.println(cert.getPublicKey());
064 return cert.getPublicKey();
065 }
066
067 public static PrivateKey getPrivateKey(String file) throws Exception {
068 // 1. 개인키 파일 읽어오기
069 byte[] encodedKey = null;
070 FileInputStream fis = null;
071 ByteArrayOutputStream bos = null;
072 try {
073 fis = new FileInputStream(new File(file));
074 bos = new ByteArrayOutputStream();
075 byte[] buffer = new byte[1024];
076 int read = -1;
077 while ((read = fis.read(buffer)) != -1) {
078 bos.write(buffer, 0, read);
079 }
080 encodedKey = bos.toByteArray();
081 } finally {
082 if (bos != null) try {bos.close();} catch(IOException ie) {}
083 if (fis != null) try {fis.close();} catch(IOException ie) {}
084 }
085
086 System.out.println("EncodedKey : " + ByteUtils.toHexString(encodedKey));
087
088 // 2. 개인카 파일 분석하기
089 EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(encodedKey);
090 System.out.println(encryptedPrivateKeyInfo);
091 System.out.println(encryptedPrivateKeyInfo.getAlgName());
092
093 byte[] salt = new byte[8];
094 System.arraycopy(encodedKey, 20, salt, 0, 8);
095 System.out.println("salt : " + ByteUtils.toHexString(salt));
096 byte[] cBytes = new byte[4];
097 System.arraycopy(encodedKey, 30, cBytes, 2, 2);
098 int iterationCount = ByteUtils.toInt(cBytes);
099 System.out.println("iterationCount : " + ByteUtils.toHexString(cBytes));
100 System.out.println("iterationCount : " + iterationCount);
101
102
103 String password = "password";
104
105 // 추출키(DK) 생성
106 byte[] dk = pbkdf1(password, salt, iterationCount);
107 System.out.println("dk : " + ByteUtils.toHexString(dk));
108
109 // 생성된 추출키(DK)에서 처음 16바이트를 암호화 키(K)로 정의한다.
110 byte[] keyData = new byte[16];
111 System.arraycopy(dk, 0, keyData, 0, 16);
112
113 // 추출키(DK)에서 암호화 키(K)를 제외한 나머지 4바이트를 SHA-1
114 // 으로 해쉬하여 20바이트의 값(DIV)을 생성하고, 그 중 처음 16바이트를 초기
115 // 벡터(IV)로 정의한다.
116 byte[] div = new byte[20];
117 byte[] tmp4Bytes = new byte[4];
118 System.arraycopy(dk, 16, tmp4Bytes, 0, 4);
119 div = SHA1Utils.getHash(tmp4Bytes);
120 System.out.println("div : " + ByteUtils.toHexString(div));
121 byte[] iv = new byte[16];
122 System.arraycopy(div, 0, iv, 0, 16);
123 System.out.println("iv : " + ByteUtils.toHexString(iv));
124
125 // 3. SEED로 복호화하기
126 BouncyCastleProvider provider = new BouncyCastleProvider();
127 Cipher cipher = Cipher.getInstance("SEED/CBC/PKCS5Padding", provider);
128 Key key = new SecretKeySpec(keyData, "SEED");
129 cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
130 byte[] output = cipher.doFinal(encryptedPrivateKeyInfo.getEncryptedData());
131
132 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(output);
133 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
134 RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)keyFactory.generatePrivate(keySpec);
135 System.out.println(privateKey);
136 return privateKey;
137
138 }
139
140 public static byte[] pbkdf1(String password, byte[] salt, int iterationCount) throws NoSuchAlgorithmException {
141 byte[] dk = new byte[20]; // 생성이 의미가 없지만 한눈에 알아보라고 20바이트로 초기화
142 MessageDigest md = MessageDigest.getInstance("SHA1");
143 md.update(password.getBytes());
144 md.update(salt);
145 dk = md.digest();
146 for (int i = 1; i < iterationCount; i++) {
147 dk = md.digest(dk);
148 }
149 return dk;
150 }
151 }



반응형
반응형
반응형

'유용한 링크 모음' 카테고리의 다른 글

무료 QR 코드 생성 사이트  (0) 2020.02.07
공인인증서 관련 개발사이트  (0) 2011.09.01
할인 쿠폰 사이트  (0) 2010.08.27
드로잉 사이트  (0) 2010.02.08

+ Recent posts