[스그랩] 자체 인증으로 signed applet 구현

[#M_ 내용 보기.. |

From. JAVA LAND
Title. [후기]Java Plugin 1.3 에서 자체 인증으로 digitally signed applet 구현하기
Name. 김일형

안녕하세요, 김일형입니다.

이번에 엄청 고생해서 자바 플러그 인을 지원하는 자체 인증을 통하여 digitally signed applet을 구현하였습니다. 아직 더 많이 다듬어야겠지만 일단은 됩니다.

환경 설명………………..

제가 구현하려는 시스템의 Front-end는 웹환경으로 자료를 검색해서 결과를 테이블로 보고 해당 자료의 다운로드가 가능해야하고 프린팅도 지원해야 합니다.
따라서 일반 Java Script 또는 JSP로는 구현하는데는 한계가 있어서 당연 Applet을 사용해야하는데 다운로드 또는 프린팅이 지원이 않되는 문제가 있습니다.
따라서 이 applet을 인증시켜야하는데 이를 위해서는 Verisign와 같은 공인된 인증기관을 이용해야 한다는 것이죠.
그런데 어차피 회사사람만이 이용을 할 것이기 때문에 제3의 기관에 돈을 내는 것은 말이 좀 말이 되지 않았습니다 ( -__-;; )
그래서 생각해낸 방법이 공인기관을 거치지 않고 자체 인증을 통한 signed applet을 구현하는 것 입니다 (OpenSSL).

준비물 …………………………………………..
1. JDK 1.3.1 또는 Java Plugin 1.3.1
2. OpenSSL 0.9.6b 이상 (www.openssl.org에서 다운가능)
3. Apache ( Web Server )

환경준비 …………………………………………

1. Unix (Linux)에 OpenSSL 설치

간단하게 설명을 드리면 …
일단 앞축을 풀고 해당 디렉토리에 가서
$ ./config –prefix=/usr/local –openssldir=/usr/local/openssl
라고 하면 실행파일은 /usr/local/bin에 가서 깔리고 인증 서비스를 위한 자료는 /usr/local/openssl 밑에가서 깔립니다.

$ make

를 해서 컴파일을 하시고

$ make test

를 해서 시험을 합니다. 만일 문제가 특별히 발생하지 않으면

$ make install

을 해서 설치를 합니다. (자세한 설치는 INSTALL 파일을 참조하십시요)

2. OpenSSL을 이용한 서비스 환경 설정

인증 서비스를 하려면 일단 rootCA라는 것을 가져야합니다. 이것은 자기 자신이 발행한 인증요구서를 자신이 인증하여 다른 개인이나 기관에게 배포하기 위한 것입니다.

2.1 비밀키의 생성

$ openssl genrsa -des3 -out ca.key 1024

2.2 비밀키를 자신이 인증하여 인증서 화일을 생성

$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt

2.3 openssl.cnf 파일 수정

CA_default 부분에 “dir”을 자신의 상황에 맞게 수정한다. (보통은 “/path/to/openssldir/자신의CA”의 형태)

2.4 필요한 디렉토리와 파일을 생성

$ mkdir /usr/local/openssl/MyCA
$ mkdir /usr/local/openssl/MyCA/certs
$ mkdir /usr/local/openssl/MyCA/crl
$ mkdir /usr/local/openssl/MyCA/newcerts
$ mkdir /usr/local/openssl/MyCA/private
$ echo “01” > /usr/local/openssl/MyCA/serial
$ touch /usr/local/openssl/MyCA/index.txt

2.5 생성된 비밀키와 공개키를 openssl.cnf에서 지정한 디렉토리에 저장한다.

ca.key는 /path/to/openssldir/자기CA/private/cakey.pem으로 복사하고 ca.crt는 /path/to/openssldir/자기CA/cacert.pem정도로 복사하면 됩니다.

이상의 내용은 http://kldp.org/KoreanDoc/html/OpenSSL-KLDP/OpenSSL-KLDP.html에서 4.2절 까지의 내용입니다.

다음에는 실제 이를 이용하여 signed applet을 작성하는 것을 설명드리도록 하겠습니다.

이번에는 실제 인증하는 방법입니다.

지금까지 제가 자료를 모은 것에 의하면 과거 1.1때에는 MS IE 또는 Netscape 독자적으로 인증을 하는 방법이 존재했습니다. 그래서 각각의 인증방법이 틀렸고 그 말은 각각의 브라우저를 위해 코드도 서로 틀리게 작성해야 한다는 것입니다. 독자적으로 import하는 패키지가 틀렸걸랑요.

그러다가 1.2때부터 SUN에서 각각의 브라우저에 사용될 수 있는 plugin을 제시하였고 이제는 각각의 브라우저에 똑같이 적용될 수 있는 것이 나왔습니다. 다 아시다시피 이제는 더이상 applet 태그를 사용하지 않습니다. IE에서는 OBJECT, NS에서는 EMBEDED 태그를 대신 사용하죠.

처음에는 저도 각각의 브라우져에 대해 인증을 하는 방법으로 접근했다가 방향을 바꿔서 SUN의 지침을 따르기로 했습니다.

하지만 단점도 있습니다만 그것은 다음에 설명을 드리도록 하죠.

1. 예제 프로그램……………………………………

첨부된 파일의 코드는 지정한 url 과 port를 검사하는 것입니다. 다 아시는 것이겠지만 applet은 자신이 온 서버와 클라이언트로만 통신이 가능합니다. 따라서 이 프로그램을 인증 없이 사용한다면 localhost의 포트는 검사할 수 없겠죠.

2. 컴파일 하고 jar로 묶기 ……………………………………..

위의 코드를 저장하고

$ javac SimpleScannerApplet.java

를 하면 다음과 같은 코드들이 생기죠.

SimpleScannerApplet$Scanner.class
SimpleScannerApplet$ScannerException.class
SimpleScannerApplet.class
SimpleScannerApplet$1.class

$jar -cvf scan.jar *.class

이렇게 하면 scan.jar가 생깁니다.

3. 인증을 위한 준비 …………………………………

이제는 자바의 keytool을 이용하여 키를 생성합니다.

$ keytool -genkey -alias jamie -keyalg rsa

라고 하면 키를 생성하기 위한 각종 질문을 해옵니다. 잘 대답을 하시면 내부에 .keystore 라는 파일이 생깁니다. 패스워드는 잘 기억을 하십시요. 2가지가 있는데 keystore자체의 password하고 해당 엘리어스 (jamie)에 대한 패스워드 2가지이죠.

다음에는 인증요청서를 작성하는 것입니다.

$keytool -certreq -alias jamie
Enter keystore password: 123456

라고 하면 아래와 같은 결과가 화면으로 나오는데 이것을 리다이렉션을 통하여 scan.csr로 저장을 합니다.

—–BEGIN NEW CERTIFICATE REQUEST—–
MIIBvzCCASgCAQAwfzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRQwEgYDVQQHEwtDaHVsYSBW
aXN0YTEXMBUGA1UEChMOSmFtZXMgSmF3b3Jza2kxHTAbBgNVBAsTFFNvZnR3YXJlIGRldmVsb3Bt
ZW50MRUwEwYDVQQDEwxqYXdvcnNraS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPb5
Yt3M48Lwf2OjVYBG8+89HF35JB/YpHyyHt4DTohFeS2KbAQEvI03FGtG9KXZpzgumBttxhfiqRF8
6bF2GO8eDK1COubJ6ckEZziSlTUFYoLXqmLTui85TApXB8kJzj+SygQ2OP0APtVy6E3dq66izl89
RUzMdTH60QPxtbc5AgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQBEtAffkQVHRB8bGsm6yP7Sb8zZ
ert3h8pXdBlFjtC+SZZxUQq/rOGyqh1H320ZqJlcnmRBrgQth3KDh3WPXposnTt4eHwJKyK/whUk
0ucbkDo3cdidLLg4/as0QsVmje7udzcCdnCX6NuQqjvAayaOviU1i5GvN8ALbpWwbrf0uw==
—–END NEW CERTIFICATE REQUEST—–

계속……………………..

4. 인증하기 …………………………………

이렇게 생성된 scan.csr파일을 Verisign같은 공인 인증기관에서 인증을 하면 그 것으로 signed applet을 만들면 되는데, 일단 돈들이기가 싫으니까 대신에 OpenSSL이 인증을 해주는 것입니다.

$ openssl ca -out scan.crt -infiles scan.csr

라고 하면 요청된 인증서에 대한 scan.crt 라는 인증파일이 작성이 됩니다. 기본적으로 전 회에서 말씀드린 openssl.cnf 파일에서 작성한 환경을 이용을 할 것입니다.

그리고 확인…

$ openssl verify -CAfile ca.crt scan.crt

위의 ca.crt 파일은 전회에서 생성한 openssl의 자체 인증서입니다.

이를 DER 형식으로 인증서를 변환을 합니다.

$ openssl crl2pkcs7 -nocrl -certfie scan.crt -certfile ca.crt -outform DER -out scan.der

앞에서 말씀드렸듯이 ca.crt파일은 전회에서 생성한 openssl의 자체 인증서입니다.

4. Applet을 인증하기 …………………………………

이렇게 생성된 scan.der 인증서 파일을 개발환경으로 가져와서 import를 시킵니다.

$ keytool -import -alias jamie -file scan.der

이렇게 하면 뭔가 쭉 나오다가 끝에가서

… is not trusted. Install reply anyway? [no]: yes

라고 나오는데 yes라고 하면 다음 메세지가 나와야 합니다.

Certificate reply was installed in keystore

그리고 마지막으로 에플릿에 사인을 합니다.

$ jarsigner scan.jar jamie

그러면 끝입니다.

첨부된 파일은 위의 에플릿을 구동하기 위한 htm 파일입니다.

5. Applet설치하기 …………………………………

이렇게 생성된 에플릿고 html파일은 일반 웹문서와 같이 웹 서버에 설치하면 됩니다.

다음에는 주의 사항을 말씀드리죠… 다 된게 아닙니다.

이제는 앞에서 준비한 것을 실행해보는 차례인데요….

처음 해보시면 인증받지 않은 기관의 것이라고 Exception 창이 뜨고
localhost에 80번 포트를 점검해보면 접근 거부가 나옵니다.

이게 이 방법을 취했을 때의 문제입니다.

과거 공인기관의 경우 승인할 지의 여부가 사용자에 의해서 판단이 되었고 설령 지금 읽어들이려는 기관이 공인기관이 아니어도 사용자만 OK하면 무조건 읽혀졌는데 JRE가 plug-in이 되면서 보안에 대한 것이 더욱 강화가 되었습니다.

그래서 지금은 물어보지도 않고 Verisign 또는 Thawte와 같은 공인 기관이 아니면 무조건 예외를 터뜨려댑니다.

그렇지만 해결책은 있지요.

사용자입장에서 보면 조금 귀찮은 것이기는 하지만 한번만 해두면 다시 건드리는 경우는 없습니다.

1. 배경설명………………………………………………….

일반적으로 JRE의 인증기관은 Windows의 경우 C:Program FilesJavaSoftJRE1.3.1_02libsecuritycacerts 파일에 binary의 형태로 기록이 되어있는 것으로 추측이 됩니다.

따라서 자신의 인증서버를 사용하고자 한다면 그 인증서를 이 파일에 추가를 해줘야 합니다.

2. 인증서 추가 방법 …………………………………………..

앞에서 만든 OpenSSL의 ca.crt파일이 인증서버의 인증서입니다. 이게 사용자에게 배포되어야 하는 것입니다.

2.1 과거의 같은 엘리어스를 사용하는 인증서를 삭제

앞에서 설명을 드렸듯이 일단 cacerts 파일의 공인기관 목록에서 같은 이름을 사용하고 있는 기관을 삭제합니다.

$ keytool -delete -keystore “C:Program Filesjavasoftjre1.3.1_02libsecuritycacerts” -storepass changeit

여기서 -storepass를 생략하면 cacerts에 대한 password를 물어오는데 기본 값으로 “changeit” 입니다. 그리고 -keystore 를 생략하면 아마도 기본적으로 자신의 기본 디렉토리에 있는 .keystore 로 작업을 합니다. 그런데 이 것은 원하는 바가 아니죠. 반드시 cacerts파일을 상대로 작업을 해야합니다.

그리고 나서 배포된 인증서 (ca.crt) 파일을 import 합니다.

$ keytool -import -file ca.crt -keystore “C:Program Filesjavasoftjre1.3.1_02libsecuritycacerts” -storepass changeit

이렇게함으로써 생성된 인증서는 cacerts로 공증기관으로서 입력이 됩니다.
그럼 다음부터는 인증되지 않은 기관이라고 무조건 Exception 터뜨리는 상황은 없겠죠.

제가 이렇게 길게 패스워드까지 포함하며 한 행으로 명령을 다 때려넣으려는 이유는 만일 저와 같은 목적으로 signed applet을 운영하고자 하시는 분이 계시면 간단하게 batch파일로 만들 수 있게 함입니다.

사용자를 위한 도움말 페이지에서 간단하게 배치파일을 다운받아 실행시키게 하면 쉽게 사용자의 공인 인증기관 목록을 업데이트할 수 있습니다.

2.2 최후 테스트

그럼 모든 상주된 브라우져를 종료하고 다시 시작해보십시요.
그럼 인증서를 어떤 형태로 허가할 것인지 물어봅니다.

“Grant this Session”, “Deny”, “Grant Always”, “View Certificate”

이 중에서 맘에 드는 것을 고르면 됩니다.
이 다이얼로그가 나와야 정상적으로 공인기관으로 등록되었다는 것입니다.

3. 끝으로 …………………………………………………..

위의 것을 IE, NS에서도 해봤는데 정상적으로 잘 되었습니다. 한마디로 호환성 걱정을 안해도 된다는 것이죠.

제가 몇주간 고생을 한 것인데 다른 분들은 그런 시간낭비를 하지 않았으면 하는 바램에서 몇자 끄적여 봤습니다.

많은 도움이 되었기를 바라며 얕은지식에 얼마나 많은 도움이 될지는 모르지만 메일 주시면 또 공부해서 답드리겠습니다.

김일형.
닫기.. | _M#]

좋은 정보에 감사^^

Intro

2003년에도 그랬을 것이다. 2004년이라는 숫자의 낯설음을…

현재 2004년. 2005년이라는 숫자가 낯설게 다가온다.

2002년 군제대, 2003년 4학년, 2004년 첫직장, 2005년 ?????

2002년도 이후 내 자신이 급변하게 일년단위로 바뀌고 있다.

2005년도에도