วันพฤหัสบดีที่ 15 ธันวาคม พ.ศ. 2554

NAT [STUN/TURN/ICE]

มาขอจด note กันลืม เรื่อง NAT traversal หน่อย [How to deal with final users / End-to-end tunnel ]

1. Nat มี 4 ประเภท แบบ fix/no fix port, fix/no fix IP ถ้าเป็นแบบที่ fix ทั้งหมด จะเรียกว่า symmetric nat ซึ่งจัดการยากที่สุด

1.1 Full cone => เหมือนกับทำ dynamic port forward เวลาส่งออก iAddr:iPort จะ map กับ eAddr:ePort แล้วส่งไปหา hAddr:hPort จากนั้น hAny:hAny สามารถส่งเข้ามาได้ iAddr:iPort ได้ แม้ว่าจะไม่เคยได้รับการติดต่อมาก่อน

1.2 Restrict cone => iAddr:iPort ส่ง packet ออกไปยังเครื่องใด ๆ ด้วย eAddr:ePort เช่น ส่งไปหา hAddr:hPort แล้ว hAddr:hAny สามารถส่งเข้ามาได้ iAddr:iPort ได้
( เวลา internal ส่งออก ไม่ว่าปลายทางเป็นเครื่องเครื่องไหน ใช้ eAddr:ePort แต่เครื่องนอก hAddr:hAny สามารถส่งกลับมาได้ ก็ต่อเมื่อเคยได้รับ packet จาก internal ก่อน)

1.3 Port Restrict cone => iAddr:iPort ส่ง packet ออกไปยังเครื่องใด ๆ ด้วย eAddr:ePort เช่น ส่งไปหา hAddr:hPort แล้ว hAddr:hPort สามารถส่งเข้ามาได้ iAddr:iPort ได้
( เวลา internal ส่งออก ไม่ว่าปลายทางเป็นเครื่องเครื่องไหน ใช้ eAddr:ePort แต่เครื่องนอก hAddr:hPort สามารถส่งกลับมาได้ ก็ต่อเมื่อเคยได้รับ packet จาก internal ก่อน)

1.4 Symmetric cone => iAddr:iPort ส่ง packet ออกไปยังเครื่องนอก ด้วยการ map port ที่ต่างกัน ไม่เหมือน 3 อันที่กล่าวมา คือ ไม่ว่าปลายทางเครื่องไหน ใช้ eAddr:ePort เสมอ แต่แบบ Symmetric จะ map port ใหม่ สำหรับ เครื่องปลายใหม่ ส่วนเวลาตอบกลับ hAddr:hPort สามารถส่งกลับมาได้ ก็ต่อเมื่อเคยได้รับ packet จาก internal ก่อนเท่านั้น


2. ใช้ application layer gateway / session border controller มาช่วยจัดการ (อ่านแล้วยัง งง ๆ ว่าตกลงมันต่างกันยังไงวะ) แต่ มัน deploy ยาก และ ไม่ scalability + more delays

3. Stun เข้ามาแก้ปัญหาเรื่อง nat แบบที่ไม่ใช่ symmetric โดยการใช้ เทคนิค UDP hole punching (จะใช้ tcp ก็ได้ แต่ไม่ค่อยนิยม และ ทำโอกาสสำเร็จมีน้อยกว่า) คือ ให้ client หลัง nat คุยกับ stun server ก่อน เป็นการเจาะรู เพื่อให้ ผู้ติดต่ออีกฝ่าย สามารถเข้าถึง client คนนี้ ผ่านทาง รู ที่เจาะไว้ โดยอาศัยข้อมูลจาก stun server กรณีนี้ ถ้าเป็น full cone ก็ติดต่อได้เลย หลังจาก เจาะรูแล้ว แต่ถ้าเป็น แบบ (port) restrict cone พอเจารูเสร็จ ทั้งคู่ จะต้องติดต่ออีกฝ่าย คนที่รับข้อมูลก่อน NAT จะ drop packet ทิ้ง เพราะถือว่าไม่เคยได้รับการติดต่อ ส่วนอีกคนที่ได้รับข้อมูลทีหลัง NAT จะปล่อยผ่าน เพราะถือว่า เคยส่งไปหาก่อน ทีนี้ก็จะสามารถติดต่อกันได้

4. กรณีที่อยู่หลัง nat ที่เป็น symmetric ทั้งคู่ ก็คล้าย ๆ กัน แต่ relay server จะต้อง forward packet ทุกอย่างไปให้ผู้ที่ติดต่อทั้ง 2 ฝ่าย (เพราะถ้าเปลี่ยน destination ตัว nat มันจะ map port ใหม่ เราเลยต้องมี relay ไว้ส่งต่อ packet) เราเรียกว่า TURN นั่นเอง = Stun + Relay extentions

5. ICE = STUN + TURNS , ICE เป็น protocol ที่คอยมาตรวจสอบว่า จำเป็นต้องใช้ Turn ด้วยหรือเปล่า แล้วก็จัดตั้งการสื่อสารขึ้นมา

แต่สุดท้ายหลักการก็เหมือนกัน ก็คือเจาะรู เข้า nat ไว้ก่อน แล้วก็ส่ง หมายเลข port ที่ใช้ในการติดต่อ ถ้ามัน restrict ทั้ง IP และ port เมื่อส่งหากันครั้งแรก package จะโดน drop ที่ฝั่งผู้รับที่ได้รับข้อมูลก่อน (เพราะมัน restrict) แต่พอ ฟังผู้รับส่งมาให้ผู้ส่ง คราวนี้จะไม่ drop ที่ฝ่ายส่งครั้งแรก เนื่องจาก ฝ่ายส่งได้เคยส่งข้อมูลหาไปแล้ว

อธิบายไว้ละเอียดที่นี่

วันอังคารที่ 6 ธันวาคม พ.ศ. 2554

Keystore for TLS/SSL #3

Create ca.pem/ca_pk.pem for HTTPS

openssl req -x509 -new -config openssl.cfg -days 365 -out ./new/ca.pem -keyout ./new/ca_pk.pem
Pass: 123456

ca.pem
ca_pk.pem

========
create keystore:
keytool -import -alias certificatekey -file ca.pem -keystore catruststore.jks

========
Convert for Apache
openssl rsa -in ./new/ca_pk.pem -out ./new/ca_pk.key
Got ca_pk.key (key file for apache)

openssl x509 -x509toreq -days 365 -in ./new/ca.pem -signkey ./new/ca_pk.key -out ./new/ca.req
Got ca.req (For sign certificate)

openssl x509 -in ./new/ca.req -out ./new/ca.cert -req -signkey ./new/ca_pk.key -days 365
Got ca.cert (certificate for apache)

================
create keystore:
keytool -import -alias certificatekey -file ca.cert -keystore catruststore-cert.jks

================
Create cert for browser
There are 3 choices:

1. Directly load from browser.

2. openssl x509 -inform PEM -in ./new/ca.pem -outform DER -out ./new/ca.cer

3. openssl x509 -inform PEM -in ./new/ca.cert -outform DER -out ./new/ca1.cer

วันพฤหัสบดีที่ 1 ธันวาคม พ.ศ. 2554

Birthday paradox

หากคุณไปงานเลี้ยง แล้วเดินถามวันเกิด (เอาเฉพาะวันกับเดือน) ของคนที่คุณคุยด้วย คุณจะพบว่าใน 23 คนที่คุณถามวันเกิด จะมีโอกาสสูงที่คนที่เกิดวันเดียวกันอยู่ 1 คน

ใน 1 ปีหนึ่งมีตั้ง 365 วัน แต่ถามแค่ 23 คน กลับเจอคนที่เกิดวันเดียวกันคนเดียว

สรุปตามหลักสถิติ
sample 2^n จะมีโอกาสเกิด collision ที่ 2^n/2

365 = 2^8.51 => collision ที่ 2^8.51/2 = 19.104 ใกล้เคียงกับความจริงคือ 23 มากเลย

เพื่อป้องการปัญหาการ collision ของ hash function ควรจะ hash ที่ 160 bits

Why not Client Auth? on TLS/SSL

- สร้าง TLS/SSL โดยใช้ JSSE ซึ่งใช้ public/private (keystore/truststore) ในการเข้ารหัส โดยกำหนดค่าผ่าน SSLContext

- Server อ่านค่า private key ของตนเอง แล้ว เปิด port รอไว้ เมื่อ client จะติดต่อ ก็ไป load public key ของ server มา แล้วก็ connect server โดยใช้ TLS/SSL ไร้ปัญหา สำหรับ server เพราะเป็นตัวจริงแน่ ๆ ถ้า public key ของ server เป็นของจริง

- ปัญหาคือ หาก server ต้องการ Authen Client ด้วย ถ้ามีแค่ 2 เครื่องแบบ client-server ก็ง่ายนิดเดียว ซึ่งเราสามารถสั่ง Client Auth ได้ผ่านคำสั่ง sslserversocket.setNeedClientAuth(true); โดยการกำหนด public key ของ client และ private key ของ server ที่ server ก่อนที่จะเปิด port รอ และ client ก็ set ในแบบเดียวกัน

- แต่ถ้าในระบบ P2P/DHT/Chord Server ไม่สามารถทราบได้ว่า client มีใครจะมาติดต่อบ้าง และ server ต้องเปิด port รอ โดยที่ยังไม่ทราบ public key ของ client และ ปัญหาใหญ่คือ ทุก ๆ เครื่องเป็น ทั้ง client/server ในตัว

- วิธีแก้ปัญหาในตอนนี้คือ ให้ verify เฉพาะ server อย่างเดียว เพราะ server เปิด port รอไว้ โดยใช้ private key ของตัวเอง client ก็ verify server โดยใช้ public key ของ server (อาจจะไป download จาก CA ที่ไหนสักแห่งที่ไว้ใจได้) ส่วนการ verify client ให้ใช้วิธีการ verify แบบอื่นที่ง่ายกว่า เช่น HTTP Digest เนื่องจาก วิธีนี้ มี overhead น้อย และ ปลอดภัย เนื่องจากมันถูกห่อหุ้มด้วย TLS/SSL อยู่ด้วย

- แต่การใช้ HTTP Digest มันก็ต้องมี pre-shared key ซึ่งส่งกันลำบาก ถ้ามองในแง่การส่งข้อมูล ที่ได้ทำการ implement แบบ stateless เวลา P1 -> P2, P2 ถูก verify แต่ P1 ไม่ถูก verify แต่เมื่อ P2 ตอบกลับ P1 ถูก verify แต่ P2 ไม่ถูก verify สุดท้ายแล้วก็ได้ verify ทั้ง 2 ฝ่ายอยู่ดี (เหลือปัญหาอยู่อย่างเดียวคือ คนที่เริ่ม connection อาจจะไม่ใช่คนนั้นจริง ๆ แต่ก็ตรวจสอบได้ภายหลัง)

CA Keystore/Truststore

Set up own Certificate Authority (need openssl for CA)

1. download openSSL from http://www.slproweb.com/products/Win32OpenSSL.html


2. สร้าง private key/certificate โดยคำสั่ง

C:\OpenSSL-Win32\bin> openssl req -x509 -new -config openssl.cfg -days 365 -out ./new/ca.pem -keyout ./new/ca_pk.pem
Pass: 123456

จากคำสั่งนี้จะได้ certificate ca.pem กับ private key ca_pk.pem


3. นำ certificate มาสร้าง CA truststore โดยคำสั่ง

C:\OpenSSL-Win32\bin> keytool -import -alias certificatekey -file ca.pem -keystore catruststore.jks



Create Keystore and Truststore for a user

1. สร้าง keystore

C:\OpenSSL-Win32\bin\new> keytool -genkey -alias certificatekey -keypass 123456 -keystore CertName.jks -storepass 123456 -validity 365

หรือ ถ้าขี้เกียจพิมพ์ เอาแบบรวดเร็วก็
C:\OpenSSL-Win32\bin\new> keytool -genkey -alias certificatekey -dname "cn=147.127.240.90, ou=IRIT, o=Sun, c=FR" -keypass 123456 -keystore CertName.jks -storepass 123456 -validity 365

ต้องใส่ค่าต่าง ๆ ให้ตรงกับใน ca.pem ถ้าใส่ไม่ตรงต้องไปแก้ openssl.cfg ดังนี้

dir = ./PEM/demoCA # Where everything is kept
policy = policy_anything # otherwise, has to put exactly the same information


2. สร้าง certificate ที่ request การ sign

C:\OpenSSL-Win32\bin\new> keytool -certreq -alias certificatekey -file CertName_csr.pem -keypass 123456 -keystore CertName.jks -storepass 123456

จะได้ output คือ CertName_csr.pem


3. sign CSR (certificate)

C:\OpenSSL-Win32\bin> openssl ca -config openssl.cfg -days 365 -in ./new/CertName_csr.pem -out ./new/CertName.pem -cert ./new/ca.pem -keyfile ./new/ca_pk.pem


4. แปลงไฟล์ในรูปแบบ PEM format
openssl x509 -in ./new/CertName.pem -out ./new/CertName.pem -outform PEM


5. เอา certificate มาต่อกัน
copy CertName.pem + X509CA\ca\new_ca.pem CertName.chain


6. update keystore (private key)
keytool -import -file CertName.chain -keypass 123456 -keystore CertName.jks -storepass 123456


7. สร้าง truststore (public key)
C:\OpenSSL-Win32\bin\new>keytool -import -alias certificatekey -file CertName.chain -keystore truststore.jks


8. ดูผล โดยการ
keytool -list -v -keystore CertName.jks => จะมี Entry type: PrivateKeyEntry และ Entry type: trustedCertEntry
keytool -list -v -keystore truststore.jks => จะมี Entry type: trustedCertEntry อย่างเดียว


Reference links:
==== CA ======
http://fusesource.com/docs/esb/4.3/amq_security/i305191.html
http://fusesource.com/docs/esb/4.3/amq_security/i382664.html
http://www.linuxquestions.org/questions/linux-networking-3/trouble-generating-ssl-certificates-116973/
http://www.g-loaded.eu/2005/11/10/be-your-own-ca/
http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/index.html

Keytool: http://www.techbrainwave.com/?p=953

Dynamic keystore: http://jcalcote.wordpress.com/2010/06/22/managing-a-dynamic-java-trust-store/

วันพุธที่ 30 พฤศจิกายน พ.ศ. 2554

Java TLS/SSL #2

ตัวอย่าง code JSSE


ตัวอย่างในการ Run
Server:
D:\java\TLS>java ClassFileServer 80 . TLS true

Client:
D:\java\TLS>java SSLSocketClientWithClientAuth 147.127.xxx.90 80 /index.html


Modify to support Client authentication:

ClassFileServer:
ks.load(new FileInputStream("keystore-147.127.xxx.90"), passphrase);
kmf.init(ks, passphrase);
KeyStore ksTrust = KeyStore.getInstance("JKS");
ksTrust.load(new FileInputStream("truststore-147.127.xxx.91"), null);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ksTrust);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
===========================

SSLSocketClientWithClientAuth:
ks.load(new FileInputStream("keystore-147.127.xxx.91"), passphrase);
kmf.init(ks, passphrase);
KeyStore ksTrust = KeyStore.getInstance("JKS");
ksTrust.load(new FileInputStream("truststore-147.127.xxx.90"), null);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ksTrust);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

===========================
Just swap truststore and keystore for each other.



Trust store เหมือน public key แต่ทำไมจึงมี password?
Ans:
NOTE: Trust stores often have passwords but for validation of credentials the password is not needed because public key certificates are publicly accessible in any key or trust store. If you supply a password, the KeyStore.load method will use it when loading the store but only to validate the integrity of non-public information during the load – never during actual use of public key certificates in the store. Thus, you may always pass null in the second argument to KeyStore.load. If you do so, only public information will be loaded from the store.

วันพฤหัสบดีที่ 24 พฤศจิกายน พ.ศ. 2554

P2PNS vs RELOAD

Interested P2PSIP security solutions

- P2PNS: เป็น p2p-sip overlay ที่ใช้ การ hash(public-key) ในการ create ID เพื่อป้องการพวก Sybil attack สามารถ config DHT algorithm ใช้งานผ่าน OpenSER ที่ติดต่อกับ overlay network ที่ได้จาก OverSim (ที่ Run ผ่าน Omnet++ อีกที)

default DHT algorithm คือ Kademlia

P2PNS ออกแบบมาเพื่อให้ peer เก็บค่าของ SIP AoR ที่ Peer เอง และ retrieve ผ่าน DHT algorithm แทนที่จะต้องไป Query ผ่าน Name Server (เลยตั้งชื่อว่า P2PNS) แต่ไม่ได้บอกรายละเอียดชัดเจน ของ security เกี่ยวกับ การรับส่งข้อมูล



- RELOAD: คล้าย ๆ กับ P2PNS แต่ กำหนดเงื่อนไข รายละเอียดการส่งข้อมูลเยอะกว่า มี security layer บังคับใช้ TLS/SSL รวมกับ PKI, มี Certificate server ไว้ตรวจสอบ กำหนดทุกการส่งต้องผ่าน TLS/SSL

default DHT algorithm คือ chord




วันศุกร์ที่ 21 ตุลาคม พ.ศ. 2554

SSLContext

วิธีการกำหนดให้ใช้ Java SSL/TLS ก่อนจะสร้าง SSLSocket ขึ้นมามีหลายวิธี

1. กำหนดผ่าน SystemProperty โดย ทาง commandline

-Djavax.net.ssl.keyStore=keystoreSrv

หรือ set ใน program
System.setProperty("javax.net.ssl.keyStore", "keystoreSrv");


2. กำหนดใน JAVA_HOME/lib/security/jssecacerts หรือ JAVA_HOME/lib/security/cacerts


สร้าง SSLSocket ได้ดังนี้
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();

หากโชคดี connect ได้พอดีกับ ตอนที่ GetDefault ของ SSLContext ที่อ่านข้อมูลจาก SystemProperty ได้ทัน ก็ Run ได้ผ่านไม่มีปัญหา ซึ่งกรณีที่ทำ 1 connection จะไม่เจอปัญหานี้ (เหมือนกับตัวอย่าง code ที่เคยเขียนไว้)

แต่วิธีที่กล่าวมานั้น ไม่สามารถใช้ได้ในกรณีที่ทำ multiple TLS/SSL connections รวมกับ การ create Multi-Thread ไว้รอรับ connections เพราะเวลาสั่ง getDefault() ของ SSLContext เพื่อสร้าง SSLSocket หรือ SSLServerSocket แล้ว มักจะเจอ error เช่น

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

หรืออาจจะเป็น error อื่น ๆ เช่น certificate error, หา certificate ไม่เจอ ฯลฯ

ทั้ง ๆ ที่เราก็ set ค่า keyStore กับ trustStore ผ่าน SystemProperty ไปแล้ว

วิธีแก้ไขคือ
ให้สร้าง SSLContext ขึ้นมาเอง ดังนี้

public SSLContext createSSLContext(int type) {
//------------
char[] password;
SSLContext ctx = null;
InputStream in = null;
KeyStore ks = null;
KeyManagerFactory kmf = null;
TrustManagerFactory tmf = null;

try {

kmf = KeyManagerFactory.getInstance("SunX509", "SunJSSE");
tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE");

if (type == KEYSTORE) { // for authen incoming connection
ks = KeyStore.getInstance(KeyStore.getDefaultType());
password = "123456".toCharArray();
in = (new FileInputStream("keystoreSrv"));
ks.load(in, password);
kmf.init(ks, password);
} else { // for connect another to authen
ks = KeyStore.getInstance(KeyStore.getDefaultType());
//password = "123456".toCharArray();
in = (new FileInputStream("truststoreCli"));
ks.load(in, null);
kmf.init(ks, null);
}

in.close();
tmf.init(ks);
ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} catch (Exception e) {
e.printStackTrace();
}
return ctx;
}

จากนั้นเราก็นำ ctx นี่แหละไปสร้าง SSLSocket หรือ SSLServerSocket ดังนี้

SSLServerSocketFactory sslserversocketfactory = ctx.getServerSocketFactory();

SSLSocketFactory sslsocketfactory = ctx.getSocketFactory();

เท่านี้ก็จะไม่เจอ Error ดังกล่าวแล้วครับ

วันอังคารที่ 18 ตุลาคม พ.ศ. 2554

Digital Home Networking Book

Some parts of my researches here are appeared in the book now. :-)

http://www.iste.co.uk/index.php?f=x&ACTION=View&id=442

วันพุธที่ 28 กันยายน พ.ศ. 2554

HTTPS Java

HTTPS server on Windows
1. download "Win32 Binary including OpenSSL 0.9.8r"
(file.key = private key, file.cert = self signed certificate + public key)
3. re-config https, restart apache and verify


HTTPS client by Java
1. Since java truststore does not use the same format, then we have to convert self-signed certificate from server using this command
c:\> keytool -import -file file.cert -storepass $PASS -keystore server.keystore

2. Error:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

3. Add anonymous class :

con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});

----- java code for https client -----

import java.net.*;
import java.io.*;
import javax.net.ssl.*;

public class HttpsClient {

public static void main(String[] args) throws Exception {
System.setProperty("javax.net.ssl.trustStore", "server.keystore");
String httpsURL = "https://147.127.xxx.xx/serverCertificate";
URL myurl = new URL(httpsURL);


HttpsURLConnection con = (HttpsURLConnection) myurl.openConnection();
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
con.connect();
InputStream ins = con.getInputStream();
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader in = new BufferedReader(isr);
String inputLine;

while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}

in.close();
}
}

Note: Just use for testing, it is not suitable for real deployment.

วันอังคารที่ 27 กันยายน พ.ศ. 2554

Event Java


My Simple example with 4 classes for understanding how event and eventListener work together.

------------------------------
package myevents;
import java.util.EventObject;

public class MyEvent extends EventObject {

private static final long serialVersionUID = 5736098458773344230L;
private Object data;

public MyEvent(Object source, Object _data) {
super(source);
data = _data;
}

public Object getData() {
return data;
}
}
-------------------------------
package myevents;
import java.util.EventListener;

public interface MyEventListener extends EventListener {
public void myEventHappend(MyEvent e);
}
------------------------------
package myevents;
public class PracticalInterface implements MyEventListener {

@Override
public void myEventHappend(MyEvent e) {
System.out.println((String) e.getData());
}
}
------------------------------
package myevents;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;

public class AppProgram extends JFrame {

private Vector listeners = new Vector();
private JTextArea _tar = new JTextArea(22,40);
private JButton _bt1 = new JButton("Yeah");
private JButton _bt2 = new JButton("Yoo");

public AppProgram() {
super("Application");
setLayout(new FlowLayout());
_bt1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
shootEvent("Yeah !!");
}
});
_bt2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
shootEvent("Yoo !?");
}
});
this.add(_tar);
this.add(_bt1);
this.add(_bt2);
}

public void addListener(MyEventListener l) {
listeners.add(l);
}

public void removeListener(MyEventListener l) {
listeners.remove(l);
}

public void shootEvent(String text) {
MyEvent me = new MyEvent(this, text);
if (listeners.size() > 0) {
((MyEventListener)listeners.firstElement()).myEventHappend(me);
}
}

public static void main(String[] args) {
AppProgram app = new AppProgram();
PracticalInterface lis = new PracticalInterface();
app.addListener(lis);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setSize(400,600);
app.setVisible(true);
}

}



จาก 
http://windygallery.wordpress.com/2010/02/18/events-and-eventlistener/

วันพุธที่ 14 กันยายน พ.ศ. 2554

Keystore for TLS/SSL

create keystore (public/private key):
keytool -genkeypair -alias certificatekey -keyalg RSA -validity 7 -keystore keystore.jks

verify keystore:
keytool -list -v -keystore keystore.jks

create self signed certificate:
keytool -export -alias certificatekey -keystore keystore.jks -rfc -file selfsignedcert.cer

import certificate to trust store (public key):
keytool -import -alias certificatekey -file selfsignedcert.cer -keystore truststore.jks

verify trust store:
keytool -list -v -keystore truststore.jks


ตัวอย่าง code TLS/SSL Java

java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 EchoServer

เราสามารถใช้ option -Djavax.net.ssl.keyStore=... ใน netbeans ได้ โดยกำหนดที่ Run parameter และ ป้อนค่า options นี้ ลงไปใน VM options (ไม่ใช่ใน arguments อันนี้ สำหรับ args[] ของฟังก์ชัน main) จากนั้น ให้เก็บ file keyStore ใน project folder (parent ของ src)




วันอังคารที่ 26 กรกฎาคม พ.ศ. 2554

UML on NB 6.9

Download:

UML plugin for NB6.9

Installation Instructions:
  1. Extract the contents of the archive into your Netbeans installation directory.
  2. In your Netbeans directory you should now have a folder called UML.
  3. Restart or open Netbeans.
  4. To verify its working, try to create a new project. In the list of project types, there should be the option to create a UML project. If you have that option, then it is all working!

Usage:

  1. Open an existing Netbeans project.
  2. In the projects pane, right click on the project your working on and click Reverse Engineer.
  3. You will be presented with a window on what to reverse engineer. Choose only the source files and tell it to create a new UML project for you.
  4. It will tick away for a little while, then you should now have a new UML project in the projects pane on the left.
  5. The UML project should now be full of all the components your using.
  6. Expand your UML project, then expand the Model.
  7. You should have folders for each package thats in the Netbeans project you generated from. Example, I had one package called assign2, so i had one folder called assign2 in the UML project. Plus several other files that arent important.
  8. Right click this folder and choose Create Diagram From Selected Elements.
  9. Choose to create a Class Diagram, and push Finish.
  10. You might be prompted with a message saying: The selected element has one or more scoped elements. Do you want to include the scope elements on the diagram in addition to the selected element?
  11. Click Yes.
  12. You should now have a completed UML class diagram.

Notes:

  • The modeler does a good job of presenting the data, however it tends to push it to the right side of the window. Which wastes a lot of printing room. The only way i found to fix this, was to move every element manually to the middle. It seems the middle is the best place for printing.
  • I also couldn’t find a way to save the UML diagram as an image or a pdf. So I used Cute PDF Writer to do the job!

วันพุธที่ 13 กรกฎาคม พ.ศ. 2554

IPSec Windows XP

การ Setup IPSec บน Windows XP

การทำงานก็คล้าย ๆ กับ Windows 7 แค่สลับหมายเลข IP กัน และ ใส่ Security parameter ให้ตรงกัน เป็นอันใช้ได้ ตามรูปครับ

เริ่มต้น เปิด Run -> secpol.msc

แล้วทำตามรูปเลยครับ






















IPSec Windows7

Setup IPSec on Windows 7

วิธีการใช้งาน IPSec ระหว่าง Windows 7 และ Windows XP แบบ ง่าย ๆ
โดย กำหนด ให้ IP 147.127.240.90 (Windows7) และ 147.127.240.91 (Windows XP) โดยใช้ preshared-key ในการเข้ารหัส ทั้งส่วนของ AH และ ESP

เข้าไปที่ Local security policy โดย -> Run (Windows+R) -> secpol.msc

เริ่มสร้าง security policy ก่อน



ไม่ต้อง activate default response





IP Tunnel ใช้ในกรณีที่ ติดต่อระหว่าง IP Private กับ IP Public










กำหนด Mirrored สำหรับ การส่ง packet กลับมา





ตรงนี้สำคัญต้อง กำหนดให้เหมือนกัน ทั้ง 2 ฝั่ง


แบบ ง่ายที่สุด กำหนด preshared key


สั่ง enable IPSec


เห็น message IPSec วิ่งแล้ว เย้ :-)

วันพฤหัสบดีที่ 16 มิถุนายน พ.ศ. 2554

POJO Cooker

Pojo Cooker เป็น Data oriented framework ที่ใช้สำหรับสร้าง share data กันหลาย ๆ platform หลาย ๆ ภาษา โดยใช้ concept ของ Object XML mapping ซึ่งมีเป้าหมายหลัก ๆ ดังนี้
  • Cross-platform exchanges
  • Multi-languages
  • Multi-devices
  • Persistency layer
  • Full text search
  • Zero-conf
โครงการนี้ มีส่วนประกอบ ส่วนสำคัญ ๆ คือ Pojo, Fridge โดยที่ Pojo คือตัว โครงสร้าง XML (key/value) แล้วเราสามารถป้อน data เข้าไปเอง และ สามารถเก็บลงใน Fridge (หรือ มองว่าเก็บข้อมูลลง disk ผ่านการ persistence) นั่นเอง

Phase แรก จะเริ่มใช้งานกับ Java เป็นหลัก จากนั้น ก็จะมีส่วนที่พัฒนาของ Php, Flex, iPhone รวมไปถึง Android ด้วย ซึ่งเราสามารถ generate และ share data ผ่าน RESTlet Web framework

ส่วนสุดท้ายของโครงงานนี้คือ เราสามารถค้นหา ข้อมูลใน object (Pojo) ที่เราเก็บไว้ใน fridge ได้ ผ่านการทำงานของ Berkeley DB ซึ่งมีขนาดเล็ก และ ทำงานได้อย่างรวดเร็ว

เนื่องจากโครงการนี้ ถูก implement โดยใช้ Maven เราจึงต้องมาเริ่มติดตั้ง Maven กันก่อน ดังนี้


การติดตั้ง Maven (3 นาที)
1) ติดตั้ง maven โดย download จาก http://maven.apache.org/download.html แล้วก็ unzip ออกมา
2) กำหนด PATH ของตัวแปร ให้เรียบร้อย ตามนี้ http://maven.apache.org/download.html#Installation
3) ทดสอบดู โดยสั่ง mvn --version ถ้าเป็น version ตรงตามที่เรา download มา แสดงว่า OK. เสร็จ


หลังจากติดตั้ง Maven เรียบร้อยแล้ว ก็มาติดตั้งตัวโครงงาน



การติดตั้ง PojoCooker (1 นาที)
เพิ่ม config ตาม http://www.pojocooker.net/install.html
ใน MAVEN_HOME/conf/settings.xml

การใช้งาน PojoCooker
- mvn pojocooker:version
-
mvn pojocooker:kitchen
- cd kitchen (จะมี file pom.xml)
- 
mvn pojocooker:java
- mvn pojocooker:server

เปิด web browser เข้าไปที่ http://locahost:8080/ เป็นอันเสร็จพิธี
(อ้างอิง http://www.pojocooker.net/start.html)

การเพิ่ม Own POJO:
เข้าไปที่ .\PojoKitchen\src\main\java\org\pojocooker\demo\pojokitchen\pojos
จะมี file ที่ชื่อว่า GeoPlace.java เป็นตัวอย่างของ Pojo เราสามารถสร้าง Pojo ขึ้นใหม่ได้ โดยเลียนแบบจาก GeoPlace.java  ข้อควรระวังคือ ห้ามใช้ build-in variable type ต้องใช้ Wrapper type เท่านั้น หลังจากที่ เข้าไป define Pojo แล้ว  ให้ทำการ compile ใหม่ โดยสั่ง mvn pojocooker:java , mvn pojocooker:java ตามลำดับ
เข้าไปที่ http://localhost:8080/pojo เราจะ เห็น file POJO ที่เรา add ไว้ กดที่ 1 ใต้ XML Sample ก็จะได้ ตัวอย่าง XML เราสามารถแก้ไขข้อมูล แล้วกด save ลงใน server ได้ จากนั้น เราสามารถ search ข้อมูลที่เรา add ไว้ (ได้ผลลัพธ์เป็น XML) และ สามารถใช้ ID ของ object จะส่ง output เป็น XML มาให้ ตาม ID ของ object ที่เราต้องการหา

วิธีลบ Own Pojo
mvn pojocooker:clear (เพื่อทำการลบ java source files ออก)
mvn clear  (เพื่อลบ class file ออก)  
 แล้วจึงสั่ง recompile ใหม่ ด้วย mvn pojocooker:java 

สรุป
คิดว่า framework นี้ ออกแบบมาให้ share XML data ผ่าน
RESTlet web framework (XML output)