Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

JavaのSSLSocketでSSLクライアントとSSLサーバーを実装する

JSSEを利用した簡単なSSLサーバー/クライアントの実装例

  • LINEで送る
  • このエントリーをはてなブックマークに追加

インターネットを利用した商取引に、SSLを利用したセキュリティの確保はかかせません。本稿では、J2SE1.4から標準で用意されたJSSE(Java Secure Socket Extension)のAPIを利用した簡単なSSLサーバー/クライアントの実装例を紹介します。

はじめに

 企業間の受発注取引をインターネットを利用して行うB2B(企業間電子商取引)も、ロゼッタネットをはじめとして、ここ数年で導入が活発化してきています。B2Bシステムを構築する際に欠かせないのがセキュリティの確保であり、セキュリティインフラの中心となるのがSSL(Secure Socket Layer)です。本記事では、J2SE1.4から標準で用意されたJSSE(Java Secure Socket Extension)のAPIを利用した簡単なSSLサーバー/クライアントの実装例を紹介します。

対象読者

 Javaプログラミングを行ったことがある方を対象とします。

必要な環境

 サンプルは以下の環境で動作確認を行っています。

SSLについて

 SSLは、ネットワークを通じたデータ送信時にデータの機密性および整合性を保護するために設計されたプロトコルです。SSLは、Netscape Communications社によって開発されました。またSSL3.0に若干の改良を加えて考案されたプロトコルとしてTLS(Transport Layer Security)があります。TLSはRFC2246としてIETF(Internet Engineering Task Force)で標準化が行われています。

JSSEについて

 JSSEはSSL(Secure Socket Layer)、TLS(Transport Layer Security)の機能提供を目的としたAPIおよび実装です。JSSEでは、SSL・TLSの基盤となる複雑なセキュリティアルゴリズムや「ハンドシェイク」機構を抽象化していますので、開発者はセキュアな通信を使用したアプリケーションを容易に実装する事ができます。J2SE1.2とJ2SE1.3ではオプショナルパッケージという位置付けでしたが、J2SE1.4からは標準APIとして提供されています。

 JSSEのパッケージ・主なクラス・インターフェース群を以下の表に示します。

JSSEのパッケージ構成
パッケージ名説明主な構成クラス・インターフェース
java.securityセキュリティフレームワークのクラスとインターフェースを提供PrivateKey、PublicKey、KeyPair、KeyStore、Signature など
java.security.aclこのパッケージの変わりにjava.securityのクラスが使われるようになった-
java.security.cert証明書、証明書の取り消しリスト(CRL)、証明書パスを解析および管理するためのクラスとインタフェースを提供CRL、X509Certificate、X509CRLなど
java.security.interfacesRSA Laboratory Technical Note PKCS#1で定義されているRSA鍵、およびNISTのFIPS-186で定義されているDSA鍵を生成するためのインタフェースを提供。DSAKey、DSAKeyPairGenerator、RSAKey、RSAKeyGeneratorなど
java.security.spec鍵仕様およびアルゴリズムパラメータ仕様のクラスおよびインタフェースを提供。AlgorithmParameterSpec、KeySpec、PKCS8EncodedKeySpec、 RSAKeyGenParameterSpecなど
javax.net.sslセキュアソケットパッケージのクラスを提供SSLSession、SSLSessionContext、TrustManager、HttpsURLConnection、 KeyManagerFactory、SSLContext、SSLServerSocket、SSLSocket、 SSLSocketFactory、TrustManagerFactoryなど

 JSSEでは、上記表のようにSSLの技術構成要素がクラス・インターフェースとして用意されています。SSL通信をする際には、javax.net.sslのクラス群を用いて接続を確立します。

サンプルの全体図

 本稿のサンプル構成を以下の図に示します。

 上記の図の用語について簡単に説明します。

サンプル全体図の用語
用語説明
トラストストア自らが信頼するCA(Certificate Authority:認証局)のルート証明書または中間証明書を保存する場所(ファイル)です。JSSEのプロバイダは、SSLの通信先がサーバー証明書を送信してきた際に、トラストストアに保存されている証明書によって署名がなされているかどうかによって認証の可否を判断します。
キーストア自らのサーバー証明書を保存する場所をいいます。JKS(Java Key Store)の場合、サーバー証明書をインストールする前に、その上位のルート証明書・中間証明書も共にインストールする必要があります。これによって証明書のチェーン(ルート証明書、中間証明書、サーバー証明書の連鎖)をSSLの通信先に送信する事が可能になります。

 本記事のサンプルでは、サーバー側に証明書をインストールするだけではなく、クライアント側にも証明書をインストールします。クライアント側にも証明書をインストールし、サーバーとクライアントでお互いに認証しあう事で、よりセキュリティ性の高いシステムを構築する事ができます。

 なおサンプルに使用するサーバー証明書は、クライアント側は、日本ベリサイン社のトライアルサーバIDサービスによるサーバー証明書、そしてサーバー側は、ビートラステッド・ジャパン株式会社のトライアル証明書発行サービスをそれぞれ使用します。ビートラステッド社のトライアルサーバー証明書は、ルート証明書・中間証明書・サーバー証明書と3層構造の連鎖となっていますのでより実践的な動作確認が可能となります。

PKI(Public Key Infrastructure)について

 SSLは、PKI(Public Key Infrastructure)というセキュリティ基盤の中で用いられます。PKIでは、サーバーにただ1つだけ存在する秘密鍵と、サーバー証明書と共に配布される公開鍵という2つの鍵から成り立ちます。公開鍵で暗号化されたデータは対となる秘密鍵でしか複合化できません。また秘密鍵で暗号化されたデータは対となる公開鍵でしか複合化できません。PKIはこれらの性質を利用してデータの機密性を実現しています。PKIの詳細な説明については、本稿の最後に記載されている参考資料等を参照して下さい。

SSL通信環境構築までの手順概要

 クライアント認証を行うSSL通信環境を構築するには、2つの証明書ストア(キーストア--自らの証明書を保存、トラストストア--信頼するCAが発行した証明書を保存)を構築する必要があります。

キーストア構築

 キーストアに保存するサーバー証明書は通常、以下の手順で用意します。

  1. キーペア作成(秘密鍵・公開鍵)
  2. CSR(Certificate Signing Request:証明書要求)の作成
  3. CA(Certificate Authority:認証局)へのCSRの提出
  4. CA(Certificate Authority:認証局)によるサーバー証明書の発行
  5. キーストアにサーバー証明書をインポート

トラストストア構築

 トラストストアには、CAが発行したルート証明書・中間証明書など自らが信頼する証明書が保存されます。SunのJDKの場合、「$JAVA_HOME/jre/lib/security/cacerts」ファイルが標準で用意されています。本記事ではベリサイン社、ビートラステッド社が提供するトライアル用ルート証明書・中間証明書をトラストストアにインポートします。

keytoolについて

 本記事では、秘密鍵作成・証明書のインポートなどサーバー証明書に関する操作をJDK付属の「keytool」で行います。

 keytool実行時には、キーペア作成、CSR作成、証明書のインポート・エクスポートなどの実行したい動作を、オプションで指定します。以下にそのオプションを示します。

keytoolのオプション(keytoolの動作モードを指定)
オプション説明
-genkeyキーペアを生成
-certreqCSR(Certificate Signing Request:証明書要求)を作成
-import証明書をインポート
-export証明書をエクスポート
-delete証明書エントリー削除
-list証明書エントリーの一覧表示

 次に各動作モードで共通して使用するオプションを示します。

keytoolのオプション(各動作モード共通オプション)
オプション説明
-alias証明書・鍵をキーストア内で識別する名前。
-keystoreキーストアのファイル名。省略した場合は、「home」ディレクトリの「.keystore」ファイル。
-storetypeキーストアの実装タイプ。省略した場合はJKS(=Java Key Store。Sun が提供する独自タイプのキーストア実装)。
-storepassキーストアのパスワード。

 各動作モードごとに異なるオプション指定は、次節の「サーバー側環境の構築」で説明します。

サーバー側環境の構築

 それでは、まずサーバー側の環境を構築します。コマンドはソースコード内の、「server」フォルダ直下で、実行します。

キーストア構築

 自らの証明書を保存するキーストアを構築します。ファイル名は「server_keystore」とします。

(1)キーペア作成(秘密鍵・公開鍵)

 最初のステップはキーペアの作成です。ここではJDKに標準で添付されているkeytoolというツールを使用して作成します。opensslなどのツールを使っても同様に作成できます。

keytool -genkey -alias ssltest -keyalg RSA -keysize 512
 -keypass changeit -validity 365 -storetype JKS
 -keystore server_keystore -storepass changeit

 以下の表に「-genkey」実行時に使用するオプションを示します。

keytoolのオプション(-genkeyオプション指定時)
オプション説明
-keyalg秘密鍵・公開鍵作成時の暗号方式。省略時した場合はDSA(Digital Signature Algorithm)。
-keysize秘密鍵・公開鍵のサイズ。省略した場合は1024。
-keypass秘密鍵のパスワード。
-validity証明書の有効日数。省略した場合は90。

 「-genkey」オプションでkeytoolコマンドを実行すると、画面上のプロンプトでキーペア作成に必要な各種パラメータの入力を順に求められるので画面上で入力します。

サーバー側キーペア作成時の入力パラメータ
項目名(日本語)名称(英語)入力値説明
姓名CN(Common Name)sslserver.wings.msn.toホスト名を入力。SSLの認証処理で使用される。
組織単位名OU(Organization Unit)Codezine任意の部署名を入力。
組織名O(Organization)Wings Project任意の組織名を入力。
都市名または地域名L(Locality)Chiba任意の都道府県名を入力。
州名または地方名ST(State)Kamagaya任意の都市名を入力。
2文字の国番号C(Country)JP日本の場合、JP。

 なお、これらの値は、keytool実行時に

-dname "cn=sslserver.wings.msn.to, ou=Codezine, o=Wings Project, c=JP"

 とDN(Distinguished Name:識別名)形式であらかじめオプション指定する事も可能です。

(2)CSR(Certificate Signing Request:証明書要求)の作成

keytool -certreq -alias ssltest -file ssl_server.csr
 -keystore server_keystore -storetype JKS -storepass changeit
 -keypass changeit

 CSRとは、CA(認証局)に証明書を発行してもらう為に、サーバーの情報を格納したデータです。CAはCSRに格納された情報をもとにサーバー証明書を発行します。

CSRの中身

 作成されたCSRファイルのデータは、以下のようにテキストで参照できるBase64エンコーディング形式と記述されます。

-----BEGIN NEW CERTIFICATE REQUEST-----
MIIBszCCARwCAQAwczELMAkGA1UEBhMCanAxDzANBgNVBAgTBkFkYWNoaTEOMAwGA1UE
BxMFVG9reW8xFTATBgNVBAoTDHRvLm1zbi53aW5nczEXMBUGA1UECxMOV2luZ3MgQ29k
ZXppbmUxEzARBgNVBAMTCkhhcnVvIFNhdG8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAMmzT+uHOwq/zkvAcpfKiyv6Y4DUwT9ZJP2cTSOCHkEeGKJFEwc9jjTYZYoQFAR3
O7HD/9EgT1ia4PMyVS0257aAM+HP5ET0R/oZOwe2LgufoEOGfLEOTAGJghRvWX/LYU/G
suxr3Hb+rb3DGH5cBXSxlQyF7Y1EwuQ0Q1nRImofAgMBAAGgADANBgkqhkiG9w0BAQQF
AAOBgQBJ9g230J+33Ms3BjV3t9OJgl9ypJbC2KJOFXSeVuXQdeS81Up6SpQjNlJh7pD7
kzGw8fjnSer1vF/pQ1YHUJN2fdZgCPZS53Nf9HGbaEeEY+7B3t1SGdeV7g21pTxwkgOb
x30+JkgKpFAuAG9xjGDnBuXy/9uLSM0PBXCjuwXrYQ==
-----END NEW CERTIFICATE REQUEST-----

(3)認証局へのCSR(証明書要求)の提出

 作成したCSRファイルをテキストエディタで開き、ビートラステッド社のトライアル証明書発行サービスのWeb画面の入力フォームに貼り付けます。

(4)サーバー証明書の取得

 Web画面上にBase64エンコーディングのテキスト形式で証明書が表示されるので(ビートラステッド社の場合)、コピーし、任意のファイル名でローカルに保存します。ここではファイル名を「ssl_server.cer」とします。また、証明書以外にCAのルート証明書、中間証明書を入手し、ローカルに保存します。それぞれ「betrusted_root_ca.cer」「betrusted_ca.cer」というファイル名で保存します。

(5)サーバー証明書インポート(証明書連鎖の構築)

 CAによって発行された証明書をキーストアに保存します。ポイントは、-trustcacerts オプションを使用して証明書連鎖を構築することと、証明書をインポートする際に、秘密鍵を生成した際のalias名と同一の名前を指定する事です。証明書連鎖を構築すると、証明書をクライアントに送信する際に連鎖している証明書も送信されます(SSLサーバーの実装によってはルート証明書も送信されますが、TLSの仕様では必須ではありません)。証明書は、ルート証明書→中間証明書→サーバー証明書の順でインポートします。

keytoolのオプション(-importオプション指定時)
オプション説明
-trustcacerts指定した場合証明書連鎖を構築してインポートする
  • ルート証明書
  • keytool -import -alias betrusted_root_ca -file
     betrusted_root_ca.cer -keystore server_keystore
     -trustcacerts -storetype JKS -keypass changeit
     -storepass changeit
    
  • 中間証明書
  • keytool -import -alias betrusted_ca -file betrusted_ca.cer
     -keystore server_keystore -trustcacerts -storetype JKS
     -keypass changeit  -storepass changeit
    
  • 証明書
  • keytool -import -alias ssltest -file ssl_server.cer -keystore
     server_keystore -trustcacerts -storetype JKS
     -keypass changeit  -storepass changeit
    

トラストストア構築

ルート証明書インポート

 当サンプルでは、クライアント認証を使用しますので、クライアント側証明書の発行者となるベリサイン社のルート証明書をサーバー側にインポートします。これにより、ベリサイン社のルート証明書の署名がなされている証明書はサーバー側で信頼されます。

 トラストストアのファイル名は「server_cacerts」とします。

keytool -import -alias verisign_root_ca -file verisign_root_ca.cer
 -keystore server_cacerts -storetype JKS -keypass changeit
 -storepass changeit

クライアント側環境の構築

 次にクライアント側の環境を構築します。コマンドはソースコード内の、「client」フォルダ直下で、実行します。

キーストア構築

 自らの証明書を保存するキーストアを構築します。ファイル名は「client_keystore」とします。

(1)キーペア作成

keytool -genkey -alias client_cer -keyalg RSA -keysize 512
 -keypass changeit -validity 365 -storetype JKS
 -keystore client_keystore -storepass changeit -v
クライアント側キーペア作成時の入力パラメータ
姓名sslclient.wings.msn.to
組織単位名Codezine
組織名Wings Project
都市名または地域名Chiba
州名または地方名Kamagaya
2文字の国番号JP

(2)CSR(Certificate Signing Request:証明書要求)の作成

keytool -certreq -alias client_cer -file
 client.csr -keypass changeit -storetype JKS -keystore
 client_keystore -storepass changeit

(3)認証局へのCSR(証明書要求)の提出

 作成したCSRファイルをテキストエディタで開き、ベリサイン社のトライアル証明書発行サービスのWeb画面の入力フォームに貼り付けます。

(4)サーバー証明書の取得

 ベリサイン社トライアルサーバー証明書申し込み時にWeb画面で入力したメールアドレス宛てに、サーバー証明書のテキストが送信されて来ます。その証明書部分のテキスト(Base64エンコーディング形式)をコピーしてローカルに保存します。ここではファイル名を「client.cer」とします。

(5)証明書のインポート

  1. テスト用ルート証明書
  2. ベリサイン社のテスト用ルート証明書をキーストアにインポートします。
    keytool -import -alias verisign_root_ca -file
     verisign_root_ca.cer -keypass changeit -trustcacerts
     -storetype JKS -keystore client_keystore -storepass changeit
    
  3. サーバー証明書
  4. ベリサイン社が発行したトライアルサーバー証明書をキーストアにインポートします。その際、「-trustcacerts」オプションで証明書連鎖を構築します。
    keytool -import -alias client_cer -file client.cer -keypass
     changeit -trustcacerts -storetype JKS -keystore
     client_keystore -storepass changeit -v
    

トラストストア構築

 ビートラステッド社のルート証明書をインポートします。これによりビートラステッド社ルート証明書の署名が成されている証明書は信頼されます。

(1)ルート証明書のインポート

keytool -import -alias betrusted_root_ca -file
 betrusted_root_ca.cer -keypass changeit -storetype JKS
 -keystore client_cacerts -storepass changeit

 以上でクライアント認証を用いたSSL通信の環境が整いました。ではいよいよ次にSSL接続を行うサンプルコードをみてみましょう。

SSLサーバー、SSLクライアントの実装

サーバー側ソースコード

「SSLServer.java」 抜粋1
System.setProperty("javax.net.ssl.trustStore" , trustStore );
System.setProperty("javax.net.ssl.trustStorePassword",
    props.getProperty( "ssl.trustStore.password" ) );

 トラストストア用のシステム環境変数を設定しています。証明書認証処理時にこの値に指定されたファイル名・パスワードを使用してサーバー証明書が認証されます。

「SSLServer.java」 抜粋2
// KeyStoreのロード
KeyStore ks = KeyStore.getInstance( "JKS" );

char[] keystorePass = props.getProperty( "ssl.keyStore.password" )
    .toCharArray();
ks.load( new FileInputStream( keyStore ) , keystorePass );

KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
kmf.init( ks, keystorePass );

SSLContext sslContext = SSLContext.getInstance( "TLS" );
sslContext.init( kmf.getKeyManagers() , null , null );
ServerSocketFactory ssf = sslContext.getServerSocketFactory();

// サーバーソケット生成
ServerSocket srvSocket  = ssf.createServerSocket( port );

// クライアント認証設定
String clientAuth = props.getProperty( "client.auth" );
if ( Boolean.valueOf(clientAuth).booleanValue() ){
    ((SSLServerSocket)(srvSocket)).setNeedClientAuth( true );    
}

 自らのサーバー証明書を保存しているキーストアをロードして、SSLのサーバー側ソケットを作成しています。プロパティファイルによってクライアント認証を行うか否かを設定しています。

「SSLServer.java」 抜粋3
// 無限ループで待機
while( true ){
    System.out.println( "--------------------------------------" );
    System.out.println( "SSL接続を待機しています。" );
    // クライアントからの接続待ちの状態に入る
    Socket client = srvSocket.accept(); 
    System.out.println( "Clientから接続されました。" );
    
    in  = new BufferedReader( 
        new InputStreamReader ( client.getInputStream() ) );
    out = new BufferedWriter( 
        new OutputStreamWriter( client.getOutputStream() ) );
    
    String msg = in.readLine();
    
    System.out.println("★★★Clientからのメッセージ:" + msg );
    out.write( "Hello Client\n" );  // クライアントに文字列送信
    out.flush();
    closeReader( in );
    closeWriter( out );
}

 無限ループによって、クライアント側からの接続を待機する状態をつくっています。クライアントからの接続を受け付けるとクライアントから送信されたデータを読み込み、標準出力に出力しています。その後、クライアントに文字列「Hello Client」を送信しています。なお、本記事のサーバー側実装は複数クライアントからの接続には対応していません。複数クライアントからの接続に対応するにはマルチスレッドを使って複数のソケットを待機させる必要があります。

送信側(クライアント側)ソースコード

「SSLClient.java」 抜粋1
// トラストストア設定
System.setProperty("javax.net.ssl.trustStore" , trustStore );
System.setProperty("javax.net.ssl.trustStorePassword",
    props.getProperty( "ssl.trustStore.password" ) );

 トラストストア用のシステム環境変数を設定しています。証明書認証処理時にこの値に指定されたトラストストアファイルを使用してサーバー側から送信されたサーバー証明書が認証されます。

「SSLClient.java」 抜粋2
// キーストアロード
KeyStore ks = KeyStore.getInstance ( "JKS" );
char[] keystorePass =
    props.getProperty( "ssl.keyStore.password" ).toCharArray();
ks.load ( new FileInputStream( keyStore ) , keystorePass );

KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
kmf.init( ks , keystorePass  );
SSLContext ctx = SSLContext.getInstance ( "TLS" );
ctx.init( kmf.getKeyManagers() , null , null );

// SSLSocket生成
SSLSocketFactory factory  = ctx.getSocketFactory();
s = (SSLSocket)factory.createSocket( serverHost , port );

 Javaのキーストアをロードして、SSLのクライアント側ソケットを作成しています。

「SSLClient.java」 抜粋3
// ハンドシェイク
s.startHandshake();

// サーバーからの入力を読み込み、標準出力に出力
out = new PrintWriter( s.getOutputStream() );
in  = new BufferedReader(
    new InputStreamReader(s.getInputStream() ) );

out.write( "Hello Server\n" ); // サーバーへ送信する文字列
out.flush();
// サーバーから受けとった文字列の読み込み
String answer = in.readLine();
System.out.println("★★★サーバーからのメッセージ:" + answer );

 SSLのハンドシェイクを実行しています。ハンドシェイクで認証が成立しなかった場合は、例外が発生します。ハンドシェイクの結果、認証された場合はサーバー側に文字列「Hello Server」を送信しています。その後サーバーから受け取った文字列を標準出力に出力しています。

実行準備

「hosts」ファイル編集

 本稿で使用した「sslserver.msn.wings.to」「sslclient.msn.wings.to」というホスト名は、テスト用のホスト名なので実在しません。名前解決ができるよう「hosts」ファイルに記述します。

  • (Win2000の場合)
  • 「C:\WINNT\SYSTEM32\DRIVERS\ETC\HOSTS」
  • (WinXPの場合)
  • 「C:\WINDOWS\system32\drivers\etc\hosts」

 以下のように記述します。

127.0.0.1       sslserver.wings.msn.to
127.0.0.1       sslclient.wings.msn.to

デバッグモードの設定

 SSLのデバッグ出力を行いたい場合、「conf」ディレクトリにある「client.properties」ファイルと「server.properties」ファイルの「ssl.debug」プロパティをtrueに設定します。この設定により、「javax.net.debug=all」という環境変数が設定され、JDKがSSLのデバッグ文字列を出力します。

実行

  1. SSLサーバーの起動
  2. server_start.bat
    
  3. SSLクライアントの実行
  4. client_start.bat
    
    正しく実行されれば、クライアント側を実行した際に、サーバー側、クライアント側に通信相手が送信した文字列が表示されます。
インターネットによる電子商取引時の脅威
 インターネット上の電子商取引を行う際には様々な脅威がありますが、SSLを用いたからといって、それらが完全に防止できるという訳ではありません。以下の表にインターネット上の脅威とそれぞれの防衛手段を示します。これらの脅威のうち、SSLで防ぐ事ができるのは「盗聴」と「なりすまし」です。ファイアーウォール、ディジタル署名などをあわせたソリューションを用いる事でセキュリティレベルをより上げる事が可能となります。
インターネット上の脅威と防衛手段
脅威の種類説明防衛手段
盗聴ネットワークの途中で第三者がデータを盗み取るSSLによる暗号化
なりすましサーバー名を偽りデータをアクセスさせるSSLによる認証
不正アクセスサーバーにアタックをかけるファイアーウォール
改ざん改変したデータを送信するディジタル署名
否認自分が送ったデータを送ったと認めない事ディジタル署名

まとめ

 本稿では、JDKの標準APIであるJSSEを使用して、SSL通信を実行する例を紹介しました。現代のエンジニアにとってセキュリティの知識は必須となってきていますが、SSLについてはやや敷居が高く、取っ付きにくいのも確かです。本記事がSSL環境の構築に初めて取り組むエンジニアの方の一助となれば幸いです。

参考資料

  1. @IT 5分で絶対にわかるPKI
  2. @IT 連載PKI基礎講座
  3. 「SSLサーバーの構築」暗号技術とSSL AI出版
  4. J2SE1.4 API Document
  5. J2SE5.0 API Document
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 佐藤 治夫 (株式会社ビープラウド)(サトウ ハルオ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5