2008年2月1日金曜日

DB2 v8.2 メモリをチューニングする

貧弱な開発環境向けに、CMのDB2のメモリ使用率を下げます。
@IT DB2チューニング・ベストプラクティス(2)を参考にすると、DB2のグローバルメモリ使用率は以下の計算式で概算がでるようです。
バッファ・プール+dbheap+util_heap_sz+pckcachesz+aslheapsz+locklist+約10%のオーバーヘッド
※太字部分は@ITのサイトに誤植(pkgcachsz)がありました。

当方の環境(icmnlsdb)で調べて見ると、以下の通りでした。
(icmnlsdbに接続します)
db2inst1@ホスト名 [sql/] $ grep -v ^-- sys.sql
select substr(bpname,1,20),npages,pagesize from syscat.bufferpools
db2inst1@ホスト名 [sql/] $ db2 -f sys.sql

1 NPAGES PAGESIZE
-------------------- ----------- -----------
IBMDEFAULTBP 1000 4096
ICMLSFREQBP4 1000 4096
ICMLSVOLATILEBP4 8000 4096
ICMLSMAINBP32 8000 32768
CMBMAIN4 1000 4096

5 レコードが選択されました。

db2inst1@ホスト名 [sql/] $ db2 get db cfg | egrep -i '(util_heap|dbheap|pckcache|aslheapsz|locklist)'
データベース・ヒープ (4KB) (DBHEAP) = 2400
ユーティリティー・ヒープ・サイズ (4KB) (UTIL_HEAP_SZ) = 5000
ロック・リスト用最大ストレージ (4KB) (LOCKLIST) = 1000
パッケージ・キャッシュ・サイズ (4KB) (PCKCACHESZ) = (MAXAPPLS*8)
db2inst1@ホスト名 [sql/] $ db2 get dbm cfg | egrep -i '(util_heap|dbheap|pckcache|aslheapsz|locklist)'
アプリケーション・サポート層ヒープ・サイズ (4KB) (ASLHEAPSZ) = 15

ざっくり計算すると、以下のような感じです。
a. バッファプール:(上から)4MB + 4MB + 32MB + 250MB + 4MB = 約300MB
b. DBヒープ:8MB
c. UTILヒープ:20MB
d. ロックリスト:4MB
e. アプリヒープ:60K
効きそうなのは、順に「250MBのバッファプール」>「32MBのバッファプール」>「20MBのUTILヒープ」のようです。他は無視しましょう。
では、各サイズを変更します。ALTER BUFFERPOOLコマンドとUPDATE DB CFGコマンドを使います。
db2inst1@ホスト名 [sql/] $ grep -v ^-- sys.sql
alter bufferpool ICMLSVOLATILEBP4 size 2000 -- 8000
alter bufferpool ICMLSMAINBP32 size 2000 -- 8000
update db cfg using UTIL_HEAP_SZ 2000
db2inst1@ホスト名 [sql/] $ db2 -f sys.sql
DB20000I SQL コマンドが正常に終了しました。

DB20000I SQL コマンドが正常に終了しました。

DB20000I UPDATE DATABASE CONFIGURATION コマンドが正常に終了しました。

db2inst1@ホスト名 [sql/] $ db2 -f sys.sql

1 NPAGES PAGESIZE
-------------------- ----------- -----------
IBMDEFAULTBP 1000 4096
ICMLSFREQBP4 1000 4096
ICMLSVOLATILEBP4 2000 4096
ICMLSMAINBP32 2000 32768
CMBMAIN4 1000 4096

5 レコードが選択されました。
db2inst1@ホスト名 [sql/] $ db2 get db cfg | egrep -i '(util_heap|dbheap|pckcache|aslheapsz|locklist)'
データベース・ヒープ (4KB) (DBHEAP) = 2400
ユーティリティー・ヒープ・サイズ (4KB) (UTIL_HEAP_SZ) = 2000
ロック・リスト用最大ストレージ (4KB) (LOCKLIST) = 1000
パッケージ・キャッシュ・サイズ (4KB) (PCKCACHESZ) = (MAXAPPLS*8)
(念のためDBを再起動します)

以上です。

DB2 v8.2 循環ロギングを設定する

定義

ここでは、データベースへの変更が記録されたファイルをログと呼びます。
(情報やイベントやエラー情報を書き出すログではありません。)
ログには複数種類(後述)があり、ラッシュリカバリー、ロールフォワードやロールバックに使われるものです。

DB2では、ログの状態によって用語を区別しています。

a. アクティブログ 
今まさに使っているログです。commit前の情報が含まれます。DBがクラッシュしたときに直前の状態に戻すために使われます。これがないとDBは復帰できません。このタスクで扱う対象ではありません。

b. オンライン・アーカイブログ
commit済みのログです。DBの起動/稼働には不要で、ロールフォワードやロールバックに使います。

c. オフライン・アーカイブログ
[b.]のログを管理のため別の場所に移したもの。あくまで運用の観点からの差異であり、ログの観点で言えば[b.]と同じです。DB2は、[b.]が一杯になったときに、ログを退避する機能を持っています。退避されたログを便宜的に「オフライン・アーカイブ」と呼びます。(異なる切り口での用語を混在させることは、話をややこしくするだけですね。)

b.-1 一次ログ、二次ログ
オンライン・アーカイブログに一次ログと二次ログというパラメータを指定することができます。一次ログに割り当てた分が溢れると、二次ログに移る、という仕組みのようです。(これも話をややこしくしているだけのような気がします。)今のタスクでは意識する必要はありません。

放置されることが多い開発環境では、アーカイブログ(b. c. d.)を設定しておくと、ログが満タンになってしまうことがままあります。循環ログを指定してログが増えつづけないように設定することで、ログ溢れによるアプリケーションの停止を回避できます。

ちなみにDB2のデフォルトは循環ログです。

手順概要

a. DBに接続します。

b. 以下のパラメータを変更します。
LOGRETAIN=NO  (デフォルト)
USEREXIT=NO (デフォルト)
LOGARCHMETH1=OFF (デフォルト)
LOGARCHMETH2=OFF (デフォルト)

c. DB2を再起動します。

手順例
db2inst1@ホスト名 [sql/] $ db2 connect to icmnlsdb

データベース接続情報

データベース・サーバー = DB2/6000 8.2.7
SQL 許可 ID = DB2INST1
ローカル・データベース別名 = ICMNLSDB

db2inst1@ホスト名 [sql/] $ db2 -f sys.sql | egrep -i '(logretain|userexit|logarchmeth)'
リカバリー用ログの保持使用可能 (LOGRETAIN) = RECOVERY
ロギング用ユーザー出口使用可能 (USEREXIT) = OFF
第 1 ログ・アーカイブ・メソッド (LOGARCHMETH1) = DISK:/cm/lsdb/archive_log/
logarchmeth1 のオプション (LOGARCHOPT1) =
第 2 ログ・アーカイブ・メソッド (LOGARCHMETH2) = OFF
logarchmeth2 のオプション (LOGARCHOPT2) =

db2inst1@ホスト名 [sql/] $ grep -v ^-- sys.sql
update db cfg using logretain NO
update db cfg using userexit NO
update db cfg using logarchmeth1 OFF
update db cfg using logarchmeth2 OFF
db2inst1@ホスト名 [sql/] $ db2 -f sys.sql
DB20000I UPDATE DATABASE CONFIGURATION コマンドが正常に終了しました。
SQL1363W 即時変更のためにサブミットされた 1
つ以上のパラメーターが動的に変更されませんでした。
これらの構成パラメーターでは、変更を有効にする前にすべてのアプリケーションをこの
データベースから切断する必要があります。

DB20000I UPDATE DATABASE CONFIGURATION コマンドが正常に終了しました。
SQL1363W 即時変更のためにサブミットされた 1
つ以上のパラメーターが動的に変更されませんでした。
これらの構成パラメーターでは、変更を有効にする前にすべてのアプリケーションをこの
データベースから切断する必要があります。

DB20000I UPDATE DATABASE CONFIGURATION コマンドが正常に終了しました。
SQL1363W 即時変更のためにサブミットされた 1
つ以上のパラメーターが動的に変更されませんでした。
これらの構成パラメーターでは、変更を有効にする前にすべてのアプリケーションをこの
データベースから切断する必要があります。

DB20000I UPDATE DATABASE CONFIGURATION コマンドが正常に終了しました。

db2inst1@ホスト名 [sql/] $ db2stop
2008-02-01 10:27:12 0 0 SQL1025N データベースがまだアクティブになっているために、データベース・マネー
ジャーが停止されませんでした。
SQL1025N データベースがまだアクティブになっているために、データベース・マネージャーが停止されませんでした。
db2inst1@ホスト名 [sql/] $ db2 force application all
DB20000I FORCE APPLICATION コマンドが正常に終了しました。
DB21024I このコマンドは非同期であり、即時に有効にならない場合もあります。

db2inst1@ホスト名 [sql/] $ db2stop
db2inst1@ホスト名 [sql/] $ db2start
2008-02-01 10:28:01 0 0 SQL1063N DB2START の処理が正常に終了しました。
SQL1063N DB2START の処理が正常に終了しました。
db2inst1@ホスト名 [sql/] $ db2 connect to icmnlsdb
db2inst1@ホスト名 [sql/] $ db2 -f sys.sql | egrep -i '(logretain|userexit|logarchmeth)'
リカバリー用ログの保持使用可能 (LOGRETAIN) = OFF
ロギング用ユーザー出口使用可能 (USEREXIT) = OFF
第 1 ログ・アーカイブ・メソッド (LOGARCHMETH1) = OFF
logarchmeth1 のオプション (LOGARCHOPT1) =
第 2 ログ・アーカイブ・メソッド (LOGARCHMETH2) = OFF
logarchmeth2 のオプション (LOGARCHOPT2) =

2008年1月31日木曜日

文字列置換ツール(無保証)

文字列置換ツールを作成しました。
時折必要性を感じるのですが、その場でさっさと作るには難しいシェルです。
かといって胸を張って公開できるようなツールでもありませんが。

当ツールは完全無保証です。ファイルが壊れるかもしれません。脅しではありません。バイナリファイルは、例え検索結果にマッチしなくても、無条件に破壊します。注意して使ってください。

私的なメモとして貼っておきます。
#!/bin/ksh
trgt_dir=$1
trgt_ext=$2
str_search=$3
str_replace=$4
self=`basename $0`
USED=0
use_parcent=0
use_slash=0

w_list_file=/tmp/tmp.$$.dirlist
w_tmp_file=/tmp/tmp.$$.aft

usage() {
echo "$self [PATH] [対象拡張子] [検索文字列] [置換文字列]"
echo "注意:バイナリファイルは破壊されます。"
echo "注意:'/'と'%'を同時に使うことはできません。"
}

# 引数チェック
if (( $# <= 2 )); then
usage;
return 0
fi

if [[ ! -d $trgt_dir ]]; then
echo "第一引数が有効なディレクトリではありません";
usage
return 1
fi

# sedで使う'/'あるいは'%'が含まれないことを確認。
echo $str_search $str_replace | grep '/' > /dev/null 2>&1
use_slash=$?
echo $str_search $str_replace | grep '%' > /dev/null 2>&1
use_percent=$?

if (( $use_slash == $USED && $use_percent == $USED )); then
echo "'/'と'%'を同時に使うことはできません。"
return 1
fi
echo "警告> ファイルのタイムスタンプは全て現在の時間に更新されます。"
if (( $# == 3 )); then
echo "警告> 置換文字列が指定されていません。"
echo "警告> 文字列[$str_search]をファイルから削除しますがよろしいですか?[Y/y] : "
read input
if [[ $input != "Y" && $input != "y" ]]; then
echo "終了します"
return 0
fi
fi

echo "警告> ${trgt_dir}/ にある *.${trgt_ext} がバイナリファイルであれば、"
echo "警告> *.${trgt_ext} は問答無用で破壊されます。よろしいですか?[Y/y]"
read input
if [[ $input != "Y" && $input != "y" ]]; then
echo "終了します"
return 0
fi
echo "警告> 本当に?[Y/y]"
read input
if [[ $input != "Y" && $input != "y" ]]; then
echo "終了します"
return 0
fi

ls -l $trgt_dir | grep -v $self | grep ^- | grep \.${trgt_ext}$ |
awk -vDIR=${trgt_dir} '{print DIR"/"$NF}' > $w_list_file

while read trgt_file
do
if (( $use_slash == $USED )); then
cat $trgt_file | sed "s%${str_search}%${str_replace}%g" > $w_tmp_file
else
cat $trgt_file | sed "s/${str_search}/${str_replace}/g" > $w_tmp_file
fi
mv $w_tmp_file $trgt_file
echo "$trgt_file を処理しました。"
done < $w_list_file

rm $w_list_file

2008年1月30日水曜日

awkに外から変数を渡す

これも基本だと思いますが、よく忘れるので・・・
awk -vVAR=VALUE '{print VAR}'

です。# 方言はあるのでしょうか?AIX5.2とcygwinのGNU Awk 3.1.5で動きました。
root:/tmp # echo a | awk -vhoge=${PWD} '{print $1,hoge}'
a /tmp

2008年1月28日月曜日

DB2 EVENT MONITOR FOR STATEMENTS を使ってみる

イベントモニター開始
create event monitor sql_evmon1 for statements write to file \
'/home/db2inst1/sql_evmon1' maxfiles 3 maxfilesize 1000
set event monitor sql_evmon1 state=1

※ディレクトリのパス名が間違っていると、2つ目のコマンド(3行目)でエラーが出ます。

SQLを実行します。

イベントモニター終了
flush event monitor sql_evmon1 buffer
set event monitor sql_evmon1 state=0


イベントモニターの結果確認
db2evmon -path ./sql_evmon1


※CMで実行してみましたが、コンテンツを一つ登録するのに相当SQL/ストアドプロシージャを発行しているようです。
CMの背後で実行されるSQLはほとんどブラックボックスとして捉えたほうがよさそうです。

2008年1月27日日曜日

今更ながらSSL(3.セキュリティについて考えてみた)

今回SSLの検証用に導入したIHSのhttpd.confを編集して、以前に導入した別の純正Apacheを起動して動作確認をする、という信じられないようなミスをしながらも、何とかSSLで稼働させることが出来ました。
(別のプロダクト起動しておいて設定が反映されるわけない・・・しかも↑のチョンボで1時間ほどロスしました。気が付くの遅い)

で、考えたこと。

a. SSLの仕組みはよく考えられている
b. でも、はっきりいって万全なセキュリティではない

SSLはネット通販サイトでは必須の機能です。SSLをサポートしていないサイトで、絶対にクレジットカード番号などを入力してはいけません。まあ、常識ですね。
しかし、逆に「鍵マークが出ていればまず安全」と思い込んでいる人が多いと思います。でもそれは完全に間違っています。まさに「逆は必ずしも真ならず」です。
証明書自体は誰にだって取得できます。だから、証明書があるからそのサイトは正しいとか、そのサイトに悪意がない、と判断するのは無謀なことです。

普通の人は、Yahoo!や楽天などの超メジャーサイトで、鍵マークを確認して、安心してクレジットカード番号などを入力していることでしょう。それは結果的にはおおむね健全な判断と言えます。

しかしその判断を成り立たせている、以下の要素を一つ一つ見てみましょう。

a. 定評のあるサイトだという思い込み
b. 正規のURLを参照しているという思い込み
c. 鍵が出ていることから来る安心感

a. 極端な話、信じられるサイトだと思って、正規のURLにアクセスして、鍵マークを確認していても、最後にその裏にいる人に騙されることがあるわけです。まあこのパターンではSSLがどうしたとか、そのレベルの議論にはなりませんが。

b. はしばらく前から流行っているフィッシング詐欺などに騙される可能性のことです。
騙りメールにウソのURLが載っていて「パスワード変更のお願い」というお知らせが来るわけです。アクセスしてみるとデザインはどう見ても正規のページ。URLもまあまあ不信なところはない。SSLにも対応している(何かポップアップウィンドウが出たけどよく分からないので無視した)。で、パスワード変更したらアカウントを乗っ取られてしまった、というパターンですね。
これに対応するには、メールを信用しない、サイトにはいつも使っているブックマークから飛ぶ、などの実践が必要です。もちろん、SSLの証明書をよく見れば分かる人は分かるのでしょうが、そんな面倒臭いことはできないですよね。多少SSLに詳しかったとしても。

c. 鍵が出ているからといって、そのサイトが信用できるとは限りません。確かにそのサーバまでの通信は暗号化されています。でもその先の人やサーバがどうなっているかは分かりません。
有名なサイトに行って、ブラウザで何の警告も出ずにSSL通信できたのなら、まず信じてよいとは思います。でも何らかの警告が出たら、まずさっさとそのサイトからは逃げたほうがよいと思います。例えどう見ても正規のページに見えたとしても。

まあ、結局はリスクをどう評価し、どう責任を取るかですね。それこそ、近所のスーパーに買い物に行っても、車にぶつかる可能性があるわけですから。

セキュリティも考えて見るといろいろ面白いものです。

今更ながらSSL(2.IBM HTTP Serverに設定してみる)-2

IBM HTTP Server(以下IHS) Infocenterの通信の保護を参考にしてIHSのSSL構成を行います。

2.2 手順概要
 a. SSLモジュールのロードを定義します。
 b. 仮想ホストとそのポート(443)を定義します。
 c. その他SSL関係のディレクティブを指定します。
Limiting IBM HTTP Server to encrypt at only 128 bits or higherを参考にしました。

2.2.1 SSLモジュールのロード定義
%IHS_ROOT%\conf\httpd.confの最後に、以下の行を追加します。
LoadModule ibm_ssl_module modules/mod_ibm_ssl.so


2.2.2 仮想ホスト定義、その他SSLディレクティブの追加
さらに以下の行を追加します。
Listen 0.0.0.0:443
<VirtualHost HOST名:443>
ServerName HOST名
DocumentRoot "F:/IBMHTTPServer/htdocs/en_US"
ErrorLog "logs/error.log"
TransferLog "logs/error.log"
ServerSignature Off
SSLEnable
Keyfile "F:/IBMHTTPServer/bin/key.kdb"
SSLClientAuth none
SSLServerCert key_test
SSLCipherSpec 27
SSLCipherSpec 21
SSLCipherSpec 23
SSLCipherSpec 3A
SSLCipherSpec 34
SSLCipherSpec 35
</VirtualHost>


2.2.3 確認
https://ホスト名/ にアクセスします。
証明書の警告が表示されます。

勝手証明書なので警告マークがついていますね。
外部サイトでこの表示を見たら逃げるが勝ちです。でも今回は自分が作った証明書なので「はい(Y)」をクリックします。ページが表示されれば完了です。

今更ながらSSL(2.IBM HTTP Serverに設定してみる)-1

IBMHTTPServerにSSLを設定してみましょう。
※このソフトウェアはApacheにIBMが独自に拡張を加えたものです。
※上記リンク先からダウンロードが出来ます。無料でダウンロードできますが、ユーザIDや個人情報が要求されます。

2 IBM HTTP ServerをSSL構成する

2.1 手順概要
i. %IHS_ROOT%\bin\ikeyman を使って証明書と公開/暗号鍵を作成します。
ii. %IHS_ROOT%\conf\httpd.conf にSSL関連の設定を行います。

2.2 ikeymanを使って証明書を作成する
ikeymanユーティリティを使って、自署名入りの証明書を作成します。
証明書と公開/暗号鍵のセットのことを、鍵データベースと記載しているようです。
以下で「鍵データベース」という用語を使います。

2.2.1 鍵データベースの作成(1)
%IBM_HTTP_SERVER_ROOT%\bin\ikeyman.bat を実行、あるいは スタート>プログラム>IBM HTTP Server V6.X とたどり、ikeymanユーティリティを起動します。




2.2.2 鍵データベースの作成(2)
新規作成します。



2.2.3 鍵データベースの作成(3)
鍵データベース・タイプはCMSとします。
その他はデフォルトにしています。


2.2.4 鍵データベースの作成(4)
パスワードは"Password1!"としました。
有効期限を設定しますか→チェック入れないまま
パスワードをファイルに隠しますか?→チェック入れる



2.2.5 鍵データベースの作成(5)
プルダウンで 個人用証明書 を選択します。
右下の 新規自己署名 をクリックします。



2.2.6 鍵データベースの作成(6)
鍵ラベル→key_test
共通名→ホスト名が入っている筈です
組織→org_test
とし、
有効期間は10年としました。



2.2.7 鍵データベースの作成(7)
以上でkey_test 鍵データベースが作成されました。

今更ながらSSL(1.概要)

今更ですがSSLについて勉強します。
外向けECサイトを構築するエンジニアにとっては当たり前の知識かもしれませんが、イントラ向けシステムを構築する人にとってはあまり縁がない機能です。かく言う私もあまりSSLを理解しているとは言えません。
CMでSSLを利用しているということもあり、今回はSSLについて、学んでみます。

※勉強に際しては、主にWikipediaの公開鍵暗号を参考にしました。非常に優れた説明です。

1 SSLとは?
通信を暗号化し、当事者以外には通信内容を分からなくする仕組みです。

1.1 暗号化って具体的にはどんな感じ?
双方で内容を暗号化/復号化する鍵を持ちます。
(i) データを送るときは暗号化して送ります。
(ii)受け取った内容は暗号化されているので、鍵で復号化して読みます。
(i)と(ii)の繰り返しです。

1.2 なあんだ。簡単じゃないか。
限られた友人やチーム内でやり取りするのならば、暗号化も簡単な話でしょう。例えばZIPファイルの暗号化を使えば、普段使いレベルの秘密は保てます。
しかしインターネットは違います。不特定多数の人とやり取りすることになりますから、最初に鍵をいかにして安全に配るかが課題となります。

1.3 どういうこと?
不特定多数のユーザーと、共通鍵暗号(お互いに共通の鍵を持ってやり取りする方法)で通信する実装を考えてみましょう。仮にサーバをXとして、ブラウザをAとします。
最初にAからリクエストが飛んできます。サーバXはランダムに鍵を生成して、Aに送付します。以降、Xは生成された鍵をA用の共通鍵として使い、AはXから貰った鍵をX用の共通鍵として使います。

1.3.1 問題なさそうだけど?
インターネットは基本的には平文が飛び交う世界です。そしてお互いのもとにたどり着くまでは、さまざまな見知らぬサーバ/ネットワーク機器を経由します。要するに全ての通信は途中のサーバ管理者から丸見えです。当然Xが生成した最初の鍵も簡単に見られてしまいます。

1.3.2 本当?
本当です。サーバ上でネットワークトラフィックをダンプすれば、全部見えます。

1.3.2.1 杞憂じゃないの?
杞憂ではありません。

1.3.2.2 そんなの割り切っちゃえば?
あなたのパスワードやらクレジットカード番号が丸見えでもいいんですか?

1.3.2.3 それはいやだな。
でしょう。

1.3.3 じゃあどうやって最初の鍵を配るの?
公開鍵というものを使います。

1.4 公開鍵って?
暗号化する手順を公開します。復号化出来るのは、その暗号化手順を作った人だけです。
Aさんは公開されている暗号化手順で通信を暗号化します。それを復号化できるのはその暗号化手順を作った人だけです。つまり、公開鍵を使って最初の通信メッセージを暗号化すれば、そのメッセージは、Xにしか復号化できません。だから最初のメッセージから安全にやりとりできるわけです。

1.5 暗号化する手順が分かれば、復号できるんじゃないの?
それが非常に難しいんだそうです。

1.5.1 どうなってるの?
詳しい話は私にも分かりません。素因数分解とか、そういう話のようです。詳しくはWikipediaなどを調べてください。

1.5.2 よく分からない。面倒くさい。
同感です。まあ、その辺は隠蔽されているので、知らなくてもSSLは設定できます。

1.5.3 それはよかった。
はい。

1.6 じゃあ秘密鍵と公開鍵を持てばSSL通信できるわけね。
いえ。まだ足りません。公開鍵が本当に通信したい相手のものかどうかを、知るすべが必要です。

1.6.1 どうして。
Aさんがインターネット書店サイト'ほんもの書店.com'から本を買うとします。'ほんもの書店.com'はネット通販のためにSSLに対応しています。Aさんはある日通販リンク集サイトの'あやしいリンク集'(実はイカサマサイト)を辿って'ほんもの書店.com'へのリンクをクリックしました。
実は、この'あやしいリンク集'経由で訪れたページは、すべてこの'リンク集'が設置されたサーバ(Yとしましょう)経由で通信されるように仕組まれていたのです。するとYはAさんに対して偽の公開鍵を発行することが可能になってしまいます。
Aさんは暗号化が行われていると信じて、クレジットカード番号と住所を打ち込むのですが、その情報は全てYに筒抜けとなるのです。
その流れを表すと、以下の流れになります。
i.   'ほんもの書店.com' → 公開鍵X →  'Y' (公開鍵XをYと差替え) → 公開鍵Y → 'Aさん'
ii. 'Aさん'(公開鍵Yで情報[共通鍵Z]を暗号化) → Y暗号 → 
   → 'Y'(Y暗号を解読。公開鍵Xで再度暗号化) → X暗号 → 'ほんもの書店.com'
iii. 'ほんもの書店.com'(クライアントから送られた共通鍵Zで暗号化) → Z暗号 →
   → 'Y'(Z暗号は既に知っているので読み取り可能) → Z暗号 → 'Aさん'

1.6.1.1 何となく分かった。でもこんな面倒くさいこと誰がするの?
面倒臭くありません。優れたプログラマなら下手をすれば数日で作っちゃいますよ。

1.6.1.2 ハッカーってやつね。
クラッカーです。ハッカーは意味が違います。(という主張も最近は聞かなくなったな)

1.6.1.3 何を言ってる?
もういいです。

1.7 どうやってある公開鍵が目的のサイトのものだと分かる?
Verisign Inc.などの第三者機関が公開鍵の証明書を発行します。
ある公開鍵がどのサイトに対して有効なものか、信頼できる第三者機関が保証してくれるわけです。

1.8 証明書?
公開鍵とあわせて証明書をクライアント(ブラウザ)に提示します。証明書には第三者機関による電子署名が入っていて、証明書の偽造を防ぎます。
ブラウザは証明書とサイトのアドレスをチェックして、目的のサイトの公開鍵かどうかをチェックすることができます。

1.8.1 SSLを使えば絶対安全なの?
そうとも言えません。
SSLで暗号化できても、その向こうにいるのはやはり人間だ、ということです。
技術的な安全性については、詳しくはWikipediaのSecure Sockets Layerを見て下さい。

1.8.2 ネットショッピングが怖くなってきた
普通に有名なサイトを利用している分には大丈夫でしょう。多分・・・

1.8.3 何かつかれてきた
私もです。

1.8.4 もう終わりにしたい
私もです。

1.8.5 まとめて
結論です。SSLを構成するのに必要なのは以下の2つです。
-公開鍵/暗号鍵
-公開鍵証明書
※外部に公開したサーバであれば、証明書は第三者機関に依頼することになります。
以上がまとめです。

1.9 (1/31追記)ちょっと待った。1.6.1の例では第三者の証明書は役に立たないじゃないか
どうしてですか。

1.9.1 中間サーバのYが正規の証明書を取ってしまえばいい
あ。

1.9.2 どうだ
くやしい。

1.9.3 ということは、証明書があるからと言って安心してはだめだ、というのが結論だな
ま、そういうことですね。