<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2240534525438980735</id><updated>2011-12-29T15:03:38.834+08:00</updated><category term='C#'/><category term='開發環境'/><category term='參考資料'/><category term='OpenCA'/><category term='開發週報'/><category term='PKI'/><category term='Resin'/><category term='MySQL'/><category term='WPF'/><category term='員工資料庫'/><category term='ESXi'/><title type='text'>RFID Fantasy</title><subtitle type='html'>NCHU MIS 99 級畢業專題 RFID 系統開發部落格</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>47</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-1361679660883313177</id><published>2010-05-03T22:02:00.009+08:00</published><updated>2010-06-23T17:50:35.154+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ESXi'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>vmci error on VMware Tools install on Ubuntu 10.04 (Linux 2.6.32) / ESXi 4</title><content type='html'>Reference: &lt;a href="http://communities.vmware.com/message/1525663?tstart=0"&gt;VMware Communities: Can't install latest VMware Server 2.0.2 on 2.6.32.8&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Problem&lt;/h2&gt;&lt;br /&gt;升級 Ubuntu 10.04 LTS (內核 2.6.32) 後嘗試重新編譯 VMware Tools 卻發生如下的問題:&lt;br /&gt;When OS kernel upgrade into Linux 2.6.32 (like Ubuntu 10.04 LTS), compiling VMware Tools will occur some problems like the below:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;CC [M]  /tmp/vmware-config1/vmci-only/vmciQueuePair.o&lt;br /&gt;In file included from /tmp/vmware-config1/vmci-only/vmci_queue_pair.h:36,&lt;br /&gt;from /tmp/vmware-config1/vmci-only/vmciQueuePair.c:36:&lt;br /&gt;/tmp/vmware-config1/vmci-only/vm_atomic.h:996:7: warning: "_MSC_VER" is not defined&lt;br /&gt;/tmp/vmware-config1/vmci-only/vm_atomic.h:1081:7: warning: "_MSC_VER" is not defined&lt;br /&gt;In file included from /tmp/vmware-config1/vmci-only/vmci_queue_pair.h:36,&lt;br /&gt;from /tmp/vmware-config1/vmci-only/vmciQueuePair.c:36:&lt;br /&gt;/tmp/vmware-config1/vmci-only/vm_atomic.h:996:7: warning: "_MSC_VER" is not defined&lt;br /&gt;/tmp/vmware-config1/vmci-only/vm_atomic.h:1081:7: warning: "_MSC_VER" is not defined&lt;br /&gt;......&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;vmci 模組無法編譯成功，也無法載入至系統，更新失敗。&lt;br /&gt;And vmci module will not be load into system.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Solution&lt;/h2&gt;&lt;br /&gt;1. cd /usr/lib/vmware-tools/modules/source&lt;br /&gt;2. tar xvf vmci.tar (Extract it)&lt;br /&gt;3. mv vmci.tar vmci.tar.bak (Backup)&lt;br /&gt;4. cd vmci-only&lt;br /&gt;5. vi pgtbl.h (Patch pgtbl.h)&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#007997; '&gt;--- vmci-only.old/include/pgtbl.h    2009-10-21 03:43:27.000000000 +0200&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#007997; '&gt;+++ vmci-only/include/pgtbl.h    2010-02-12 19:00:50.277528449 +0100&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#e34adc; '&gt;@@ -24,6 +24,7 @@&lt;/span&gt;&lt;br /&gt; #include "compat_pgtable.h"&lt;br /&gt; #include "compat_spinlock.h"&lt;br /&gt; #include "compat_page.h"&lt;br /&gt;&lt;span style='color:#0000e6; '&gt;+#include "compat_sched.h"&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; #if LINUX_VERSION_CODE &amp;lt; KERNEL_VERSION(&lt;span style='color:#008c00; '&gt;2&lt;/span&gt;, &lt;span style='color:#008c00; '&gt;3&lt;/span&gt;, &lt;span style='color:#008c00; '&gt;11&lt;/span&gt;)&lt;br /&gt; # define compat_active_mm  mm&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;把 #include "compat_sched.h" 加在 #include "compat_page.h" 後面一行。存檔離開。&lt;br /&gt;Add "#include "compat_sched.h"" after "#include "compat_page.h"" and save. Quit.&lt;br /&gt;&lt;br /&gt;6. vi Makefile (Patch Makefile)&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#007997; '&gt;--- vmci-only.old/Makefile    2009-10-21 03:43:27.000000000 +0200&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#007997; '&gt;+++ vmci-only/Makefile    2010-02-12 17:59:21.470529639 +0100&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#e34adc; '&gt;@@ -113,7 +113,7 @@&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \&lt;br /&gt;     $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) \&lt;br /&gt;&lt;span style='color:#0f69ff; '&gt;-    $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#0000e6; '&gt;+    $(EXTRA_CFLAGS) -I$(HEADER_DIR) -Iinclude2/asm/mach-default \&lt;/span&gt;&lt;br /&gt;     -DKBUILD_BASENAME=\"$(DRIVER)\" \&lt;br /&gt;     -Werror -S -o /dev/null -xc $(&lt;span style='color:#008c00; '&gt;1&lt;/span&gt;) \&lt;br /&gt;     &gt; /dev/null &lt;span style='color:#008c00; '&gt;2&lt;/span&gt;&gt;&amp;amp;&lt;span style='color:#008c00; '&gt;1&lt;/span&gt;; then echo "$(&lt;span style='color:#008c00; '&gt;2&lt;/span&gt;)"; else echo "$(&lt;span style='color:#008c00; '&gt;3&lt;/span&gt;)"; fi)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;找到這行&lt;br /&gt;Replace this line:&lt;br /&gt;&lt;blockquote&gt;$(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \&lt;/blockquote&gt;取代成&lt;br /&gt;With:&lt;br /&gt;&lt;blockquote&gt;$(EXTRA_CFLAGS) -I$(HEADER_DIR) -Iinclude2/asm/mach-default \&lt;/blockquote&gt;一樣存檔退出。&lt;br /&gt;Then save and quit.&lt;br /&gt;&lt;br /&gt;7. cd .. (Quit this folder)&lt;br /&gt;8. tar cvf vmci.tar vmci-only/ (Repack the source)&lt;br /&gt;9. rm vmci-only -r (Delete the entire folder)&lt;br /&gt;10. /usr/bin/vmware-config-tools.pl (Re-run config tool to recompile modules)&lt;br /&gt;&lt;br /&gt;重新執行之後應該就可以順利編譯成功並載入至系統，檢查看看是否載入:&lt;br /&gt;Alter all, check if these modules are loaded perfectly:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;$ lsmod|grep "^v"&lt;br /&gt;vsock                  38646  0&lt;br /&gt;vmmemctl                8768  0&lt;br /&gt;vmxnet                 15992  0&lt;br /&gt;vga16fb                12757  1&lt;br /&gt;vgastate                9857  1 vga16fb&lt;br /&gt;vmci                   29828  1 vsock    &lt;-- Here, good&lt;br /&gt;vmw_pvscsi             15744  0&lt;br /&gt;vmxnet3                30709  0&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-1361679660883313177?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/1361679660883313177/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2010/05/vmware-tools-install-on-ubuntu-1004.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1361679660883313177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1361679660883313177'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2010/05/vmware-tools-install-on-ubuntu-1004.html' title='vmci error on VMware Tools install on Ubuntu 10.04 (Linux 2.6.32) / ESXi 4'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-6288586231668894955</id><published>2010-03-26T23:01:00.001+08:00</published><updated>2010-05-03T22:28:50.420+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ESXi'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>Sometimes can't access Guest OS from outside in ESXi</title><content type='html'>很奇怪的問題，在專題期間如果發生了我們肯定氣死，不過現在換學弟妹痛苦了就是。&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;環境&lt;/h2&gt;&lt;br /&gt;描述情況，簡單說明一下 ESXi 伺服器的狀況:&lt;br /&gt;&lt;br /&gt;ESXi Server [192.168.0.2]&lt;br /&gt;├ Ubuntu Server [192.168.0.3]&lt;br /&gt;└ Windows XP Pro [192.168.0.4]&lt;br /&gt;&lt;br /&gt;ESXi 伺服器運作兩台虛擬機器，且兩台虛擬機器都直接設定靜態IP位置 (Static IP)，原本是 140 開頭的為了保護我就先以 192 代替。&lt;br /&gt;&lt;br /&gt;原本在只有 ESXi 和 Ubuntu 的時候相安無事，一切都很順。最近新灌了一個 XP，要給學弟妹用，架設完成給定 MAC Address 和對應的 IP Address，從外面連接也能瀏覽架設的網頁伺服器。&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;問題&lt;/h2&gt;&lt;br /&gt;但運作幾天後，從外面分別連 Ubuntu Server 和 Windows XP Pro 都出現逾時錯誤 (Connection Timeout)，更扯的是 ESXi 甚至連不上管理了，感覺好像整個網路被鎖了一樣。但可能等個一段時間，又突然正常。正常的機器也不一定，可能是 Windows、Ubuntu、ESXi 其中一台，也可能一次多台。&lt;br /&gt;&lt;br /&gt;後來有機會能夠透過同網域的電腦來連線 (即 192.168.0.1/24 網域) 發現這些伺服器都能正常連線！可是從外面連不進去，將 ESXi 更新到最新版本仍舊有此問題，因為以往都能正常連線排除網路線路問題，開始懷疑可能是網卡驅動的問題。&lt;br /&gt;&lt;br /&gt;進一步發現，出問題的 Guest OS 一開始會無法對外瀏覽，查詢 DNS 階段就發生錯誤，但是只要進行網路操作 (Windows 是選修復網路；Ubuntu 是 ping 外面的機器)，奇妙的是連線又恢復正常了。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;PING XXX.XXX.XXX.XXX (---------) 56(84) bytes of data.&lt;br /&gt;64 bytes from XXX.XXX.XXX.XXX: icmp_seq=1, ttl=224, time=600.59ms&lt;br /&gt;64 bytes from XXX.XXX.XXX.XXX: icmp_seq=2, ttl=224, time=5.59ms&lt;br /&gt;64 bytes from XXX.XXX.XXX.XXX: icmp_seq=3, ttl=224, time=4.82ms&lt;br /&gt;64 bytes from XXX.XXX.XXX.XXX: icmp_seq=4, ttl=224, time=5.35ms&lt;/blockquote&gt;&lt;br /&gt;會有這種第一次查詢爆慢，後面查詢開始正常的狀況。&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;類似案例&lt;/h2&gt;&lt;br /&gt;說真的不知道要用什麼關鍵字來找這種問題，但是還是被我搜到類似的東西：&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.vpsee.com/2010/02/fix-minix-amd-lance-nic-driver-problem/"&gt;Minix 上的 AMD Lance 网卡驱动问题&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;使用静态 IP 地址以后，外部网络无法 ping 通 Minix，必须 Minix 先 ping 外面，然后外面才能 ping 通它&lt;/blockquote&gt;簡直是一模一樣的狀況！不同的是OS不一樣，所以解決方案就沒有效了。不過可推測問題可能就是OS載入的網路驅動出問題。&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://ubuntuforums.org/showthread.php?t=1105019"&gt;[other] In ESXi can't access guest OS (Ubuntu 8.10) from outside &lt;/a&gt;&lt;br /&gt;Ubuntu 官方論壇，描述跟我的情況是最相近的了。可惜沒多少人注意並回答這個問題，回應提到可能跟 ESXi 的 vSwitch 或 VLAN 設定有關？但我都沒有更動過，完全是預設值。至少虛擬機器只有一台的時候，非常順。&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;結論&lt;/h2&gt;&lt;br /&gt;總之，目前無解。茲紀錄如下希望能有其他有相同問題的人、或是有能力解決的人解惑了。&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;土砲解法&lt;/h2&gt;&lt;br /&gt;問題不能就這樣放著，所以我想出奇招。&lt;br /&gt;&lt;br /&gt;既然機器ping外部的時候，網路會暫時回復一陣子，那我就定時ping外面的機器，讓線路保持動作。這樣就可以確保連線正常了。聽起來很蠢，但是實際使用確實有效。需要搭配 cron 作定期工作。&lt;br /&gt;&lt;br /&gt;/etc/crontab 加一行&lt;br /&gt;&lt;blockquote&gt;*/2 * * * *     root    python /usr/bin/randomping.py &gt;&gt; /var/log/ping.log&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;其中 &gt;&gt; 後面的意思是附加輸出 STDOUT 到檔案，觀察用，與ping無關。關鍵程式 randomping.py:&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;import&lt;/span&gt; random&lt;span style='color:#808030; '&gt;,&lt;/span&gt; os&lt;br /&gt;&lt;br /&gt;pingHosts &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;"168.95.1.1"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"168.95.192.1"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"139.175.150.20"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"139.175.55.244"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"8.8.8.8"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"8.8.4.4"&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Host &lt;span style='color:#808030; '&gt;=&lt;/span&gt; random&lt;span style='color:#808030; '&gt;.&lt;/span&gt;sample&lt;span style='color:#808030; '&gt;(&lt;/span&gt;pingHosts&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;1&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt;&lt;br /&gt;os&lt;span style='color:#808030; '&gt;.&lt;/span&gt;system&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;"date"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;os&lt;span style='color:#808030; '&gt;.&lt;/span&gt;system&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;"ping "&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; Host &lt;span style='color:#808030; '&gt;+&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;" -c 2"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;因為怕定期ping某單一機器會被鎖之類的，所以設定了多組名單來ping。而這些Server都是公開的DNS，應該沒有問題。&lt;br /&gt;&lt;br /&gt;存到 /usr/bin/randomping.py 後，就讓它自動運作吧。真是爛方法，但是確實有效，唉。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-6288586231668894955?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/6288586231668894955/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2010/03/sometimes-cant-access-guest-os-from.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6288586231668894955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6288586231668894955'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2010/03/sometimes-cant-access-guest-os-from.html' title='Sometimes can&apos;t access Guest OS from outside in ESXi'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-9139404382912123654</id><published>2010-03-14T19:40:00.002+08:00</published><updated>2010-05-03T22:28:50.421+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ESXi'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>Install/Upgrade VMware Tools on ESXi Guest OS</title><content type='html'>這麼重要的流程竟然沒做紀錄，作一下免得日後忘記。&lt;br /&gt;&lt;br /&gt;ESXi 裡的 Guest OS 最好裝一下 VMware Tools 以取得更佳的效能，和 VMware 自家其他虛擬機器程式一樣。安裝方式首先要從 ESXi 管理介面設定 Install/Upgrade VMware Tools。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_YTQXzGpyark/S5zHGtrDabI/AAAAAAAAA5c/VikTkbBkHvA/s1600-h/vmtools-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="144" src="http://1.bp.blogspot.com/_YTQXzGpyark/S5zHGtrDabI/AAAAAAAAA5c/VikTkbBkHvA/s320/vmtools-01.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;按下選項後，Guest OS 的光碟機就好像放了一片驅動程式光碟一般，*nix 系的安裝方式比較麻煩，需要手動操作:&lt;br /&gt;&lt;br /&gt;0. 首先先切換到 root 帳號取得必要權限&lt;br /&gt;&lt;blockquote&gt;sudo -s&lt;/blockquote&gt;&lt;br /&gt;1. 安裝必要編譯套件及檔頭檔&lt;br /&gt;&lt;blockquote&gt;apt-get update&lt;br /&gt;apt-get install build-essential&lt;br /&gt;apt-get install linux-headers-`uname -r`&lt;/blockquote&gt;&lt;br /&gt;第二行是安裝所需的編譯套件 (gcc, make 等)，第二行是安裝 VMware Tools 需要的 Linux 檔頭檔。&lt;br /&gt;&lt;br /&gt;2. 建立暫存目錄，掛載 CD-ROM&lt;br /&gt;&lt;blockquote&gt;cd /tmp&lt;br /&gt;&lt;br /&gt;mkdir /tmp/vm&lt;br /&gt;mount /dev/cdrom /tmp/vm&lt;/blockquote&gt;&lt;br /&gt;3. 取出 VMware Tools 並解壓編譯&lt;br /&gt;&lt;blockquote&gt;cp /tmp/vm/VMwareTools* /tmp&lt;br /&gt;umount /tmp/vm&lt;br /&gt;&lt;br /&gt;tar xzf VMwareTools*&lt;br /&gt;/tmp/vmware-tools-distrib/vmware-install.pl&lt;/blockquote&gt;&lt;br /&gt;過程中會看到許多訊息跑出來，大概就是要問你安裝的位置和是否手動編譯之類的，一路按下 Enter 採用預設值即可，到最後會編譯各個組件，然後設定完成。&lt;br /&gt;&lt;br /&gt;出現如下的成功訊息就表示整個安裝/升級的程序完成了！&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_YTQXzGpyark/S5zIv159n_I/AAAAAAAAA5g/ReIB4NBkoWk/s1600-h/vmtools-02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="207" src="http://1.bp.blogspot.com/_YTQXzGpyark/S5zIv159n_I/AAAAAAAAA5g/ReIB4NBkoWk/s320/vmtools-02.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;檢查一下 Guest OS 的面板顯示狀態。&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_YTQXzGpyark/S5zJ2dFaEAI/AAAAAAAAA5k/Ymrlm61ojRM/s1600-h/vmtools-03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="185" src="http://3.bp.blogspot.com/_YTQXzGpyark/S5zJ2dFaEAI/AAAAAAAAA5k/Ymrlm61ojRM/s320/vmtools-03.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;記得只要更新了 Linux Kernel 版本 (uname -r 可得知版本)，就必須重作一次升級的動作，因為 VMware Tools 是針對 Kernel 作更動以達成最佳化，舊有的版本在新版的 Kernel 是沒有用的。另外升級的話 apt-get install build-essential 可以不必再作，因為要安裝時就已經有這個套件了吧。但是 linux-headers 記得要裝！上面的指令會自動抓取與 Kernel 相同版本的 Header 檔。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-9139404382912123654?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/9139404382912123654/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2010/03/installupgrade-vmware-tools-on-esxi.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/9139404382912123654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/9139404382912123654'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2010/03/installupgrade-vmware-tools-on-esxi.html' title='Install/Upgrade VMware Tools on ESXi Guest OS'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_YTQXzGpyark/S5zHGtrDabI/AAAAAAAAA5c/VikTkbBkHvA/s72-c/vmtools-01.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-7132354277210481536</id><published>2009-12-31T14:22:00.001+08:00</published><updated>2009-12-31T14:23:39.481+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>WPF Frame.NavigationFailed 正確捕捉方式</title><content type='html'>我們的程式用到了 Frame 當作瀏覽器視窗，可以接受使用者輸入的 URL 顯示網頁。但如果使用者隨便輸入或鍵入一個不存在的網址要求 (使用 frame.Navigate(Uri))，Frame 會跳出 WebException。&lt;br /&gt;&lt;br /&gt;因為這樣會強制結束程式，所以我加個 try ... catch 來攔截，這下總沒有問題了吧？&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;try{&lt;br /&gt;    frame.Navigate(new Uri(url));&lt;br /&gt;}catch{&lt;br /&gt;    // show something ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;結果程式一跑，相同的 Exception 一樣憑空跳出，讓我丈二金剛摸不著頭腦，究竟是怎麼一回事呢？查了MSDN發現，原來 Frame 有專屬的 &lt;a href="http://msdn.microsoft.com/zh-tw/library/system.windows.controls.frame.navigationfailed.aspx"&gt;NavigationFailed&lt;/a&gt; 事件，要撰寫事件來抓這個錯誤才行，Navigate 方法本身不丟出錯誤的。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;frmBrowser.NavigationFailed += new NavigationFailedEventHandler(this.NavigationFailedEventHandler);&lt;br /&gt;&lt;br /&gt;private void NavigationFailedEventHandler(object sender, NavigationFailedEventArgs e) {&lt;br /&gt;    // show something ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;好，我按照 MSDN 的說明，用了事件捕捉，這下總沒事了吧？事情通常沒我們想的簡單，Exception 還是偷偷的跑出來打斷了我們的程式，怎麼會這樣？&lt;br /&gt;&lt;br /&gt;注意看 MSDN，尋找可能的問題，後來發現事件的其中一個參數 NavigationFailedEventArgs 非常可疑，一看才知道原來它隱藏著本篇的解藥！其實就是它的 &lt;a href="http://msdn.microsoft.com/zh-tw/library/system.windows.navigation.navigationfailedeventargs.handled.aspx"&gt;Handled&lt;/a&gt; 屬性。說明是這樣寫的：&lt;br /&gt;&lt;blockquote&gt;當處理 NavigationFailed 以處理因巡覽失敗所擲回的例外狀況，而您也不想 WPF 繼續處理例外狀況時，應該將 Handled 屬性設定為 true。&lt;/blockquote&gt;&lt;pre&gt;private void NavigationFailedEventHandler(object sender, NavigationFailedEventArgs e) {&lt;br /&gt;    // show something ...&lt;br /&gt;    e.Handled = true; // 已處理，不再擲出錯誤&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;結果加了一行，例外就乖乖的不出現了。如此重要的參數竟然在事件裡或範例中隻字未提，如果沒有發現 NavigationFailedEventArgs 參數的玄機，我想會卡非常久。特此將此經驗公諸於世，希望能救到後來人。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-7132354277210481536?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/7132354277210481536/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/12/wpf-framenavigationfailed.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7132354277210481536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7132354277210481536'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/12/wpf-framenavigationfailed.html' title='WPF Frame.NavigationFailed 正確捕捉方式'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-6148902863042997436</id><published>2009-12-31T13:57:00.002+08:00</published><updated>2009-12-31T14:03:23.705+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>WPF ListView + GridView Items.Add</title><content type='html'>我們的程式用到了 ListView，而且又用了 GridView 分欄，讓清單看起來比較美觀，結果就像是Windows檔案總管的詳細資料那樣。&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_YTQXzGpyark/Szw4dwJ-gJI/AAAAAAAAA1Y/tghJNVn1KrU/s1600-h/listView.png" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_YTQXzGpyark/Szw4dwJ-gJI/AAAAAAAAA1Y/tghJNVn1KrU/s320/listView.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: rgb(255, 255, 255) none repeat scroll 0% 0%; color: black; overflow: auto;"&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;ListView&lt;/span&gt; &lt;span style="color: #274796;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;listView1&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #274796;"&gt;Margin&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;178,29,35,51&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #274796;"&gt;SelectionMode&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;Single&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;ListView.View&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;GridView&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;GridViewColumn&lt;/span&gt; &lt;span style="color: #274796;"&gt;Header&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;FileName&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #274796;"&gt;Width&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;230&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #274796;"&gt;DisplayMemberBinding&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;{Binding Path=FileName}&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #a65700;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;GridViewColumn&lt;/span&gt; &lt;span style="color: #274796;"&gt;Header&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;Date&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #274796;"&gt;Width&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;140&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #274796;"&gt;DisplayMemberBinding&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;{Binding Path=Date}&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt; &lt;span style="color: #a65700;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;GridView&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;ListView.View&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;ListView&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;但是加上了GridView的ListView，不再可以容易的以 物件名.Items.Add("String") 直接新增一條資料，這樣許多欄位的資料都會一樣。網路上的做法是使用資料繫結的方式，維護一個物件然後 Bind 上去即可，但是我還是習慣以程式動態新增，可不可以達成呢？當然可以。&lt;br /&gt;&lt;br /&gt;因為是 WPF，所以沒有 Windows Form 的 ListViewItem 物件和物件名.SubItem 等屬性可以用。查了一下網路說明，需要建立一個物件而不是文字傳入 Items.Add()。&lt;br /&gt;&lt;br /&gt;因為我是多欄，所以物件也要有多個屬性值，我建立一個結構來儲存：&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;private&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;struct&lt;/span&gt; FileStructure&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;string&lt;/span&gt; FileName &lt;span style='color:#800080; '&gt;{&lt;/span&gt; get&lt;span style='color:#800080; '&gt;;&lt;/span&gt; set&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; String Date &lt;span style='color:#800080; '&gt;{&lt;/span&gt; get&lt;span style='color:#800080; '&gt;;&lt;/span&gt; set&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;值得一提的是 { get; set; } 要加上，如果沒有加上這個繫結將會失敗。&lt;br /&gt;&lt;br /&gt;然後在 WPF 的 GridView 的 DisplayMemberBinding 屬性設定 Binding，讓程式知道物件的哪個值對應到哪個欄位。請參考一開始的 WPF 原始碼。雖然我的方法還是有用到 Bind，但那是告訴 ListView 我的東西要怎樣呈現。&lt;br /&gt;&lt;br /&gt;最後，以程式新增：&lt;br /&gt;&lt;br /&gt;listView1.Items.Add(new FileStructure{ FileName = "test.zip", Date = "2009/12/21" });&lt;br /&gt;listView1.Items.Add(new FileStructure{ FileName = "test.rar", Date = "2009/12/22" });&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;這樣就可以動態新增ListView的資料，而且每一欄的資料都正確的填進去了。&lt;br /&gt;---&lt;br /&gt;參考文獻：&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/1305406/wpf-listview-how-to-bind-single-items"&gt;http://stackoverflow.com/questions/1305406/wpf-listview-how-to-bind-single-items&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-6148902863042997436?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/6148902863042997436/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/12/wpf-listview-gridview-itemsadd.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6148902863042997436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6148902863042997436'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/12/wpf-listview-gridview-itemsadd.html' title='WPF ListView + GridView Items.Add'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_YTQXzGpyark/Szw4dwJ-gJI/AAAAAAAAA1Y/tghJNVn1KrU/s72-c/listView.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-1881265580339803696</id><published>2009-11-26T09:57:00.003+08:00</published><updated>2009-11-26T09:58:36.007+08:00</updated><title type='text'>小論文格式</title><content type='html'>&lt;div&gt;一.摘要&lt;/div&gt;&lt;div&gt;二.Abstract&lt;/div&gt;&lt;div&gt;三.前言&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;1.研究動機&lt;/div&gt;&lt;div&gt;四.使用者需求分析&lt;/div&gt;&lt;div&gt;五.研究與方法(文獻探討)&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;1.RFID技術&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;2.PKI技術&lt;/div&gt;&lt;div&gt;六.系統架構&lt;/div&gt;&lt;div&gt;七.系統評估&lt;/div&gt;&lt;div&gt;八.結論&lt;/div&gt;&lt;div&gt;九.參考文獻&lt;/div&gt;&lt;div&gt;-------------------------&lt;/div&gt;&lt;div&gt;大概這樣吧！要改再討論吧&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-1881265580339803696?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/1881265580339803696/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/11/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1881265580339803696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1881265580339803696'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/11/blog-post.html' title='小論文格式'/><author><name>Jimmy</name><uri>http://www.blogger.com/profile/14068193898204652397</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-5032551473486547056</id><published>2009-10-11T13:29:00.002+08:00</published><updated>2009-10-11T13:35:44.949+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><title type='text'>資通PKI應用競賽 時程表</title><content type='html'>活動網站：&lt;br /&gt;&lt;a href="http://csim.tca.org.tw/"&gt;http://csim.tca.org.tw/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ares.com.tw/pki_pk2009/a.php"&gt;http://www.ares.com.tw/pki_pk2009/a.php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1. 報名日期：98年10月1日(四)至11月19日(四) 下午六點截止&lt;br /&gt;2. 初賽日期：98年11月23日(一)至11月27日(五)&lt;br /&gt;3. 決賽日期：98年12月5日(六)&lt;br /&gt;4. 競賽地點：台灣大學綜合體育館（台北市羅斯福路四段一號）&lt;br /&gt;&lt;br /&gt;別忘了還有這個活動啊XD&lt;br /&gt;---&lt;br /&gt;報名還要錄製VCD，且邊操作邊說明，所以這系統一定要在期限內完成啊。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-5032551473486547056?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/5032551473486547056/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/10/pki.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5032551473486547056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5032551473486547056'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/10/pki.html' title='資通PKI應用競賽 時程表'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-7333032104147422940</id><published>2009-10-04T15:02:00.003+08:00</published><updated>2009-10-04T15:52:50.047+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>One-Time Password</title><content type='html'>沒想像中的那麼容易，為了簡化文章，我直接將運作流程列出來：&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;先在「安全環境」(如你家電腦)設定產生OTP的各項參數: 密碼, Seed, 演算法, Count/Seq.，產生OTP密碼表格&lt;/li&gt;&lt;li&gt;到「非安全環境」(如網咖、學校)登入時，系統會要求你查找密碼表格的某一個密碼(例如第49個)&lt;/li&gt;&lt;li&gt;以查表法查出正確密碼，輸入後登入。如果不想查表，可以用 OTPGen/Mobile-OTP 等 Java程式，給予當初初始化的參數，算出表格再查表輸入&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;這是正統的 &lt;a href="http://www.faqs.org/rfcs/rfc2289.html"&gt;RFC2289&lt;/a&gt; 一次性密碼系統的流程，很明顯在我們的系統用這種東西根本不對。&lt;br /&gt;&lt;br /&gt;因為教授說用預先定義好的內容作數位簽章，很容易被中間人攻擊，所以希望這個內容能夠隨機產生，最好是一次性的，這樣中間人攔截內容要重送時已經失效了。&lt;br /&gt;&lt;br /&gt;不過正規的OTP系統，是寫死的流程，跟我們單純要求的隨機內容有點差距。所以又只能自己動手了。&lt;br /&gt;&lt;br /&gt;因為我們要求的隨機密碼不會有讓使用者手動輸入的機會，得到後就立刻數位簽章送給伺服器認證，不必擔心太過複雜難以輸入的問題。我的想法是這樣的：&lt;br /&gt;&lt;br /&gt;登入系統向伺服器要求(https)一次性隨機密碼&lt;br /&gt;↓&lt;br /&gt;伺服器回傳(https)，同時紀錄於 Session 內&lt;br /&gt;↓&lt;br /&gt;登入系統收到密碼，簽章傳送給伺服器(https)&lt;br /&gt;↓&lt;br /&gt;伺服器拿出使用者憑證跟 Session 紀錄的一次性隨機密碼，進行驗證。不論成功與否皆清除 Session 密碼&lt;br /&gt;&lt;br /&gt;原先教授的疑慮是這樣的：當我用固定的內容(如: 「超爽的，撿到一百塊咧」或者是當天日期)，系統送出給伺服器的過程中假如被攔截(假設 https 還會被攔截解密的話啦...)，中間人可以進行重送攻擊 (因為簽章驗證會通過，驗證是驗證資料不是送的人)。如果是固定文字，那此攻擊可以不限時間成功；當天日期的話，當天重送攻擊都有效。所以教授才會說要將內容加到分鐘，甚至是秒，以避免這種攻擊。&lt;br /&gt;&lt;br /&gt;改成隨機內容的話，由於使用者要登入都得先向伺服器要求產生一次性隨機密碼，這個密碼萬一真被中間人竊取成功，中間人並沒有私鑰可以進行簽章，所以攻擊失敗。要是在送出簽章的時候攔截實施重送攻擊，一來中間人並沒有要求伺服器發給一次性密碼，伺服器也就沒有用Session儲存，在進行檢查的時候就沒有東西可以用，而紀錄警告；二來這個一次性隨機密碼已經在剛才的正規使用者登入時，就已失效，所以還是沒有用。&lt;br /&gt;&lt;br /&gt;如果中間人夠厲害，一次性隨機密碼、數位簽章都取得，再加上入侵伺服器將 Session 改成一次性隨機密碼，那就有機會。但是這需要攻擊 HTTPS, 伺服器，自有難度。Session 變造內容的攻擊法還沒有聽說過，因為 Session 存在伺服器除非入侵不然改不到。只有 Session ID 攻擊 (參見: &lt;a href="http://anti-hacker.blogspot.com/2007/01/session-hijacking-cookie-45.html"&gt;Session Hijacking 攻擊與Cookie 欺騙(4/5) - 網路攻防戰&lt;/a&gt;)：利用 Session ID 綁 Cookie 的設計，竊取正規使用者 Cookie，把自己的 Cookie 改的跟正規者一樣，Session ID自然一樣，對應的 Session 正是合法使用者的。&lt;br /&gt;&lt;br /&gt;解決方式是每次要求就改變 Session ID，PHP 有函式 session_regenerate_id() 可以避免這種問題。&lt;hr /&gt;&lt;br /&gt;結論：根基於 HTTPS、一次性隨機密碼、數位簽章、Session 跟每次改變 Session ID的方式，讓中間人的破解難度增加，我想可以達到安全。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-7333032104147422940?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/7333032104147422940/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/10/one-time-password.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7333032104147422940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7333032104147422940'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/10/one-time-password.html' title='One-Time Password'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-3989542395352001710</id><published>2009-09-29T20:40:00.005+08:00</published><updated>2009-09-29T22:59:48.700+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發週報'/><title type='text'>09/29 開會結論</title><content type='html'>- C# &lt;-&gt; MySQL 加密連線傳輸使用法&lt;br /&gt;&lt;br /&gt;pMA 開啟 MySQL SSL 連線&lt;br /&gt;http://wiki.phpmyadmin.net/pma/Config/Servers#ssl&lt;br /&gt;&lt;br /&gt;MySQL SSL 支援&lt;br /&gt;http://www.option-c.com/xwiki/MySQL_Replication_with_SSL&lt;br /&gt;&lt;br /&gt;好吧，C#部分不明，很多人在問但沒有一個好回答&lt;br /&gt;http://dev.mysql.com/doc/refman/5.1/en/connector-net-programming-connection-options.html&lt;br /&gt;官方是說連線字串加上 useSSL=true 就成，實際上沒那麼容易，一試就error。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- 數位簽章本文使用 OTP 方式建立，避免數位簽章被中間人攔截登入&lt;br /&gt;- 闡明技術部份 (CA如何建立，如何管憑證、安全傳輸使用 ,etc)&lt;br /&gt;&lt;br /&gt;還有，三本文件的催生。&lt;br /&gt;&lt;br /&gt;最後右邊有個增加緊張感的自製 Widget，希望可以給大家一點推力XD&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-3989542395352001710?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/3989542395352001710/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/09/0929.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3989542395352001710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3989542395352001710'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/09/0929.html' title='09/29 開會結論'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-1953926150667520282</id><published>2009-09-12T23:00:00.005+08:00</published><updated>2009-09-12T23:29:03.015+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>設定 iptables - 防火牆規則設定</title><content type='html'>Ubuntu 預設的 iptables 設定是全部通行，防火牆如果全部通行那就等於沒設定，所以我們要對它設些規則。&lt;br /&gt;&lt;br /&gt;目標:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;對內: 僅打開 SSH(22), HTTP(80), HTTPS(443), MYSQL(3306) PORT，其他全部封鎖&lt;/li&gt;&lt;li&gt;對外: 不設限&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;這樣就可以防止有心人入侵其他 Port。&lt;br /&gt;&lt;br /&gt;本來是要下一大堆指令的，不過 iptables 可以用 iptables-save 來輸出規則，所以我直接貼出規則檔:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;# Generated by iptables-save v1.4.1.1 on Tue Aug 25 12:57:50 2009&lt;br /&gt;*filter&lt;br /&gt;:INPUT DROP [2858:374901]&lt;br /&gt;:FORWARD DROP [0:0]&lt;br /&gt;:OUTPUT ACCEPT [186:47949]&lt;br /&gt;-A INPUT -i lo -j ACCEPT&lt;br /&gt;-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT&lt;br /&gt;-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT&lt;br /&gt;-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT&lt;br /&gt;-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT&lt;br /&gt;-A OUTPUT -o lo -j ACCEPT&lt;br /&gt;COMMIT&lt;br /&gt;# Completed on Tue Aug 25 12:57:50 2009&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;將此檔存到 /etc/iptables.up.rule。&lt;br /&gt;&lt;br /&gt;因為每次開機後 iptables 的規則就會重置，要修改開機時能夠讀取剛才建立的規則檔，這樣我們建立的防火牆規則才有效。&lt;br /&gt;&lt;br /&gt;用 vi 打開 /etc/network/interfaces，應該可以看到網路卡設定，加一行指令即可:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;pre-up iptables-restore &lt; /etc/iptables.up.rule&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;並存檔。這樣可以確保開機後自動回覆規則。&lt;br /&gt;&lt;br /&gt;但是沒重新開機前，現在的 iptables 狀態還是空的，所以我們要手動載入規則檔，執行：&lt;br /&gt;&lt;br /&gt;# iptables-restore &lt; /etc/iptables.up.rule&lt;br /&gt;&lt;br /&gt;就可以了，要查看是否成功的話可以下指令:&lt;br /&gt;&lt;br /&gt;# iptables -L&lt;br /&gt;&lt;br /&gt;應該會出現很多規則，這樣就成功了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-1953926150667520282?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/1953926150667520282/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/09/iptables.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1953926150667520282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1953926150667520282'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/09/iptables.html' title='設定 iptables - 防火牆規則設定'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-3931406173736748800</id><published>2009-08-31T13:45:00.002+08:00</published><updated>2009-08-31T13:56:44.764+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Resin'/><title type='text'>resin-4.0 session的設定</title><content type='html'>我們&lt;br /&gt;這在做管理介面時遇到鬼打牆&lt;br /&gt;看session是啟用的&lt;br /&gt;存活時間是30分鐘&lt;br /&gt;但只要一換頁面session就會變空的&lt;br /&gt;翻來翻去翻resin的說明&lt;h1 class="section"&gt;&lt;session-config&gt;&lt;/session-config&gt;&lt;/h1&gt;有這玩意兒可以來調session的設定&lt;br /&gt;&lt;a href="http://caucho.com/resin/reference/session-tags.xtp"&gt;請參考這裡&lt;/a&gt;&lt;br /&gt;前面講了一大推沒在用的我還去試他orz&lt;br /&gt;最後試一試是只要設這個&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color: rgb(105, 105, 105);"&gt; enable persistent sessions &lt;/span&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--&gt;&lt;/span&gt;&lt;br /&gt;−&lt;br /&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(95, 80, 53);"&gt;session-config&lt;/span&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(95, 80, 53);"&gt;save-mode&lt;/span&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&gt;&lt;/span&gt;after-request&lt;span style="color: rgb(166, 87, 0);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(95, 80, 53);"&gt;save-mode&lt;/span&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(95, 80, 53);"&gt;use-persistent-store&lt;/span&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;/&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(95, 80, 53);"&gt;session-config&lt;/span&gt;&lt;span style="color: rgb(166, 87, 0);"&gt;&gt;&lt;/span&gt;&lt;br /&gt;−&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;&amp;lt;!--&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;增加save-mode這個child&lt;br /&gt;並設定其質為after-request&lt;br /&gt;一有request就存進去&lt;br /&gt;解決這問題&lt;br /&gt;&lt;br /&gt;(題外　管理介面有做一些小變更　包含登入驗證等頁面改變　可以去看看？)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-3931406173736748800?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/3931406173736748800/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/resin-40-session.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3931406173736748800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3931406173736748800'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/resin-40-session.html' title='resin-4.0 session的設定'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-2070653626469101118</id><published>2009-08-30T17:40:00.005+08:00</published><updated>2009-08-31T11:09:16.202+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>PKI Research #4.5 - Digital Signature 再臨</title><content type='html'>最近要實作檔案傳輸的部分，由於一開始作使用者登入時，驗證的部分是在本機端 (Client) 作的，伺服器端 (Server) 根本無法得知真實性。所以當有人聲稱某甲要求檔案或傳輸檔案過來時，我們也不能肯定他就是本人。因此，有必要在伺服器端再作一遍。&lt;br /&gt;&lt;br /&gt;數位簽章的實作，其實在研究 #4 中已經有了，但是主要是驗證簽章的部分，要在伺服器中執行。搭配接收 POST 上傳檔案的設計，我採用 PHP 來實作。查了一下 PHP 也有 OpenSSL 套件支援 (&lt;a href="http://www.php.net/openssl"&gt;API&lt;/a&gt;)，所以我只要使用它提供的函式就可以驗證簽章，關鍵函式 openssl_verify。&lt;br /&gt;&lt;br /&gt;openssl_verify 能接受一些參數 (原訊息、數位簽章、公鑰) 來驗證簽章正確性，其中簽章演算法只支援到 SHA1，沒有先前研究的 SHA256，只好把簽章的部分也改用 SHA1 以配合。公鑰的部分，得先從憑證裡抽出來，這有 openssl_get_publickey 可以使用。&lt;br /&gt;&lt;br /&gt;大概像這樣:&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#a65700; background:#ffffe8; '&gt;&amp;lt;?php&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$message&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'test'&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#696969; background:#ffffe8; '&gt;// Original Message&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;try&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;{&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$dbh&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;new&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; PDO&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'mysql:dbname=FAST;host=127.0.0.1'&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;,&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'user'&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;,&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'pass'&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;}&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;catch&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;PDOException &lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$e&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;{&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;echo&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'Connection failed: '&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;.&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$e&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;-&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;&gt;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;getMessage&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;}&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$sth&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$dbh&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;-&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;&gt;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;prepare&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'SELECT `Public_Key` FROM XXX WHERE ID = ?'&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$sth&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;-&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;&gt;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;bindParam&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; background:#ffffe8; '&gt;1&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;,&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$tagID&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;,&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; PDO&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;::&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;PARAM_STR&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;,&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#008c00; background:#ffffe8; '&gt;8&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$sth&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;-&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;&gt;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;execute&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$row&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$sth&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;-&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;&gt;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;fetch&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$pubkeyid&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#400000; background:#ffffe8; '&gt;openssl_get_publickey&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$row&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;[&lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'Public_Key'&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;]&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#696969; background:#ffffe8; '&gt;// state whether signature is okay or not&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$ok&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#400000; background:#ffffe8; '&gt;openssl_verify&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$message&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;,&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#400000; background:#ffffe8; '&gt;base64_decode&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$_POST&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;[&lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;'sigData'&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;]&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;,&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$pubkeyid&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;if&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$ok&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#008c00; background:#ffffe8; '&gt;1&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;{&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;echo&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;"good"&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;}&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;elseif&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$ok&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;=&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#008c00; background:#ffffe8; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;{&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;echo&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;"bad"&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;}&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;else&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;{&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&lt;/span&gt;&lt;span style='color:#800000; background:#ffffe8; font-weight:bold; '&gt;echo&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt; &lt;/span&gt;&lt;span style='color:#0000e6; background:#ffffe8; '&gt;"ugly, error checking signature"&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;}&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#696969; background:#ffffe8; '&gt;// free the key from memory&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#400000; background:#ffffe8; '&gt;openssl_free_key&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;(&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;$pubkeyid&lt;/span&gt;&lt;span style='color:#808030; background:#ffffe8; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; background:#ffffe8; '&gt;;&lt;/span&gt;&lt;span style='color:#000000; background:#ffffe8; '&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#a65700; background:#ffffe8; '&gt;?&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;sigData 是數位簽章內容，為了傳輸方便已先行以 BASE64 編碼，所以這邊再解碼還原。&lt;br /&gt;&lt;br /&gt;實際測試時，發現結果一直回傳 bad 即簽章不符，因為 C# 實作驗證都一切正常，所以我懷疑是不是 PHP 的問題，改換使用 JSP 來實作簽章驗證的部分，結果一樣失敗，不同的是 Java 跳出簽章結構錯誤的訊息，我開始懷疑起實作簽章的部分了。在 PHP 上使用 key 私鑰檔實作簽名，跑出來的東西跟 C# 的完全不一樣。C# 簽章驗證的結果，兩種結果都能通過驗證，不過 C# 的結果丟給 PHP 是失敗的，百思不得其解。&lt;br /&gt;&lt;br /&gt;回頭想想，會不是會當初實作簽章的時候，想法錯了呢？還記得 .NET Framework 不許我們使用公鑰解密，取而代之的提供 Verify 方法，找看看 Bouncy Castle 有沒有提供類似的 Sign 方法，結果真的有。&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; signature&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; data&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;try&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        AsymmetricCipherKeyPair keyPair&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;var reader &lt;span style='color:#808030; '&gt;=&lt;/span&gt; File&lt;span style='color:#808030; '&gt;.&lt;/span&gt;OpenText&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;D:\Programs\OpenSSL\user1.key&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Direct read pem format RSA private key file&lt;/span&gt;&lt;br /&gt;            keyPair &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;AsymmetricCipherKeyPair&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; PemReader&lt;span style='color:#808030; '&gt;(&lt;/span&gt;reader&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadObject&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        RsaDigestSigner rds &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaDigestSigner&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Sha1Digest&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        rds&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Init&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;true&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; keyPair&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Private&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        rds&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BlockUpdate&lt;span style='color:#808030; '&gt;(&lt;/span&gt;data&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; data&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Length&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; rds&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GenerateSignature&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;catch&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Exception e&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;throw&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; IOException&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;problem creating private key: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; e&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;bool&lt;/span&gt; verify&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; message&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; sig&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    var crt &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; X509Certificate2&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;D:\Programs\OpenSSL\user1.crt&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Read X509 Certificate file&lt;/span&gt;&lt;br /&gt;    var rsa &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;RSACryptoServiceProvider&lt;span style='color:#808030; '&gt;)&lt;/span&gt; crt&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PublicKey&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Key&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Get public key&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;VerifyData&lt;span style='color:#808030; '&gt;(&lt;/span&gt;message&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;SHA1&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; sig&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Bouncy Castle 提供了 Org.BouncyCastle.Crypto.Signer 類別來處理數位簽章，RsaDigestSigner 就是給 RSA 公開金鑰演算法使用的數位簽章處理類別，由於 PHP 方的 Hash 演算法只支援到 SHA1，所以我簽章的部分也僅使用 SHA1。使用這個 Signer 類別不必自己手動 Hash 訊息，交給類別去作。&lt;br /&gt;&lt;br /&gt;驗證簽章的部分跟上次基本上沒很大的差別，只是我也捨棄 VerifyHash 方法改使用 VerifyData 方法，直接把訊息 Hash 的動作交給了方法去處理，我完全不必實作相關 Hash 方法。&lt;br /&gt;&lt;br /&gt;這次修改後，產生簽章的結果跟 PHP 的一模一樣，這樣就可以由 C#產生簽章，由 PHP 接收來驗證，進而確認使用者身份，伺服器端也可以利用 SESSION 暫時紀錄結果，就不必每次都要驗證。預設 30 分鐘 SESSION 會過期，到時候再驗證一次即可。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-2070653626469101118?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/2070653626469101118/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-45-digital-signature.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2070653626469101118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2070653626469101118'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-45-digital-signature.html' title='PKI Research #4.5 - Digital Signature 再臨'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-7886509763878860026</id><published>2009-08-26T17:23:00.002+08:00</published><updated>2009-08-26T19:35:42.970+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>mod_jk (Apache + Tomcat) 在 Ubuntu 下的設定方式</title><content type='html'>因為組員只會寫JSP，所以原本的Apache以外勢必還要再架設一個跑JSP的服務，我就想到了 Tomcat。因為 Ubuntu 的套件庫很多已經編譯好的玩意，連相依性都幫我考慮好了，很方便。所以我就打開 Synaptic 套件管理工具來找尋 Tomcat 安裝。&lt;br /&gt;&lt;br /&gt;安裝的是 Tomcat6，連帶安裝了 OpenJDK 等 Java 函式庫。我突然看到還有 mod_jk 可以安裝，說明是說可以把 Tomcat 跟 Apache 連接起來，透過 Apache 就可以執行 JSP (說穿了就是扮演代理角色)。因為 Apache 的效能比 Tomcat 還要好，所以透過 mod_jk 不但可以除去網址老是有 8080 Port 的不便，也可以獲得 Apache 的代理效能。&lt;br /&gt;&lt;br /&gt;全部利用 Synaptic 套件管理工具安裝完後，mod_jk還需要手動設定，而且還滿多地方需要手動設定不然按照預設值是跑不起來的地方，不知道是不是版本的關係。我使用 Ubuntu 9.04 Server 版。&lt;hr /&gt;&lt;br /&gt;首先，要先去修改 /etc/libapache2-mod-jk/workers.properties 這個檔案。這個檔案是 mod_jk 使用，作為 Apache 跟 Tomcat 溝通的工人 (Worker)。使用 vi 打開後主要修改幾處地方：&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;workers.tomcat_home=/usr/share/tomcat6&lt;br /&gt;這個值預設是安裝 Tomcat 5 的位置，因為我是安裝新版的 6 版，不修改一定不能用。改成 /usr/share/tomcat6 就可以順利指定 Tomcat6 的目錄。&lt;br /&gt;&lt;br /&gt;workers.java_home=/usr/lib/jvm/default-java&lt;br /&gt;這個值預設是 JavaVM 沒錯，但是現在已經有開放原始碼的 OpenJRE/OpenJDK，如果你也是安裝了 OpenJRE，那記得改一下位置: /usr/lib/jvm/default-java，這個路徑是一個 Symbolic Link，不知道其他版本是不是也有這個 link。&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;接下來請到 /etc/apache2/mods-available，打 ls 查看一下可以發現有 jk.load，這是載入 mod_jk 模組的設定檔，但卻沒看到對應的 jk.conf (照理說是 mod_jk 的設定)，查了一下發現在 /usr/share/doc/libapache2-mod-jk 目錄下有 httpd_example_apache2.conf 範例設定檔，將這個檔案 cp 到 /etc/apache2/mods-available 並改名為 jk.conf 以方便作業。接著，打開檔案編輯。&lt;br /&gt;&lt;br /&gt;這個檔案預設上是差不多可以用了，但是還是需要修改：&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;加上一行 JkMountCopy All&lt;br /&gt;加這行的用意是因為預設 mod_jk 只會運作在 Apache 主網站，其他的虛擬網站 (VirtualHost) 設定不會套用。但是 Ubuntu 預設的結構是，主網站也是使用虛擬網站設定，並沒有主網站設定，所以按照預設值 mod_jk 會無法對應到正確的檔案 (這可以從 log 看的出來)。而這行就是將設定複製到全部的虛擬網站。&lt;br /&gt;&lt;br /&gt;因為我的網站設定只有 80 port 跟 443 port，而且網站內容一模一樣，這樣的設定沒有什麼問題。但是如果你的虛擬網站很複雜，各自有不同內容，那就請只在想要連接到 Tomcat 的網站設定檔內修改加入一行 JkMountCopy On，讓你指定的虛擬網站能夠正常運作 mod_jk 設定。&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;結束編輯後，我們還要建立一個 Symbolic Link 讓 Apache 讀取。到 /etc/apache2/mods-enabled 執行以下指令：&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;ln -s ../mods-available/jk.conf jk.conf&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;最後重新啟動 Apache (執行 /etc/init.d/apache2 restart 指令)，就大功告成了。&lt;hr /&gt;&lt;br /&gt;結果就是 http://127.0.0.1/*.jsp 會自動對應到 http://127.0.0.1:8080/*.jsp，如果你想要更特別的設定，打開 /etc/apache2/mods-available/jk.conf 就可以自由新增。&lt;br /&gt;&lt;br /&gt;JkMount /*.jsp ajp13_worker&lt;br /&gt;JkMount /*/servlet/ ajp13_worker&lt;br /&gt;&lt;br /&gt;這是預設的設定，用意就是將符合的條件送給 Tomcat 處理。所以我打 /test.jsp 就會送到 :8080/test.jsp&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-7886509763878860026?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/7886509763878860026/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/modjk-apache-tomcat-ubuntu.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7886509763878860026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7886509763878860026'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/modjk-apache-tomcat-ubuntu.html' title='mod_jk (Apache + Tomcat) 在 Ubuntu 下的設定方式'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-5757889533472708868</id><published>2009-08-24T10:50:00.003+08:00</published><updated>2009-08-24T10:55:56.146+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='員工資料庫'/><title type='text'>員工資料庫　介面　申請單　JSP上做MD5</title><content type='html'>員工資料庫完成&lt;br /&gt;增（給員工填的申請表單）&lt;br /&gt;刪（與列表、查合一）&lt;br /&gt;改&lt;br /&gt;查&lt;br /&gt;介面皆讓大家看過&lt;br /&gt;就不截圖了...&lt;br /&gt;外觀上或功能上有意見請在此篇回應&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;再來說到身份ID做hash部份&lt;br /&gt;使用到java.security內的方法MessagerDigest&lt;br /&gt;我們得先import java.security.*後&lt;br /&gt;執行如此下的方法&lt;a href="http://snook.ca/archives/java/create_md5_hash/"&gt;（參考資料）&lt;/a&gt;&lt;br /&gt;&lt;pre style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;MessageDigest mdAlgorithm = MessageDigest.getInstance("MD5")&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;mdAlgorithm.update(User_ID.getBytes())&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt; byte[] digest = mdAlgorithm.digest()&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt; StringBuffer hexString = new StringBuffer()&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;   for (int i = 0&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt; i &amp;lt; digest.length&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt; i++) &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;   User_ID &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(187, 121, 119); font-weight: bold;"&gt;Integer&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;toHexString&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;0xFF&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;&amp;amp;&lt;/span&gt; digest&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;User_ID&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;length&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;              User_ID &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"0"&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt; User_ID&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;         hexString&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;append&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;User_ID&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt; User_ID=hexString.toString()&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;就可以成功執行hash動作&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-5757889533472708868?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/5757889533472708868/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/jspmd5.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5757889533472708868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5757889533472708868'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/jspmd5.html' title='員工資料庫　介面　申請單　JSP上做MD5'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-1072997409864589669</id><published>2009-08-18T21:09:00.014+08:00</published><updated>2009-08-19T01:28:23.156+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenCA'/><title type='text'>PKI Research #5 - 使用 OpenCA 產生的憑證跟加密過的私鑰</title><content type='html'>本篇是研究最卡的部分，足足卡了三天。欲知原因以下見曉。(關鍵字：PKCS#8, PKCS#5)&lt;br /&gt;&lt;br /&gt;因為伊達說已經完成研究 OpenCA 發憑證的部分，因此我們使用 OpenCA 的最大目的「產生憑證、私鑰檔和 CRL 憑證廢止清冊」就已經達成，再來就是要研究如何拿來用。&lt;br /&gt;&lt;br /&gt;OpenCA 主要使用 MySQL 來儲存相關資料，舉凡憑證申請、憑證存放、CA 憑證、CRL 憑證廢止清冊等全部都在資料庫內，而不是一般的檔案。以 phpMyAdmin 登入後可以看到。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_YTQXzGpyark/SoqtEfbk0vI/AAAAAAAAAyc/jmBwMhf48ss/s1600-h/openca_01.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 160px;" src="http://2.bp.blogspot.com/_YTQXzGpyark/SoqtEfbk0vI/AAAAAAAAAyc/jmBwMhf48ss/s320/openca_01.png" alt="" id="BLOGGER_PHOTO_ID_5371295798260978418" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_YTQXzGpyark/SoqtE4MaTDI/AAAAAAAAAyk/7W8oT3NUt3U/s1600-h/openca_02.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 174px;" src="http://2.bp.blogspot.com/_YTQXzGpyark/SoqtE4MaTDI/AAAAAAAAAyk/7W8oT3NUt3U/s320/openca_02.png" alt="" id="BLOGGER_PHOTO_ID_5371295804908260402" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;最重要的就是 certificate 資料表了，data 欄位就是重點。裡面存放著憑證以及私鑰檔，我們只要取出來應該就可以利用了吧。我當初是這麼想，但是他的私鑰檔卻經過 DES 加密 (「私鑰經過 PKCS#5 密碼加密標準 "PBEwithMD5andDES-CBC" 加密過的」PKCS#8 私鑰格式標準)，檔案格式看起來像這樣：&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;-----BEGIN ENCRYPTED PRIVATE KEY-----&lt;br /&gt;MIIBgTAbBgkqhkiG9w0BBQMwDgQIjgXxhGkmgGcCAggABIIBYEXZfHjLUnXJ8h+F&lt;br /&gt;...&lt;br /&gt;mtuOc9U=&lt;br /&gt;-----END ENCRYPTED PRIVATE KEY-----&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;看得出跟一般 OpenSSL 產生的未加密的私鑰檔不同吧，如下 (純粹私鑰，非 PKCS#8 格式)：&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;-----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;MIIBOQIBAAJBAOWeK9TSYVnPEkmK45TeI7NrC8MzvwabSVg1aEuTmcNkLRg/Qibv&lt;br /&gt;...&lt;br /&gt;Ft4zOc8TnbXnGxXRfGVG0RZfXmxcQNv2yX2G4Vc=&lt;br /&gt;-----END RSA PRIVATE KEY-----&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;如果以為 PKCS#8 私鑰 key 檔能跟 OpenSSL 的私鑰 key 檔一樣讀取操作 (&lt;a href="http://www.blogger.com/2009/08/pki-research-3.html"&gt;PKI Research #3 - RSA 加解密&lt;/a&gt;)，那你就錯了。你會發現 keyPair 永遠是 null，因為察看原始碼才發現，&lt;a href="https://www.cryptool.org/trac/CrypTool2/browser/trunk/CrypPlugins/bouncycastle/src/openssl/PEMReader.cs"&gt;PemReader&lt;/a&gt; 沒有特別處理 BEGIN (ENCRYPTED) PRIVATE KEY 的加密私鑰檔 (90 行 switch 開始)，更簡單的說法就是 PemReader 不支援 PKCS#8 格式私鑰檔，所以只好自己找方法了。&lt;br /&gt;&lt;br /&gt;由於中文極度缺乏相關資源，英文的資源雖然有找到類似的討論串，但也是跟我有著一樣的疑問，而沒有人回答。例如：&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bytes.com/topic/net/answers/162428-pkcs-8-support"&gt;PKCS#8 Support&lt;/a&gt; (沒人鳥他)&lt;/li&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/809590/how-can-i-decode-a-pkcs5-encrypted-pkcs8-private-key-in-java"&gt;How can I decode a PKCS#5 encrypted PKCS#8 Private Key in Java&lt;/a&gt; (不過這是 Java 解法)&lt;/li&gt;&lt;li&gt;&lt;a href="http://osdir.com/ml/encryption.cryptopp/2006-06/msg00016.html"&gt;Re: RSA Private Key BER decode error: msg#00016&lt;/a&gt; (這篇點出手工實作法，是我首先嘗試的目標)&lt;/li&gt;&lt;li&gt;&lt;a href="http://osdir.com/ml/encryption.bouncy-castle.devel/2005-05/msg00019.html"&gt;PKCS8 decrypt Privatekey: msg#00019&lt;/a&gt; (跟我一樣的問題，PemReader always return null)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;其實還有很多，但是我一時忘了。嘗試用 PBEwithMD5andDES-CBC 當關鍵字知道 &lt;a href="http://www.bouncycastle.org/specifications.html"&gt;Bouncy Castle&lt;/a&gt; 的 Org.BouncyCastle.Security.PbeUtilities 有支援，但是它的說明手冊不夠完整 (或者該說，沒這種玩意，只有 API)，到底是怎樣的使用法也沒人提到。於是我們就來看 &lt;a href="https://www.cryptool.org/trac/CrypTool2/browser/trunk/CrypPlugins/bouncycastle/src/security/PbeUtilities.cs"&gt;PbeUtilities.cs 的原始碼&lt;/a&gt;吧：&lt;hr /&gt;&lt;br /&gt;如果你想知道為什麼是 PKCS#5 PBEwithMD5andDES-CBC 加密格式，用 OpenSSL asn1parse -in 檔案路徑 就可以查看 ASN.1 結構，就會寫到。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_YTQXzGpyark/SoqzFBp2bCI/AAAAAAAAAys/FrIDH5HsH5Q/s1600-h/openca_03.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 206px;" src="http://3.bp.blogspot.com/_YTQXzGpyark/SoqzFBp2bCI/AAAAAAAAAys/FrIDH5HsH5Q/s320/openca_03.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5371302404517424162" /&gt;&lt;/a&gt;&lt;hr /&gt;&lt;br /&gt;原始碼果然定義一堆加密的方法，這下子有希望了。看了一下大概是像這樣子使用：&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;IO&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Text&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Asn1&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Crypto&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Pkcs&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Security&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;const&lt;/span&gt; String pemp8header &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;-----BEGIN ENCRYPTED PRIVATE KEY-----&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;const&lt;/span&gt; String pemp8footer &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;-----END ENCRYPTED PRIVATE KEY-----&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;char&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; password &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;xxxxxx&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToCharArray&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// 解密密碼&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// 取出檔案中 BASE64 編碼的部分，還原&lt;/span&gt;&lt;br /&gt;StringBuilder sb &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; StringBuilder&lt;span style='color:#808030; '&gt;(&lt;/span&gt;File&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadAllText&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;B:\tmp.key&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;sb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Replace&lt;span style='color:#808030; '&gt;(&lt;/span&gt;pemp8header&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;sb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Replace&lt;span style='color:#808030; '&gt;(&lt;/span&gt;pemp8footer&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;String pubstr &lt;span style='color:#808030; '&gt;=&lt;/span&gt; sb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Trim&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; binkey &lt;span style='color:#808030; '&gt;=&lt;/span&gt; Convert&lt;span style='color:#808030; '&gt;.&lt;/span&gt;FromBase64String&lt;span style='color:#808030; '&gt;(&lt;/span&gt;pubstr&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;var info &lt;span style='color:#808030; '&gt;=&lt;/span&gt; EncryptedPrivateKeyInfo&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetInstance&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Asn1Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;FromByteArray&lt;span style='color:#808030; '&gt;(&lt;/span&gt;binkey&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// 開始建立解密引擎，準備進行 DES-CBC 解密&lt;/span&gt;&lt;br /&gt;var algId &lt;span style='color:#808030; '&gt;=&lt;/span&gt; info&lt;span style='color:#808030; '&gt;.&lt;/span&gt;EncryptionAlgorithm&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;var cipher &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;BufferedBlockCipher&lt;span style='color:#808030; '&gt;)&lt;/span&gt; PbeUtilities&lt;span style='color:#808030; '&gt;.&lt;/span&gt;CreateEngine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;algId&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ObjectID&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;var param &lt;span style='color:#808030; '&gt;=&lt;/span&gt; PbeUtilities&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GenerateCipherParameters&lt;span style='color:#808030; '&gt;(&lt;/span&gt;algId&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ObjectID&lt;span style='color:#808030; '&gt;,&lt;/span&gt; password&lt;span style='color:#808030; '&gt;,&lt;/span&gt; algId&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Parameters&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;cipher&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Init&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;false&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; param&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// 取出加密資料，進行解密&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; data &lt;span style='color:#808030; '&gt;=&lt;/span&gt; info&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetEncryptedData&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; outBytes &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;cipher&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetOutputSize&lt;span style='color:#808030; '&gt;(&lt;/span&gt;data&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Length&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;int&lt;/span&gt; len &lt;span style='color:#808030; '&gt;=&lt;/span&gt; cipher&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ProcessBytes&lt;span style='color:#808030; '&gt;(&lt;/span&gt;data&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; data&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Length&lt;span style='color:#808030; '&gt;,&lt;/span&gt; outBytes&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;try&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    len &lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; cipher&lt;span style='color:#808030; '&gt;.&lt;/span&gt;DoFinal&lt;span style='color:#808030; '&gt;(&lt;/span&gt;outBytes&lt;span style='color:#808030; '&gt;,&lt;/span&gt; len&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;catch&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Exception e&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;throw&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Exception&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;failed DoFinal - exception &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; e&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// outBytes 為解密完的 PrivateKeyInfo (PKCS#8)，接著取出 PrivateKey&lt;/span&gt;&lt;br /&gt;var p &lt;span style='color:#808030; '&gt;=&lt;/span&gt; PrivateKeyInfo&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetInstance&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Asn1Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;FromByteArray&lt;span style='color:#808030; '&gt;(&lt;/span&gt;outBytes&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;var rsa &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaPrivateKeyStructure&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Asn1Sequence&lt;span style='color:#808030; '&gt;)&lt;/span&gt; p&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PrivateKey&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// privSpec 可用於解密&lt;/span&gt;&lt;br /&gt;var privSpec &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaKeyParameters&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;true&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Modulus&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PrivateExponent&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;手工實作法的步驟很繁雜，有沒有更好的方法呢？&lt;br /&gt;&lt;br /&gt;想想可能還有其他已經包好的方法用了 PbeUtilities 來讀取加密私鑰了，就查查看。果不其然又讓我發現了 &lt;a href="https://www.cryptool.org/trac/CrypTool2/browser/trunk/CrypPlugins/bouncycastle/src/pkcs/PrivateKeyInfoFactory.cs"&gt;PrivateKeyInfoFactory.cs&lt;/a&gt; 原始碼，原來只要幾行：&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;IO&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Text&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Asn1&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Crypto&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Pkcs&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Security&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;const&lt;/span&gt; String pemp8header &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;-----BEGIN ENCRYPTED PRIVATE KEY-----&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;const&lt;/span&gt; String pemp8footer &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;-----END ENCRYPTED PRIVATE KEY-----&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;char&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; password &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;xxxxxx&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToCharArray&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// 解密密碼&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// 取出檔案中 BASE64 編碼的部分，還原&lt;/span&gt;&lt;br /&gt;StringBuilder sb &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; StringBuilder&lt;span style='color:#808030; '&gt;(&lt;/span&gt;File&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadAllText&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;B:\tmp.key&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;sb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Replace&lt;span style='color:#808030; '&gt;(&lt;/span&gt;pemp8header&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;sb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Replace&lt;span style='color:#808030; '&gt;(&lt;/span&gt;pemp8footer&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;String pubstr &lt;span style='color:#808030; '&gt;=&lt;/span&gt; sb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Trim&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; binkey &lt;span style='color:#808030; '&gt;=&lt;/span&gt; Convert&lt;span style='color:#808030; '&gt;.&lt;/span&gt;FromBase64String&lt;span style='color:#808030; '&gt;(&lt;/span&gt;pubstr&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;var info &lt;span style='color:#808030; '&gt;=&lt;/span&gt; EncryptedPrivateKeyInfo&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetInstance&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Asn1Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;FromByteArray&lt;span style='color:#808030; '&gt;(&lt;/span&gt;binkey&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// 重點方法: PrivateKeyInfoFactory.CreatePrivateKeyInfo() 一行抵十行&lt;/span&gt;&lt;br /&gt;var p &lt;span style='color:#808030; '&gt;=&lt;/span&gt; PrivateKeyInfoFactory&lt;span style='color:#808030; '&gt;.&lt;/span&gt;CreatePrivateKeyInfo&lt;span style='color:#808030; '&gt;(&lt;/span&gt;password&lt;span style='color:#808030; '&gt;,&lt;/span&gt; info&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;var rsa &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaPrivateKeyStructure&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Asn1Sequence&lt;span style='color:#808030; '&gt;)&lt;/span&gt; p&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PrivateKey&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;// privSpec 可用於解密&lt;/span&gt;&lt;br /&gt;var privSpec &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaKeyParameters&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;true&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Modulus&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PrivateExponent&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;br /&gt;總結：開放原始碼是有必要的，畢竟最後還是得看原始碼找答案的嘛 (大誤)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-1072997409864589669?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/1072997409864589669/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-5-using-openca-certificate.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1072997409864589669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1072997409864589669'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-5-using-openca-certificate.html' title='PKI Research #5 - 使用 OpenCA 產生的憑證跟加密過的私鑰'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_YTQXzGpyark/SoqtEfbk0vI/AAAAAAAAAyc/jmBwMhf48ss/s72-c/openca_01.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-6833594878523773882</id><published>2009-08-14T00:57:00.010+08:00</published><updated>2009-08-14T15:42:52.296+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenCA'/><title type='text'>OpenCA 新增憑證　&amp; 匯出</title><content type='html'>嗯&lt;br /&gt;今天來說說那個OpenCA弄新憑證＆匯出我們要的資料的方法&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gVD4GG_1J10/SoRGlnQVfWI/AAAAAAAAABo/DDkmqR6QI5A/s1600-h/SNAG-0000.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 400px; height: 185px;" src="http://2.bp.blogspot.com/_gVD4GG_1J10/SoRGlnQVfWI/AAAAAAAAABo/DDkmqR6QI5A/s320/SNAG-0000.jpg" alt="" id="BLOGGER_PHOTO_ID_5369494267739077986" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;s&gt;到PKI Init &amp;amp; Config的Initialization&gt;CA administrator&lt;/s&gt;&lt;br /&gt;到Pub頁面，下方就有Request a Certificate&lt;br /&gt;&lt;br /&gt;去request一個新的憑證&lt;br /&gt;需要填入的資料表單如下&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gVD4GG_1J10/SoRKpmCAr7I/AAAAAAAAABw/WZhRyKJ1EsE/s1600-h/SNAG-0001.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 233px;" src="http://1.bp.blogspot.com/_gVD4GG_1J10/SoRKpmCAr7I/AAAAAAAAABw/WZhRyKJ1EsE/s320/SNAG-0001.jpg" alt="" id="BLOGGER_PHOTO_ID_5369498734176546738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;基本上,只有名稱跟email是一定必填的&lt;br /&gt;若要做給使用者填寫的表格,要再思考&lt;br /&gt;其他欄位是否有必要性&lt;br /&gt;&lt;br /&gt;精過一番精密...喔不　是簡單的過程後&lt;br /&gt;這個"Request"就成功發出了　接下來就到CA operation去做　憑‧證　承～～認！&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gVD4GG_1J10/SoRZzh_RGoI/AAAAAAAAAB4/Da-JVrLg7TQ/s1600-h/SNAG-0002.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 236px; height: 55px;" src="http://2.bp.blogspot.com/_gVD4GG_1J10/SoRZzh_RGoI/AAAAAAAAAB4/Da-JVrLg7TQ/s320/SNAG-0002.jpg" alt="" id="BLOGGER_PHOTO_ID_5369515397564406402" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;來這　選NEW(即能看到新進的憑證伸請要求)&lt;br /&gt;然後承認後&lt;br /&gt;可以到Information &gt; CA Certificates &gt; valid (合法的Certificates）&lt;br /&gt;&lt;br /&gt;看到列表入下&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_gVD4GG_1J10/SoRcSsZ_7cI/AAAAAAAAACQ/cunkDIXYPmc/s1600-h/SNAG-0003_mod.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 43px;" src="http://4.bp.blogspot.com/_gVD4GG_1J10/SoRcSsZ_7cI/AAAAAAAAACQ/cunkDIXYPmc/s320/SNAG-0003_mod.jpg" alt="" id="BLOGGER_PHOTO_ID_5369518131960081858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;那麼點選就能進入該觀看Certificate資料&lt;br /&gt;並選擇下載(格式可選)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gVD4GG_1J10/SoRbgMIjsBI/AAAAAAAAACI/5Co2EBfvets/s1600-h/SNAG-0004.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 79px;" src="http://2.bp.blogspot.com/_gVD4GG_1J10/SoRbgMIjsBI/AAAAAAAAACI/5Co2EBfvets/s320/SNAG-0004.jpg" alt="" id="BLOGGER_PHOTO_ID_5369517264303534098" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;選我們要的格式就OK了w&lt;br /&gt;Got it!  Go to next.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-6833594878523773882?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/6833594878523773882/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/openca.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6833594878523773882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6833594878523773882'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/openca.html' title='OpenCA 新增憑證　&amp; 匯出'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_gVD4GG_1J10/SoRGlnQVfWI/AAAAAAAAABo/DDkmqR6QI5A/s72-c/SNAG-0000.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-112837448086750576</id><published>2009-08-13T14:21:00.002+08:00</published><updated>2009-08-13T14:23:12.978+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發週報'/><title type='text'>流程</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_JnRGUYYN22s/SoOxEn208QI/AAAAAAAAAIo/JXbvP3As8Pg/s1600-h/a.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 290px; height: 320px;" src="http://4.bp.blogspot.com/_JnRGUYYN22s/SoOxEn208QI/AAAAAAAAAIo/JXbvP3As8Pg/s320/a.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5369329873732301058" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;可能還是要先多想想需要甚麼功能吧!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-112837448086750576?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/112837448086750576/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/blog-post.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/112837448086750576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/112837448086750576'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/blog-post.html' title='流程'/><author><name>Jimmy</name><uri>http://www.blogger.com/profile/14068193898204652397</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_JnRGUYYN22s/SoOxEn208QI/AAAAAAAAAIo/JXbvP3As8Pg/s72-c/a.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-2745739025004396390</id><published>2009-08-13T10:29:00.005+08:00</published><updated>2009-08-15T15:49:54.424+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>各部分研究目標</title><content type='html'>OpenCA&lt;br /&gt;- 功能: 輸入使用者個人資訊以產生伺服器簽發憑證跟私鑰檔，並能產生廢止清冊 CRLs&lt;br /&gt;- 目的: 產生憑證檔跟私鑰檔來驗證，還有 CRLs 讓程式判斷憑證是否可使用&lt;br /&gt;- 研究: 如何申請使用者憑證，並能取得憑證檔&lt;br /&gt;&lt;br /&gt;PKI&lt;br /&gt;- 功能: 公開金鑰加解密、數位簽章及驗證&lt;br /&gt;- 目的: 使用者身分鑑別&lt;br /&gt;- 研究: 得出公鑰 crt 憑證、RSA 私鑰 key，讀取 CRL 檢查是否已撤銷&lt;br /&gt;&lt;br /&gt;RFID&lt;br /&gt;- 功能: 讀取/寫入私鑰檔跟個人設定之類的資訊&lt;br /&gt;- 目的: 當作使用者身分鑑別的媒介&lt;br /&gt;- 研究: RFID Tag Block 寫入資料區塊的利用分配&lt;br /&gt;&lt;br /&gt;MySQL&lt;br /&gt;- 功能: 儲存使用者相關資料&lt;br /&gt;- 目的: 跟 RFID 連動取得進一步的使用者資料&lt;br /&gt;- 研究: 資料表要放什麼&lt;br /&gt;&lt;br /&gt;Apache&lt;br /&gt;- 功能: 網頁伺服器&lt;br /&gt;- 目的: 上傳/下載公文、個人檔案的傳輸媒介，利用 SSL 加密&lt;br /&gt;- 研究: 如何讓使用者上下傳檔案&lt;br /&gt;&lt;br /&gt;C#&lt;br /&gt;- 功能: 撰寫程式&lt;br /&gt;- 目的: 利用 RFID 讀取私鑰檔，連接 MySQL 取得資料進行驗證。前端 GUI 顯示公文、個人檔案等等&lt;br /&gt;- 研究: 如何結合以上功能寫出程式&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-2745739025004396390?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/2745739025004396390/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/notitle.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2745739025004396390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2745739025004396390'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/notitle.html' title='各部分研究目標'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-9007682993709696161</id><published>2009-08-13T10:15:00.018+08:00</published><updated>2009-08-13T14:34:05.139+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><title type='text'>DB裡面</title><content type='html'>Database裡面應該會這樣放&lt;br /&gt;覺得可以再更改的地方再提出吧!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ID_Transformation&lt;br /&gt;&lt;table align="" border="1" cellpadding="1" cellspacing="1" width="100"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;Tag_ID&lt;/td&gt;&lt;td style="text-align: center;"&gt;Database_ID&lt;/td&gt;&lt;td style="text-align: center;"&gt;Changed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;1212343456567878&lt;/td&gt;&lt;td style="text-align: center;"&gt;98000001&lt;/td&gt;&lt;td style="text-align: center;"&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;1212343456567899&lt;/td&gt;&lt;td style="text-align: center;"&gt;98000002&lt;/td&gt;&lt;td style="text-align: center;"&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;1212343456567800&lt;/td&gt;&lt;td style="text-align: center;"&gt;98000003&lt;/td&gt;&lt;td style="text-align: center;"&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;1212343456567812&lt;/td&gt;&lt;td style="text-align: center;"&gt;98000004&lt;/td&gt;&lt;td style="text-align: center;"&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;//Tag_ID 代表 Tag的ID&lt;br /&gt;//Database_ID 代表Database上的ID&lt;br /&gt;//changed 代表 Tag_ID更改次數，也可以代表Tag遺失次數！XD&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Key(Key的儲存)&lt;br /&gt;&lt;table align="" border="1" cellpadding="1" cellspacing="1" width="200"&gt;&lt;tbody&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt;Database_ID&lt;/td&gt;     &lt;td style="text-align: center;"&gt;Public_Key&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000001&lt;/td&gt;     &lt;td style="text-align: center;"&gt; qwerasdfzxcvtgbh&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000002&lt;/td&gt;     &lt;td style="text-align: center;"&gt; qasdfghjklmnbvcx&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000003&lt;/td&gt;     &lt;td style="text-align: center;"&gt; qasdfghjklmnbaaa&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000004&lt;/td&gt;     &lt;td style="text-align: center;"&gt;  qasdfghjklmasdfg&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;// Public_Key 儲存 public key，認證用！&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Paper(記錄公文的資訊)&lt;br /&gt;&lt;table align="" border="1" cellpadding="1" cellspacing="1" width="200"&gt;&lt;tbody&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt;Database_ID&lt;/td&gt;     &lt;td style="text-align: center;"&gt;Paper_Read&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000001&lt;/td&gt;     &lt;td style="text-align: center;"&gt; y&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000002&lt;/td&gt;     &lt;td style="text-align: center;"&gt; n&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000003&lt;/td&gt;     &lt;td style="text-align: center;"&gt; n&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;     &lt;td style="text-align: center;"&gt; 98000004&lt;/td&gt;     &lt;td style="text-align: center;"&gt;  y&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;// Paper_Read 代表 公文已讀與否!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Identity(user身分)&lt;br /&gt;&lt;table align="" border="1" cellpadding="1" cellspacing="1" width="200"&gt;&lt;tbody&gt;&lt;tr&gt;       &lt;td style="text-align: center;"&gt;Database_ID&lt;/td&gt;       &lt;td style="text-align: center;"&gt;Name&lt;/td&gt;&lt;td style="text-align: center;"&gt;Level&lt;/td&gt;&lt;td style="text-align: center;"&gt;User_ID&lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;       &lt;td style="text-align: center;"&gt; 98000001&lt;/td&gt;       &lt;td style="text-align: center;"&gt; Jimmy     &lt;/td&gt;&lt;td style="text-align: center;"&gt; Chairman     &lt;/td&gt;&lt;td style="text-align: center;"&gt; A123456789       &lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;       &lt;td style="text-align: center;"&gt; 98000002&lt;/td&gt;        &lt;td style="text-align: center;"&gt; RobertCamel     &lt;/td&gt;&lt;td style="text-align: center;"&gt; Manager     &lt;/td&gt;&lt;td style="text-align: center;"&gt; B123456789   &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;       &lt;td style="text-align: center;"&gt; 98000003&lt;/td&gt;       &lt;td style="text-align: center;"&gt; Scribe     &lt;/td&gt;&lt;td style="text-align: center;"&gt; Manager     &lt;/td&gt;&lt;td style="text-align: center;"&gt; C123456789   &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;       &lt;td style="text-align: center;"&gt; 98000004&lt;/td&gt;       &lt;td style="text-align: center;"&gt; Soultaker      &lt;/td&gt;&lt;td style="text-align: center;"&gt; Chairman      &lt;/td&gt;&lt;td style="text-align: center;"&gt; D123456789   &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;// Level 代表 職位&lt;br /&gt;// User_ID 代表 身分證字號&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ENV_Set(用來儲存user的設定值)&lt;br /&gt;&lt;table style="width: 244px; height: 119px;" align="" border="1" cellpadding="1" cellspacing="1"&gt;&lt;tbody&gt;&lt;tr&gt;        &lt;td style="text-align: center;"&gt;Database_ID&lt;/td&gt;        &lt;td style="text-align: center;"&gt;Set_1&lt;/td&gt;&lt;td style="text-align: center;"&gt;Set_2&lt;/td&gt;&lt;td style="text-align: center;"&gt;Set_3&lt;/td&gt;    &lt;/tr&gt;&lt;tr&gt;        &lt;td style="text-align: center;"&gt; 98000001&lt;/td&gt;        &lt;td style="text-align: center;"&gt; 0 &lt;/td&gt;&lt;td style="text-align: center;"&gt; 1 &lt;/td&gt;&lt;td style="text-align: center;"&gt; 1 &lt;/td&gt;    &lt;/tr&gt;&lt;tr&gt;        &lt;td style="text-align: center;"&gt; 98000002&lt;/td&gt;        &lt;td style="text-align: center;"&gt; 1 &lt;/td&gt;&lt;td style="text-align: center;"&gt; 1 &lt;/td&gt;&lt;td style="text-align: center;"&gt; 1 &lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;        &lt;td style="text-align: center;"&gt; 98000003&lt;/td&gt;        &lt;td style="text-align: center;"&gt; 0 &lt;/td&gt;&lt;td style="text-align: center;"&gt; 1 &lt;/td&gt;&lt;td style="text-align: center;"&gt; 0 &lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;        &lt;td style="text-align: center;"&gt; 98000004&lt;/td&gt;        &lt;td style="text-align: center;"&gt; 1      &lt;/td&gt;&lt;td style="text-align: center;"&gt; 0      &lt;/td&gt;&lt;td style="text-align: center;"&gt; 1    &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;// set_1 代表 user環境的設定 0:off   1:on (例如button要不要透明化!?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-9007682993709696161?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/9007682993709696161/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/db.html#comment-form' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/9007682993709696161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/9007682993709696161'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/db.html' title='DB裡面'/><author><name>Jimmy</name><uri>http://www.blogger.com/profile/14068193898204652397</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-7891344258235775850</id><published>2009-08-12T10:33:00.002+08:00</published><updated>2009-08-12T10:42:49.447+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>架設 OpenCA 1.0.2 on Ubuntu 9.04 Server</title><content type='html'>終於完成啦！完全照著嚕嚕咪的教學(&lt;a href="http://www.wretch.cc/blog/hiyao/10201668"&gt;見此&lt;/a&gt;)照抄就完成了，沒啥好說的。&lt;br /&gt;&lt;br /&gt;倒是順便安裝了 phpMyAdmin 套件 (apt-get phpmyadmin)，不是直接下載原始碼安裝，最後會裝到 /usr/share/phpmyadmin，但是網頁預設目錄是 /var/www，所以要建立一個 Symbolic link，在 /var/www 目錄下 ln -s /usr/share/phpmyadmin phpmyadmin 就可以建立一個連結，不必複製整個目錄就可以使用。&lt;br /&gt;&lt;br /&gt;既然架好了，請其他人盡速開始研究 MySQL 跟 OpenCA 囉。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-7891344258235775850?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/7891344258235775850/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/openca-102-on-ubuntu-904-server.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7891344258235775850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7891344258235775850'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/openca-102-on-ubuntu-904-server.html' title='架設 OpenCA 1.0.2 on Ubuntu 9.04 Server'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-368404180234438325</id><published>2009-08-02T23:51:00.006+08:00</published><updated>2009-08-03T14:16:04.750+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>PKI Research #4 - Digital Signature</title><content type='html'>這篇預定要來研究數位簽章。&lt;br /&gt;&lt;br /&gt;數位簽章的方式跟加解密剛好是反過來的，加解密使用公鑰加密，使用私鑰解密；數位簽章卻是使用私鑰簽章，使用公鑰驗證。&lt;br /&gt;&lt;br /&gt;加解密的對象是明文檔案內容，而數位簽章的對象則是明文檔案內容經過雜湊後的值。常用的有 MD5 跟 SHA-1，聽說這兩個都有被碰撞破解的個案，所以使用 SHA256 (SHA-2 家族)。&lt;br /&gt;&lt;br /&gt;.NET Fraamework 的 System.Security.Cryptography 命名空間實作不少相關雜湊，我直接寫成以下方法：&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; useSHA256&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; data&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    SHA256 sha &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; SHA256Managed&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; sha&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ComputeHash&lt;span style='color:#808030; '&gt;(&lt;/span&gt;data&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;流程圖一張：&lt;br /&gt;http://en.wikipedia.org/wiki/File:Digital_Signature_diagram.svg&lt;br /&gt;&lt;br /&gt;先從簽章實作。第一件事就是將文章進行 Hash，我使用上面寫好的 SHA256 方法來製造。然後要將此 Hash 以私鑰加密，因為 X509Certificate2 不能直接支援 RSA Private Key PEM 檔 (範例中使用 DER 格式方便 RFID Tag 儲存)，所以我使用 Bouncy Castle C# 來進行私鑰的讀取，並用來加密 Hash 產生數位簽章 (稱為 Hash')。&lt;br /&gt;&lt;br /&gt;另一邊進行驗證。驗證也需要將文章進行 Hash，以便跟數位簽章比對。一樣使用 SHA256 產生 Hash。然後將數位簽章使用 .crt 憑證內存的公鑰解密 (得到 Hash')，結果拿來跟 Hash 比對。如果完全正確 (Hash' = Hash) 表示文章沒有經過竄改，而且也能確定簽章者正是本人。但是 X509Certificate2 不能直接拿公鑰進行解密 (Decrypt)，而是提供另一個驗證 (VerifyHash) 方法供呼叫，我也搞不懂為什麼不行。&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; signature&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; data&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; hash &lt;span style='color:#808030; '&gt;=&lt;/span&gt; useSHA256&lt;span style='color:#808030; '&gt;(&lt;/span&gt;data&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;try&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        var seq &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;Asn1Sequence&lt;span style='color:#808030; '&gt;)&lt;/span&gt; Asn1Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;FromStream&lt;span style='color:#808030; '&gt;(&lt;/span&gt;File&lt;span style='color:#808030; '&gt;.&lt;/span&gt;OpenRead&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;B:\OpenSSL\1-der.key&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        var rsa &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaPrivateKeyStructure&lt;span style='color:#808030; '&gt;(&lt;/span&gt;seq&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        var privSpec &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaPrivateCrtKeyParameters&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;br /&gt;            rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Modulus&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PublicExponent&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PrivateExponent&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;            rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Prime1&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Prime2&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Exponent1&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Exponent2&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;            rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Coefficient&lt;br /&gt;        &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        var encryptEngine &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Pkcs1Encoding&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaEngine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        encryptEngine&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Init&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;true&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; privSpec&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; encryptEngine&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ProcessBlock&lt;span style='color:#808030; '&gt;(&lt;/span&gt;hash&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; hash&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Length&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Digital Signature&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;catch&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Exception e&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;throw&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; IOException&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;problem creating private key: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; e&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;bool&lt;/span&gt; verify&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; message&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; sig&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; hash &lt;span style='color:#808030; '&gt;=&lt;/span&gt; useSHA256&lt;span style='color:#808030; '&gt;(&lt;/span&gt;message&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    var crt &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; X509Certificate2&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;B:\OpenSSL\1.crt&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Read X509 Certificate file&lt;/span&gt;&lt;br /&gt;    var rsa &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;RSACryptoServiceProvider&lt;span style='color:#808030; '&gt;)&lt;/span&gt; crt&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PublicKey&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Key&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Get public key&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;VerifyHash&lt;span style='color:#808030; '&gt;(&lt;/span&gt;hash&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;SHA256&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; sig&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-368404180234438325?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/368404180234438325/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-4.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/368404180234438325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/368404180234438325'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-4.html' title='PKI Research #4 - Digital Signature'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-3338916191527861089</id><published>2009-08-02T01:10:00.012+08:00</published><updated>2009-08-02T23:51:13.205+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>PKI Research #3 - RSA 加解密</title><content type='html'>CA 部分還沒搞定，但生成憑證簽署方面都可以利用 OpenSSL 來完成。OpenSSL 是開放原始碼專案，在 Unix-like 界非常廣泛，Windows 有別人 Port 好的版本：&lt;a href="http://www.openssl.org/related/binaries.html"&gt;OpenSSL Binary Distributions&lt;/a&gt;，可以下載來玩看看。下指令的方式上一篇已經有許多篇參考資料，不再說明。&lt;br /&gt;&lt;br /&gt;複習一下 .key 檔跟 .crt 檔的樣子：&lt;br /&gt;&lt;br /&gt;user.key: (PEM-encoded)&lt;br /&gt;&lt;blockquote&gt;-----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;MIIBOQIBAAJBAOWeK9TSYVnPEkmK45TeI7NrC8MzvwabSVg1aEuTmcNkLRg/Qibv&lt;br /&gt;B6ST5F056HCk0xvzm5rfO5A+q+4ncBMGMhkCAwEAAQJABGaLoICHrRjy2MX4ppm7&lt;br /&gt;RWz/xLXxK0c+mJotbYVepQf1KYB6kPc4df1t4KrFFgxMyXzdJ/eiegf4j3HFT4Hs&lt;br /&gt;gQIhAPiVVZNSMqp1uUx7OXB3GGW+3uslvA3+NvuAKqVguIo9AiEA7Hf6ykGeuRBN&lt;br /&gt;k2EN+J+Vof4ryzFOtJGH+eyycmKPsQ0CIFJYteZ9nkcVhHKvh1GYQj7CQfpHn8pK&lt;br /&gt;4k/iHz51kexJAiBwKs1kiVHv+QLDSQNmjtRcngNKBB6QWoQEkjlnNsdwNQIgbJYa&lt;br /&gt;Ft4zOc8TnbXnGxXRfGVG0RZfXmxcQNv2yX2G4Vc=&lt;br /&gt;-----END RSA PRIVATE KEY-----&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;user.crt: (PEM-encoded)&lt;br /&gt;&lt;blockquote&gt;-----BEGIN CERTIFICATE-----&lt;br /&gt;MIIBtDCCAV4CCQChpB3R8j5vwDANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJU&lt;br /&gt;VzEPMA0GA1UECBMGVGFpd2FuMQ8wDQYDVQQHEwZUYWl3YW4xHDAaBgNVBAoTE05D&lt;br /&gt;SFUgTUlTIERlcGFydG1lbnQxEjAQBgNVBAMTCXNvdWx0YWtlcjAeFw0wOTA3MzEw&lt;br /&gt;NDE1MDJaFw0xMDA3MzEwNDE1MDJaMGExCzAJBgNVBAYTAlRXMQ8wDQYDVQQIEwZU&lt;br /&gt;YWl3YW4xDzANBgNVBAcTBlRhaXdhbjEcMBoGA1UEChMTTkNIVSBNSVMgRGVwYXJ0&lt;br /&gt;bWVudDESMBAGA1UEAxMJc291bHRha2VyMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB&lt;br /&gt;AOWeK9TSYVnPEkmK45TeI7NrC8MzvwabSVg1aEuTmcNkLRg/QibvB6ST5F056HCk&lt;br /&gt;0xvzm5rfO5A+q+4ncBMGMhkCAwEAATANBgkqhkiG9w0BAQUFAANBAGQhB8VKtY2N&lt;br /&gt;hecmukSUmJkTzFWwT15fPmTGzf0KdrccNCSK2bE/u6bTW9dkUF12MkTaHNVytmKd&lt;br /&gt;u7MoPuNvCnA=&lt;br /&gt;-----END CERTIFICATE-----&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;所以，當我有了 .key 檔 (RSA 私鑰) 跟 .crt 憑證 (含公鑰的憑證) 後，該怎麼使用？這是本篇要研究的目標。&lt;br /&gt;&lt;br /&gt;C# 利用 X.509 憑證加密，網路上有很棒的教學：&lt;a href="http://blog.csdn.net/chnking/archive/2007/09/28/1805117.aspx"&gt;使用X.509数字证书加密解密实务（二）-- 使用RSA证书加密敏感数据&lt;/a&gt;，圖文並茂很容易了解。基本上 .NET Framework 的 &lt;a href="http://msdn.microsoft.com/zh-tw/library/system.security.cryptography.x509certificates.x509certificate2.aspx"&gt;X509Certificate2&lt;/a&gt; 類別非常好用，它屬於 System.Security.Cryptography.X509Certificates 命名空間。只要建構元放入 .crt 憑證檔路徑，就可以抽出公鑰，加密資料。&lt;br /&gt;&lt;br /&gt;解密的話，X509Certificate2 支援公私鑰綁一起的 PKCS#12，但不支援 OpenSSL 直接匯出的私鑰格式 (稱為 PEM 格式)，當你直接指定 .key 檔位置會丟出例外，所以解密要找其他方案。&lt;br /&gt;&lt;br /&gt;剛好無意間找到利用 &lt;a href="http://www.bouncycastle.org/csharp/"&gt;Bouncy Castle for C# API&lt;/a&gt; 直接讀取 PEM 格式 RSA 私鑰進行解密的教學：&lt;a href="http://www.cnprog.com/questions/41/"&gt;用openSSL生成了一对RSA密钥,在C#里面怎么使用它啊？ &lt;/a&gt;，回答的第二項就是我們要的。你可能覺得奇怪它說第三項也可以用啊，但實際上那是讀取 .pfx 或 .p12 的 PKCS#12 個人憑證，直接讀取 OpenSSL RSA 私鑰 PEM 格式檔是絕對不行的。&lt;br /&gt;&lt;br /&gt;DER (&lt;a href="http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules"&gt;Distinguished Encoding Rules&lt;/a&gt;)：&lt;br /&gt;二進位內容，是屬於 &lt;a href="http://zh.wikipedia.org/w/index.php?title=ASN.1&amp;variant=zh-tw"&gt;ASN.1&lt;/a&gt; 制定的編碼之一。&lt;br /&gt;&lt;br /&gt;PEM (&lt;a href="http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail"&gt;Privacy-enhanced Electronic Mail&lt;/a&gt;)：&lt;br /&gt;就是 DER 格式經過 BASE64 編碼後所能見到的內容，通常會有 ----- BEGIN XXX ----- / ----- END XXX ----- 之類的東西包夾起來。由於 PEM 格式採用了 BASE64 編碼，文字都被編成常用的英文數字符號，方便於網路上傳送及複製 (如即時通訊、電子郵件等)。OpenSSL 預設產生的檔案都是 PEM 格式。當然也可以透過 -inform / -outform 來指定 DER 等格式。&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff; overflow:auto'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;IO&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Security&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Cryptography&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Security&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Cryptography&lt;span style='color:#808030; '&gt;.&lt;/span&gt;X509Certificates&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Text&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Asn1&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Asn1&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Pkcs&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Crypto&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Crypto&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Encodings&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Crypto&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Engines&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Crypto&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Parameters&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; Org&lt;span style='color:#808030; '&gt;.&lt;/span&gt;BouncyCastle&lt;span style='color:#808030; '&gt;.&lt;/span&gt;OpenSsl&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;namespace&lt;/span&gt; PKI_RSAEnDecryptDemo &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;class&lt;/span&gt; Program &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; Main&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;string&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; args&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; plainTextByte &lt;span style='color:#808030; '&gt;=&lt;/span&gt; Encoding&lt;span style='color:#808030; '&gt;.&lt;/span&gt;UTF8&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetBytes&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;超爽的，撿到100塊咧～咧？&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; encTextType &lt;span style='color:#808030; '&gt;=&lt;/span&gt; encrypt&lt;span style='color:#808030; '&gt;(&lt;/span&gt;plainTextByte&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;string&lt;/span&gt; base64 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; Convert&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToBase64String&lt;span style='color:#808030; '&gt;(&lt;/span&gt;encTextType&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;base64&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; oristr &lt;span style='color:#808030; '&gt;=&lt;/span&gt; decrypt_DER&lt;span style='color:#808030; '&gt;(&lt;/span&gt;encTextType&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Encoding&lt;span style='color:#808030; '&gt;.&lt;/span&gt;UTF8&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;oristr&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadKey&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; encrypt&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; plainTextByte&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            var crt &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; X509Certificate2&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;B:\OpenSSL\1.crt&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Read X509 Certificate file&lt;/span&gt;&lt;br /&gt;            var rsa &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;RSACryptoServiceProvider&lt;span style='color:#808030; '&gt;)&lt;/span&gt; crt&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PublicKey&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Key&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Get public key&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; Cryptograph &lt;span style='color:#808030; '&gt;=&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Encrypt&lt;span style='color:#808030; '&gt;(&lt;/span&gt;plainTextByte&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;false&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Encrypt&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; Cryptograph&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; decrypt&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; encTextType&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            AsymmetricCipherKeyPair keyPair&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;var reader &lt;span style='color:#808030; '&gt;=&lt;/span&gt; File&lt;span style='color:#808030; '&gt;.&lt;/span&gt;OpenText&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;B:\OpenSSL\1.key&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Direct read pem format RSA private key file&lt;/span&gt;&lt;br /&gt;                keyPair &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;AsymmetricCipherKeyPair&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; PemReader&lt;span style='color:#808030; '&gt;(&lt;/span&gt;reader&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadObject&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;            var decryptEngine &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Pkcs1Encoding&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaEngine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            decryptEngine&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Init&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;false&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; keyPair&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Private&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; decryptEngine&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ProcessBlock&lt;span style='color:#808030; '&gt;(&lt;/span&gt;encTextType&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; encTextType&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Length&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Decrypt&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; decrypt_DER&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;byte&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; encText&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;try&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;                var seq &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;Asn1Sequence&lt;span style='color:#808030; '&gt;)&lt;/span&gt; Asn1Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;FromStream&lt;span style='color:#808030; '&gt;(&lt;/span&gt;File&lt;span style='color:#808030; '&gt;.&lt;/span&gt;OpenRead&lt;span style='color:#808030; '&gt;(&lt;/span&gt;@&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;B:\OpenSSL\1-der.key&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                var rsa &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaPrivateKeyStructure&lt;span style='color:#808030; '&gt;(&lt;/span&gt;seq&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                var privSpec &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaPrivateCrtKeyParameters&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;br /&gt;                    rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Modulus&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PublicExponent&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PrivateExponent&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;                    rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Prime1&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Prime2&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Exponent1&lt;span style='color:#808030; '&gt;,&lt;/span&gt; rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Exponent2&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;                    rsa&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Coefficient&lt;br /&gt;                &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                var decryptEngine &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Pkcs1Encoding&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; RsaEngine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                decryptEngine&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Init&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;false&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; privSpec&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; decryptEngine&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ProcessBlock&lt;span style='color:#808030; '&gt;(&lt;/span&gt;encText&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; encText&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Length&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// Decrypt&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;catch&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Exception e&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;                &lt;span style='color:#800000; font-weight:bold; '&gt;throw&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; IOException&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;problem creating private key: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; e&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;參考資料：&lt;br /&gt;&lt;a href="http://www.ichiayi.com/wiki/tech/openssl_tips"&gt;OpenSSL 常用語法整理&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-3338916191527861089?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/3338916191527861089/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-3.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3338916191527861089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3338916191527861089'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/08/pki-research-3.html' title='PKI Research #3 - RSA 加解密'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-1842567310269621821</id><published>2009-07-31T11:44:00.010+08:00</published><updated>2009-08-03T13:33:11.411+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><title type='text'>PKI  Research #2 - 憑證製作</title><content type='html'>拿舊電腦安裝 OpenCA (on CentOS 5.3) 安裝失敗，無法啟動。看到 Fedora 有自己寫的 &lt;a href="http://pki.fedoraproject.org/wiki/PKI_Main_Page"&gt;Dogtag 憑證系統&lt;/a&gt;，不知道有沒有用，這方面先交給別人實驗。&lt;br /&gt;&lt;br /&gt;我們要 PKI 的目的是要使用產生的公私鑰對來驗證使用者身分，但是發憑證很簡單 (OpenSSL 就可以簽 X.509 了)，但要集中管理使用者金鑰卻很困難，不得不架設 CA 一類的東西，尤其是憑證廢止清冊，這一定要中央集權式管理才可以。OpenSSL 簽憑證並沒有辦法考慮到廢止的問題吧 (頂多自動過期，離職等無法強制廢止) 所以似乎還是要 CA 中央管理憑證。&lt;br /&gt;&lt;br /&gt;我提過我已經可以自行簽發憑證了 (&lt;a href="http://www.imacat.idv.tw/tech/sslcerts.html.zh-tw"&gt;見此 OpenSSL 教學&lt;/a&gt;)，跟教授借來的那本也有提到 &lt;a href="http://www.bouncycastle.org/"&gt;Bouncy Castle&lt;/a&gt; 這個 Java 函式庫可以簽發，但是重點的憑證管理卻隻字未提。還有簽完的 RSA Private Key 檔、憑證申請書和簽發憑證檔都是特定格式，要直接抽出公私鑰對存在 RFID Tag 太難了，我想許多程式設計都是直接將憑證檔案丟去處理的吧。&lt;br /&gt;&lt;br /&gt;以下為絕對沒用過的 RSA Private Key 檔範例：&lt;br /&gt;&lt;blockquote&gt;-----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;MIIBOQIBAAJBAOWeK9TSYVnPEkmK45TeI7NrC8MzvwabSVg1aEuTmcNkLRg/Qibv&lt;br /&gt;B6ST5F056HCk0xvzm5rfO5A+q+4ncBMGMhkCAwEAAQJABGaLoICHrRjy2MX4ppm7&lt;br /&gt;RWz/xLXxK0c+mJotbYVepQf1KYB6kPc4df1t4KrFFgxMyXzdJ/eiegf4j3HFT4Hs&lt;br /&gt;gQIhAPiVVZNSMqp1uUx7OXB3GGW+3uslvA3+NvuAKqVguIo9AiEA7Hf6ykGeuRBN&lt;br /&gt;k2EN+J+Vof4ryzFOtJGH+eyycmKPsQ0CIFJYteZ9nkcVhHKvh1GYQj7CQfpHn8pK&lt;br /&gt;4k/iHz51kexJAiBwKs1kiVHv+QLDSQNmjtRcngNKBB6QWoQEkjlnNsdwNQIgbJYa&lt;br /&gt;Ft4zOc8TnbXnGxXRfGVG0RZfXmxcQNv2yX2G4Vc=&lt;br /&gt;-----END RSA PRIVATE KEY-----&lt;/blockquote&gt;&lt;br /&gt;你能看出這個檔案內的私鑰組成是什麼嗎？&lt;br /&gt;&lt;br /&gt;openssl rsa -in 1.key -text&lt;br /&gt;可看出私鑰的各組成資訊。&lt;br /&gt;&lt;br /&gt;PEM 內文經過 BASE64 解碼後的 DER 編碼有 317 bytes，一個 Tag Block 有 16bytes，也要約 20 格。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;-----BEGIN CERTIFICATE REQUEST-----&lt;br /&gt;MIIBGzCBxgIBADBhMQswCQYDVQQGEwJUVzEPMA0GA1UECBMGVGFpd2FuMQ8wDQYD&lt;br /&gt;VQQHEwZUYWl3YW4xHDAaBgNVBAoTE05DSFUgTUlTIERlcGFydG1lbnQxEjAQBgNV&lt;br /&gt;BAMTCXNvdWx0YWtlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlnivU0mFZzxJJ&lt;br /&gt;iuOU3iOzawvDM78Gm0lYNWhLk5nDZC0YP0Im7wekk+RdOehwpNMb85ua3zuQPqvu&lt;br /&gt;J3ATBjIZAgMBAAGgADANBgkqhkiG9w0BAQUFAANBANOz3JapX/SSbdTCaQiriALm&lt;br /&gt;ZlMeGW+L3XWnj4H7kXVljqsyYv6JJEAnQzdBcw1MiUZDYZqFOYJHxmx56eSIx8o=&lt;br /&gt;-----END CERTIFICATE REQUEST-----&lt;/blockquote&gt;&lt;br /&gt;要求憑證簽發的申請檔，內含有國家、組織、姓名等個人資訊，你看得出來嗎？&lt;br /&gt;&lt;blockquote&gt;-----BEGIN CERTIFICATE-----&lt;br /&gt;MIIBtDCCAV4CCQChpB3R8j5vwDANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJU&lt;br /&gt;VzEPMA0GA1UECBMGVGFpd2FuMQ8wDQYDVQQHEwZUYWl3YW4xHDAaBgNVBAoTE05D&lt;br /&gt;SFUgTUlTIERlcGFydG1lbnQxEjAQBgNVBAMTCXNvdWx0YWtlcjAeFw0wOTA3MzEw&lt;br /&gt;NDE1MDJaFw0xMDA3MzEwNDE1MDJaMGExCzAJBgNVBAYTAlRXMQ8wDQYDVQQIEwZU&lt;br /&gt;YWl3YW4xDzANBgNVBAcTBlRhaXdhbjEcMBoGA1UEChMTTkNIVSBNSVMgRGVwYXJ0&lt;br /&gt;bWVudDESMBAGA1UEAxMJc291bHRha2VyMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB&lt;br /&gt;AOWeK9TSYVnPEkmK45TeI7NrC8MzvwabSVg1aEuTmcNkLRg/QibvB6ST5F056HCk&lt;br /&gt;0xvzm5rfO5A+q+4ncBMGMhkCAwEAATANBgkqhkiG9w0BAQUFAANBAGQhB8VKtY2N&lt;br /&gt;hecmukSUmJkTzFWwT15fPmTGzf0KdrccNCSK2bE/u6bTW9dkUF12MkTaHNVytmKd&lt;br /&gt;u7MoPuNvCnA=&lt;br /&gt;-----END CERTIFICATE-----&lt;/blockquote&gt;&lt;br /&gt;crt 已簽署憑證內容。這張憑證是自我簽署的，沒什麼效用。&lt;br /&gt;&lt;br /&gt;openssl x509 -in 1.crt -noout -modulus&lt;br /&gt;輸出公鑰係數。&lt;hr /&gt;&lt;br /&gt;OpenSSL 參考資料：&lt;br /&gt;http://www.ascc.sinica.edu.tw/nl/91/1819/02.txt&lt;br /&gt;http://setnet.com.tw/ftp/%BA%FB%AD%D7%A7%DE%B3N%BB%A1%A9%FA/Linux/%C3%B1%B5o%BE%CC%B5%FD.txt&lt;br /&gt;http://csc.ocean-pioneer.com/docum/ssl_basic.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-1842567310269621821?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/1842567310269621821/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/pki_31.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1842567310269621821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1842567310269621821'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/pki_31.html' title='PKI  Research #2 - 憑證製作'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-2048886046565294405</id><published>2009-07-30T13:52:00.006+08:00</published><updated>2009-07-30T14:01:21.473+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>C# 編譯產生 Unable to find manifest signing certificate in the certificate store 錯誤</title><content type='html'>當專案搬到另一台機器進行編譯後，可能會發生「Unable to find manifest signing certificate in the certificate store」，百思不得其解。查閱 Google 大神發現錯誤原因，由於 ClickOnce 的佈署需要經金鑰認證，換一台機器後編譯的金鑰就不同而會發生錯誤。可以手動開啟 *.csproj 檔案，搜尋：&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;lt;manifestcertificatethumbprint&gt;XXX&amp;lt;/manifestcertificatethumbprint&gt;&lt;br /&gt;&amp;lt;manifestkeyfile&gt;XXX&amp;lt;/manifestkeyfile&gt;&lt;br /&gt;&amp;lt;generatemanifests&gt;true&amp;lt;/generatemanifests&gt;&lt;br /&gt;&amp;lt;signmanifests&gt;true&amp;lt;/signmanifests&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;將這幾行刪除後重新存檔，應該就能正常編譯。&lt;br /&gt;--&lt;br /&gt;參考資料：&lt;a href="http://www.cnblogs.com/abeen/archive/2009/05/18/1459283.html"&gt;Unable to find manifest signing certificate in the certificate store&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-2048886046565294405?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/2048886046565294405/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-unable-to-find-manifest-signing.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2048886046565294405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2048886046565294405'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-unable-to-find-manifest-signing.html' title='C# 編譯產生 Unable to find manifest signing certificate in the certificate store 錯誤'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-8048903860460744109</id><published>2009-07-30T12:01:00.002+08:00</published><updated>2009-07-30T12:06:15.590+08:00</updated><title type='text'></title><content type='html'>話說, 有鑑於 icLin 的標準&lt;br /&gt;&lt;br /&gt;大家就一起來想想看這系統中有啥功能 &amp;amp; PO 一下唄&lt;br /&gt;&lt;br /&gt;現在既定的有...&lt;br /&gt;&lt;br /&gt;A) 看公文&lt;br /&gt;&lt;br /&gt;B) 上傳 [netDrive]&lt;br /&gt;&lt;br /&gt;C) 圖示隨意拖拉放&lt;br /&gt;&lt;br /&gt;想到啥就 有閒沒閒 回個應好過年 唄.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-8048903860460744109?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/8048903860460744109/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/iclin-po.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/8048903860460744109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/8048903860460744109'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/iclin-po.html' title=''/><author><name>馬各</name><uri>http://www.blogger.com/profile/05112202218372116737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-5952556777864652253</id><published>2009-07-27T11:47:00.001+08:00</published><updated>2009-07-27T11:49:11.092+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發週報'/><title type='text'>開發週報7/27</title><content type='html'>進度: iclin快把電腦給我生出來呀!!!!!&lt;br /&gt;&lt;br /&gt;OpenCA 試架&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;預想認證方式&lt;br /&gt;&lt;br /&gt;遺失補發&lt;br /&gt;所有者持身份證件or 護照 至管理部門進行與DB內的資料核對&lt;br /&gt;若成功就予以補發 錯誤就代表此人為不合法想要申請TAG補發的使用者&lt;br /&gt;&lt;br /&gt;根據認證方法與補發辦法上&lt;br /&gt;TAG與DB的儲存內容調整為以下&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;TAG 內存&lt;br /&gt;&lt;br /&gt;使用者名稱  個人介面選項 公鑰 私鑰&lt;br /&gt;&lt;br /&gt;          &lt;br /&gt;DB內存&lt;br /&gt;&lt;br /&gt;使用者名稱 職位等級(讀公文等級,思考中?) 身份證字號(或護照號碼)先做hash再存入 公鑰&lt;br /&gt;&lt;br /&gt;試問:&lt;br /&gt;伺服器問題是否以解決&lt;br /&gt;&lt;br /&gt;--------------------&lt;br /&gt;PPT進度在回覆回報一下&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-5952556777864652253?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/5952556777864652253/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/727.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5952556777864652253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5952556777864652253'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/727.html' title='開發週報7/27'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-2148221243570992287</id><published>2009-07-22T15:00:00.006+08:00</published><updated>2009-07-23T14:10:46.894+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發週報'/><title type='text'>下一步?</title><content type='html'>RFID:&lt;br /&gt;因為若真的要用SK &amp;amp; PK 來認證的話&lt;br /&gt;那麼原本要存進TAG&amp;amp;DB的　我們所給的ID(自動編號的0001,0002)之類的　這項可以去掉&lt;br /&gt;再來留　SK PK各8　blocks來存&lt;br /&gt;改存&lt;br /&gt;&lt;br /&gt;1.USER NAME&lt;br /&gt;2.LEVEL&lt;br /&gt;3.UserMod&lt;br /&gt;5.SK&lt;br /&gt;6.PK(從資料庫存取資料的index)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;其中5,6為後來再來執行 &lt;/span&gt;&lt;br /&gt;------------------------------------------------&lt;br /&gt;DB的話&lt;br /&gt;驗證方面的似乎要分開？&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;現在要先做的應該是做主程式從SERVER端讀取公文檔案&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;傳到本地端電腦這一塊&lt;/span&gt;&lt;br /&gt;我們要就是讓他傳檔案到本地端電腦還是？&lt;br /&gt;基本上我們一開始的想法是公文&lt;br /&gt;公文並不能修改&lt;br /&gt;所以並不需要做修改後回存這一部份的動作跟程式&lt;br /&gt;但聽IC說法好像想要讓我們做可以修改回存...(?)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;麻煩大家說一下意見吧？&lt;br /&gt;&lt;br /&gt;----------------------------------&lt;br /&gt;7/23更新&lt;br /&gt;&lt;br /&gt;DB增加身份證字號 or 護照 號碼   HASH後的值&lt;br /&gt;(Varchar32) 存入&lt;br /&gt;拿來當萬一TAG 被使用者弄丟的話&lt;br /&gt;使用者可憑證件向公司申請補發一張新的TAG&lt;br /&gt;同時重新讓認證中心重新發佈SK &amp;amp; PK&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-2148221243570992287?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/2148221243570992287/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post_22.html#comment-form' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2148221243570992287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2148221243570992287'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post_22.html' title='下一步?'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-2319458327519920731</id><published>2009-07-21T18:24:00.005+08:00</published><updated>2009-07-21T18:39:44.464+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>OpenCA</title><content type='html'>好，既然無論如何都要加 PKI，那就硬幹看看。&lt;a href="http://www.openca.org/"&gt;OpenCA&lt;/a&gt; 我們已經知道可以用來建立 CA 了，至於要怎麼用還不清楚。這裡有份 &lt;a href="http://crypto.nknu.edu.tw/download/main.html"&gt;Live CD 的說明文件&lt;/a&gt;，可以下載 Live CD 直接以光碟開機啟動。&lt;br /&gt;&lt;br /&gt;我不知道 &lt;a href="http://www.imacat.idv.tw/tech/sslcerts.html.zh-tw"&gt;X.509&lt;/a&gt; 憑證裡面寫了啥，不過如果真的只需要公鑰跟私鑰，他創一個這麼大的檔案要幹嘛？如果真的有辦法只取出公私鑰塞入 Tag，這樣不就變成單純的 RSA 機制？那 CA 的驗證等等還有用嗎？但這個機制避掉了 Tag 空間不夠，只存必要資訊的方法。(話說也沒人這樣做過？我們算先驅？)&lt;br /&gt;&lt;br /&gt;另一種方法則是將憑證檔案也存放到 Server，統一保管 (注意這有被駭的安全性問題)，Tag內只存放索引，必要時調出憑證來確認。這個方法似乎避免掉了憑證檔不能存在 Tag 的問題，卻又引發了另一個問題。&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;伺服器機架問題，還未能正式上線。我希望下週就能搞定，就可以架設 OpenCA (+ OpenSSL, Apache HTTP Server 等)，現在只能找 Live CD 套著玩。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-2319458327519920731?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/2319458327519920731/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/openca.html#comment-form' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2319458327519920731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2319458327519920731'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/openca.html' title='OpenCA'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-8860776416209089051</id><published>2009-07-15T11:09:00.007+08:00</published><updated>2009-07-20T00:07:23.995+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><title type='text'>PKI目前結論</title><content type='html'>該比賽有教學&lt;br /&gt;跟套件可索取&lt;br /&gt;這玩意兒是給&lt;br /&gt;"智慧卡"用的&lt;br /&gt;並不是用RFID&lt;br /&gt;&lt;br /&gt;結論:...擱置&lt;br /&gt;---------------------------------&lt;br /&gt;7/16更新&lt;br /&gt;RFID與PKI結合應用研究 &lt; CYY的技術報告 準備要去神出來(大家上)&lt;br /&gt;&lt;br /&gt;PKI直接架構無法使用在RFID TAG(太耗空間)&lt;br /&gt;PKI要參加比賽要用已知的PKI技術(不知CYY他們的技術報告可不可行)&lt;br /&gt;&lt;br /&gt;資通 PKI 競賽第一屆&lt;a href="http://edm.ares.com.tw/dm/newsletter-2009-03/focus.htm"&gt;電子報&lt;/a&gt;&lt;br /&gt;亞軍：朝陽科大資工-「應用PKI為安全基礎的共享汽車系統」&lt;br /&gt;RFID 搭配自然人憑證 (先以自然人憑證認證，再將憑證卡號綁定 Tag 的方式)，並非 Tag 內儲存 PKI 資訊，自己建立憑證中心。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cs.nctu.edu.tw/~wmwang/RFID_PKI/"&gt;交大資工&lt;/a&gt;&lt;br /&gt;一系列工研院的 RFID 安全研究，提到 OpenCA 架設憑證中心自行發行憑證的可能性。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cqvip.com/qk/95033x/2007021/25843209.html"&gt;PKI技术在RFID标签数据安全中的应用&lt;/a&gt; / 杨金国 - 计算机工程与设计, 2007&lt;br /&gt;一篇大陸論文，因為無法存取所以無法知道更詳細的資料，只知道至少有人在研究這個領域。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://articles.e-works.net.cn/Autoid/Article54124_1.htm"&gt;RFID在产品防伪应用中的关键技术研究&lt;/a&gt;&lt;br /&gt;有圖有真相&lt;br /&gt;&lt;br /&gt;&lt;a href="http://edm.ares.com.tw/dm/20081202-pki/Non-Distribution%20Agreement.doc"&gt;保密承諾書&lt;/a&gt;&lt;br /&gt;參加ARES uPKI比賽要簽的賣身契，基本上就是uPKI是他們的機密，比賽完後就不可使用及流出。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-8860776416209089051?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/8860776416209089051/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/pki_15.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/8860776416209089051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/8860776416209089051'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/pki_15.html' title='PKI目前結論'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-690770908908943344</id><published>2009-07-13T21:04:00.008+08:00</published><updated>2010-05-03T22:28:50.421+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ESXi'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>部署 VMware ESXi Server 4 on IBM System x3550</title><content type='html'>最後我選了 ESXi 作為虛擬化的方案。&lt;br /&gt;&lt;br /&gt;第一：OpenVZ 基於一個 Linux，這個 OS 必須去維護它，我維護其他 OS 都嫌麻煩了；ESXi 是特化的 Linux 核心，幾乎不需維護 (定期注意系統更新即可)。&lt;br /&gt;&lt;br /&gt;第二：OpenVZ 只能支援 Linux OS，因為它是 OS-Based 虛擬化的緣故；ESXi 使用 VMware 長久以來全虛擬化的結晶實作了一個半虛擬化的 Hypervisor 平台，可以運作多樣的 OS，當然也包含 Windows。&lt;br /&gt;&lt;br /&gt;第三：這有點偏見，ESXi 安裝很簡單，OpenVZ 卻還要慢慢設定。&lt;hr /&gt;&lt;br /&gt;說了這麼多，最後我終於啟動了 System x3550，有如渦輪引擎的六具 6000 轉抽風扇瞬間轉起，那吵度真不是蓋的。卻發現它沒有 PS/2 插孔而只有 USB，因為手中沒有 USB 鍵盤所以只好又跑一趟電子街買一個 KIMYO NT$195 的 USB 陽春鍵盤。插上去後仔細看螢幕說明，按下 F1 按鍵進入 BIOS 設定，可以看到裝著兩顆 Intel Xeon E5405 2.0GHz、2GB 的記憶體及兩顆 SAS 167GB 硬碟。接著依指示按下 Ctrl + A 進入 RAID 管理。&lt;br /&gt;&lt;br /&gt;我想 RAID 0 應該沒有勇者要試吧，這是伺服器耶。於是就選了 RAID 1 鏡像備份模式。建立完之後跳出設定，放入預先燒好的 ESXi 安裝光碟，開始安裝。&lt;br /&gt;&lt;br /&gt;安裝過程沒什麼好說的，就是看指示按下對應按鈕，可能是 F8、F11 或 Enter 一直變換，大概是不想讓你一路跳過去吧。安裝過程根本沒難度，只是 ESXi 4 的安裝條件相當嚴苛，通常不能安裝都是卡在 RAID 卡或是網路卡不支援，這台 IBM System x3550 算是通過考驗了。安裝完成重開機，就進入 ESXi 介面。&lt;br /&gt;&lt;br /&gt;介面什麼都沒有。總之先按下 F2 設定 root 密碼跟伺服器 IP 吧，成功輸入 IP、Subnet mask、Gateway和 DNS 後，就完成了網路設定。最後打開被封印的 SSH 遠端管理功能，這是一定要的 (&lt;a href="http://blog.s5x.tw/log/2009/04/enable-ssh-on-esxi.html"&gt;參考文章&lt;/a&gt;)。過程中比較難的大概是 vi 指令，因為許久未碰都忘光了XD 按 a 進編輯模式，刪除註解的 # 字元，按下 Esc 跳出編輯模式，輸入 :wq (冒號: Shift + ;) 寫入並離開就大功告成，最後重開一下。&lt;br /&gt;&lt;br /&gt;要管理必須透過 vSphere Client 連線 (可以 HTTP 連到伺服器 IP 有下載連結)，而且只有 Windows 版，怪。安裝完成後發現 Windows 7 RC 版不能登入，顯示 clients.xml 錯誤啥的。官方也有&lt;a href="http://communities.vmware.com/thread/211440"&gt;網友回報&lt;/a&gt;討論串，官方解答竟然是叫你用 7 的 XP Mode 執行，這真是我聽過最棒的回答法了，去你的。還好下面有強者提出解套法：去其他安裝 .NET 3.5 SP 的電腦上找 System.dll 複製，修改 VpxClient.exe.config 文件，使用 BAT 下環境變數執行，真的成功，真是太棒了。&lt;br /&gt;&lt;br /&gt;最後就利用 GUI 登入，上傳作業系統 ISO 檔供虛擬系統安裝時使用，設定虛擬系統跟 VMware 其他產品非常像，這是最易上手的地方。最後啟動虛擬系統，按照安裝 OS 的步驟來安裝 (放入光碟、更改 BIOS 開機順序)，就大功告成。記得最後裝個 VMware Tools 來使系統更快更穩。&lt;br /&gt;&lt;br /&gt;灌了一個 CentOS 5.3 版，跑看看再說。在 CentOS 的 eth0 設定使用手動 IP 設定，也可以取得固定 IP，有如另一台伺服器在線運作一般，真好玩。也可以 SSH 連進去管理。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-690770908908943344?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/690770908908943344/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/vmware-esxi-server-4.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/690770908908943344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/690770908908943344'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/vmware-esxi-server-4.html' title='部署 VMware ESXi Server 4 on IBM System x3550'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-6722947698380220196</id><published>2009-07-10T19:49:00.017+08:00</published><updated>2009-07-13T21:46:40.231+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>架設機架式伺服器</title><content type='html'>目前位在我們研究室的那台伺服器，是IBM出品的 &lt;a href="http://www-07.ibm.com/systems/tw/x/hardware/rack/x3550/index.html"&gt;System x3550&lt;/a&gt;(&lt;a href="http://processorfinder.intel.com/details.aspx?sSpec=SLAP2"&gt;Intel Xeon E5405&lt;/a&gt; 2.0GHz x 2, 2GB DDR2 RAM)，這一台東西被擱置已經有半年以上了(NT$八萬多耶)，現在即將在一週內被安裝到機房內，並建構好作業環境。&lt;br /&gt;&lt;br /&gt;順利的話，這台機器可以放在新蓋的社管大樓5F機房，佔用1U機架的空間，有備援電源跟冷氣照顧，應該比放在研究室好上很多。這方面還要看到時候有沒有辦法，畢竟只是說說。然後這台新機器確定要由三組團隊共用，我不相信三組人馬能好好的共處在一個作業環境下，所以我想將這台機器建立在虛擬化的技術上，讓每一組自己搞自己的那一塊。&lt;br /&gt;&lt;br /&gt;例如有 &lt;a href="http://wiki.openvz.org/Main_Page"&gt;OpenVZ&lt;/a&gt; 這種 OS-Based 半虛擬化技術，它是直接在 Linux Kernel 上動手腳，讓其他環境直接在機器上同時運作，並幾乎以一般的速度運作，因此其他虛擬私人伺服器 (Virtual Private Server, VPS) 所運行的作業系統只能是 Linux 了。&lt;br /&gt;&lt;br /&gt;OpenVZ 必須先安裝 CentOS 4/5 或是 Fedora 系 Linux，才能在其上安裝 OpenVZ，目前 Wiki 有介紹如何下載 yum 套件安裝。另外架設完成後，Host OS必須使用 OpenVZ 預先準備好的包裝來建置，不過有&lt;a href="http://download.openvz.org/template/precreated/"&gt;非常多的Distributuion 可選擇&lt;/a&gt;，Ubuntu 什麼的都可以用，放到/vz/template/cache即可。&lt;br /&gt;&lt;br /&gt;OpenVZ 搭配 HyperVM 的網頁式管理介面應該是最好的了，安裝也很容易。&lt;br /&gt;&lt;br /&gt;發現有包裝好的 OS + OpenVZ + Web管理包：&lt;a href="http://pve.proxmox.com/wiki/Main_Page"&gt;Proxmox VE&lt;/a&gt;，它同時也包進了QEMU全虛擬化環境，可以運作 Windows (慢)，如果要選 OpenVZ 方案我會用這個整合包來安裝。&lt;br /&gt;&lt;br /&gt;另一個方案是 &lt;a href="http://www.vmware.com/tw/products/vi/esx/esx3i.html"&gt;VMware ESXi Server&lt;/a&gt; 半虛擬化技術，這套軟體是商業軟體免費化。&lt;a href="http://www.ithome.com.tw/itadm/article.php?c=55553"&gt;相關文章&lt;/a&gt;。唯一的不同是這套可以支援許多 OS，連 Windows 都有，但整體效率應該比 OpenVZ 來的差一點吧。優點是他跟我們平常接觸的全虛擬化環境 (例如 Virtual PC, VMware, VirtualBox) 非常接近，但由於是建購在半虛擬化技術上，速度比較快。&lt;br /&gt;&lt;br /&gt;VMware ESXi 需要搭配專用的連線程式連到主機去佈置 Host OS，不知道有沒有多帳號可以分開管理就是了。&lt;br /&gt;&lt;br /&gt;07/13 編輯：有多帳號，但是似乎沒有辦法讓每個人自己只管自己的 VM，而是一次給予所有 VM 的修改權限？也就是我可以改你的，這太不好了，我再研究看看。&lt;br /&gt;---&lt;br /&gt;相關文獻&lt;br /&gt;&lt;br /&gt;http://wiki.centos.org/HowTos/Virtualization/OpenVZ&lt;br /&gt;http://www.linuxfly.org/post/307/&lt;br /&gt;http://phorum.study-area.org/index.php/board,39.0.html&lt;br /&gt;http://blog.s5x.tw/log/2009/04/enable-ssh-on-esxi.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-6722947698380220196?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/6722947698380220196/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post_10.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6722947698380220196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6722947698380220196'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post_10.html' title='架設機架式伺服器'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-5187316394279690667</id><published>2009-07-10T14:34:00.005+08:00</published><updated>2009-07-16T14:51:51.209+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKI'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>PKI</title><content type='html'>PKI(Public Key Infrastructure;&lt;b&gt;公開金鑰基礎建設&lt;/b&gt;)&lt;br /&gt;&lt;br /&gt;何謂PKI?&lt;br /&gt;提供在電腦網路運作的個人資料、商務與商業能夠如同信封簽章與封印般的技術。&lt;br /&gt;密碼學上，藉著&lt;a href="http://zh.wikipedia.org/w/index.php?title=CA&amp;amp;variant=zh-tw" title="CA"&gt;憑證管理中心&lt;/a&gt;（CA）將使用者的個人身分跟公開金鑰鏈結在一起。&lt;br /&gt;&lt;br /&gt;PKI所能達到的目標?&lt;br /&gt;機密性、真確性、驗證性、不可否認性&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dlm.ntu.edu.tw/upload/%7B979DBC8E-6958-479A-9BE4-F0465DA8EC63%7D/PKI.pdf"&gt;PKI概念介紹&lt;/a&gt;(PDF)&lt;hr /&gt;&lt;br /&gt;&lt;a href="http://www.ares.com.tw/pki_pk2009/a.php"&gt;資通PKI應用競賽 歡迎來PK!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ARES uPKI套件是免費提供的 (在這個比賽)，但是它好像是用在 SmartCard 上，RFID上不知可不可行。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-5187316394279690667?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/5187316394279690667/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/pki.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5187316394279690667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/5187316394279690667'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/pki.html' title='PKI'/><author><name>Jimmy</name><uri>http://www.blogger.com/profile/14068193898204652397</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-696782633083302397</id><published>2009-07-09T11:21:00.004+08:00</published><updated>2009-07-09T14:13:53.798+08:00</updated><title type='text'>職位等級該取得之資料分級方法</title><content type='html'>今天討論後&lt;br /&gt;由依等級不同分存在不同等級的資料夾&lt;br /&gt;所以依不同等級建立不同資料夾來存&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ex:&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="cursor: pointer; width: 128px; height: 128px;" src="http://1.bp.blogspot.com/_gVD4GG_1J10/SlWJUYuAyLI/AAAAAAAAAAk/wr1VJX4PQ5Y/s320/folder.png" alt="" id="BLOGGER_PHOTO_ID_5356338315152902322" border="0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img style="cursor: pointer; width: 128px; height: 128px;" src="http://1.bp.blogspot.com/_gVD4GG_1J10/SlWJUYuAyLI/AAAAAAAAAAk/wr1VJX4PQ5Y/s320/folder.png" alt="" id="BLOGGER_PHOTO_ID_5356338315152902322" border="0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img style="cursor: pointer; width: 128px; height: 128px;" src="http://1.bp.blogspot.com/_gVD4GG_1J10/SlWJUYuAyLI/AAAAAAAAAAk/wr1VJX4PQ5Y/s320/folder.png" alt="" id="BLOGGER_PHOTO_ID_5356338315152902322" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Level 1&lt;/td&gt;&lt;td&gt;Level 2&lt;/td&gt;&lt;td&gt;Level 3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;如圖&lt;br /&gt;各level資料夾更放著不等level的該取得的訊息等&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-696782633083302397?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/696782633083302397/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post_09.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/696782633083302397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/696782633083302397'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post_09.html' title='職位等級該取得之資料分級方法'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_gVD4GG_1J10/SlWJUYuAyLI/AAAAAAAAAAk/wr1VJX4PQ5Y/s72-c/folder.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-7274182471643312608</id><published>2009-07-08T14:53:00.002+08:00</published><updated>2009-07-08T14:58:05.476+08:00</updated><title type='text'>C# 迴圈 vs 遞迴</title><content type='html'>剛剛想要驗證書上說&lt;br /&gt;遞迴比迴圈有效率(我覺得他在唬爛...)&lt;br /&gt;於是用程式run看看&lt;br /&gt;有鑑於電腦跑起來速度我感覺不出來...&lt;br /&gt;依java經驗(?)來講&lt;br /&gt;當然是迴圈快&lt;br /&gt;只好拜咕大神&lt;br /&gt;沒有看見遞迴比迴圈有效率的說法(除了特殊情況下)&lt;br /&gt;&lt;br /&gt;雖然遞迴就結構上比較直覺&lt;br /&gt;&lt;br /&gt;但對我來說就程式邏輯而言還是迴圈比較好想&lt;br /&gt;而在效率上也是迴圈比較好&lt;br /&gt;Visual C# 2005 精要剖析書上是錯的&lt;br /&gt;不要相信它= =a&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-7274182471643312608?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/7274182471643312608/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-vs.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7274182471643312608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7274182471643312608'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-vs.html' title='C# 迴圈 vs 遞迴'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-6106785627287979693</id><published>2009-07-08T11:37:00.009+08:00</published><updated>2009-07-08T15:15:20.734+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>C# Delegate 委派 使用方法</title><content type='html'>之前講到委派 (Delegate)，當時不清楚做法。查了一些資料後，大概了解它是一個代理者的角色，代替你執行你要執行的方法。例如說你可以手動打開電視開關來收看電視，也可以利用電視遙控器 (代理者) 來幫你執行打開電視的工作。&lt;br /&gt;&lt;br /&gt;C# 提供 delegate 修飾子來宣告一個委派方法：&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;delegate&lt;/span&gt; String getNameDelegate&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String n&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;委派方法的參數個數、順序、型態乃至於回傳型態都必須跟要被委派的方法一樣 (但變數名稱可以不相同)。下面是我們要委派這個 getNameDelegate 方法呼叫的一個方法：&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; String getName&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String name&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;g1: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; name&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;所以我們把 getName 想成打開電視機，getNameDelegate 當作遙控器，這樣可以多少理解吧？&lt;br /&gt;&lt;br /&gt;要呼叫委派方法，有許多方法，隨著 &lt;a href="http://msdn.microsoft.com/zh-tw/library/bb882516.aspx"&gt;C# 版本的演進&lt;/a&gt;已經越來越方便，就從最複雜的開始說起吧。&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Collections&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Generic&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Linq&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Text&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;namespace&lt;/span&gt; ConsoleApplication1 &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;class&lt;/span&gt; Program &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;delegate&lt;/span&gt; String getNameDelegate&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String n&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; Main&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;string&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; args&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            getNameDelegate g0 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; getNameDelegate&lt;span style='color:#808030; '&gt;(&lt;/span&gt;getName&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            getNameDelegate g1 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; getName&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            getNameDelegate g2 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;delegate&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String n&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;g2: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; n&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            getNameDelegate g3 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; n &lt;span style='color:#808030; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; '&gt;&gt;&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;g3: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; n&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;g0&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;0&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;g1&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;1&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;g2&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;2&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;g3&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;3&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadKey&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; String getName&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String name&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;g1: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; name&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;首先是 getNameDelegate g0 = new getNameDelegate(getName); 這段，這是最早的方法。你就將 getNameDelegate 給實體化，並在其建構元上指定要代為執行的方法 (如 getName) 就可以了。&lt;br /&gt;&lt;br /&gt;因為這樣太麻煩，所以後來的 C# 支援這種寫法：getNameDelegate g1 = getName; 是不是更直覺呢？&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/zh-tw/library/0yw3tz5k.aspx"&gt;C# 2.0 中，增加了匿名方法的建立&lt;/a&gt;，像我們的 getName 這麼簡單的一行，可以簡化為&lt;br /&gt;getNameDelegate g2 = delegate(String n) { return "g2: " + n; };&lt;br /&gt;這樣，利用 delegate(){ } 來定義匿名方法。&lt;br /&gt;&lt;br /&gt;C# 3.0 中，更以 &lt;a href="http://msdn.microsoft.com/zh-tw/library/bb397687.aspx"&gt;Lambda 運算式&lt;/a&gt;取代匿名方法，一行 getNameDelegate g3 = n =&gt; "g3: " + n; 輕鬆打發。 n =&gt; "g3: " + n; 就是所謂的 Lambda 運算式。例如 x =&gt; x * x 就是「傳入 x，執行 x * x 並回傳」。&lt;br /&gt;&lt;br /&gt;最後準備好 g1 等委派物件後，就可以開始執行了。執行的方式有兩種，一種是 g1.Invoke(); 來引發，另一種是更為直覺的 g1(); 直接執行。&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;這麼看起來委派只是代為執行，並沒有什麼好用的感覺啊。像上面的例子，我大可直接呼叫 getName() 就好，為什麼還要繞一圈以 getNameDelegate 包裝起來再呼叫呢？脫褲子放屁嗎？&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;getNameDelegate g1 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; getName&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;g1&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Scribe&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;getName&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Scribe&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;They're the same!&lt;br /&gt;&lt;br /&gt;雖然我現在還搞不懂委派有什麼好的，不過我發現委派他可以一次呼叫代為多個方法，這樣就比較有用多了。例如我按下遙控器的開關，就可以幫我把電視、冷氣、電燈等開關一次打開，不是很方便嗎？所以下面要教你怎麼一次委派多個方法。&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;namespace&lt;/span&gt; ConsoleApplication1 &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;class&lt;/span&gt; Program &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;delegate&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; consoleDelegate&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String txt&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;delegate&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; printNameDelegate&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String n&lt;span style='color:#808030; '&gt;,&lt;/span&gt; consoleDelegate p&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; Main&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;string&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; args&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            var g0 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; printNameDelegate&lt;span style='color:#808030; '&gt;(&lt;/span&gt;printName&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            g0 &lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;delegate&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String n&lt;span style='color:#808030; '&gt;,&lt;/span&gt; consoleDelegate p&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt; p&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Call from anonymous func: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; n&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            g0 &lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;n&lt;span style='color:#808030; '&gt;,&lt;/span&gt; p&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; '&gt;&gt;&lt;/span&gt; p&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Call from Lambda: &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; n&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            g0&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;scribe&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; print2Console&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadKey&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; printName&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String name&lt;span style='color:#808030; '&gt;,&lt;/span&gt; consoleDelegate p&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            p&lt;span style='color:#808030; '&gt;(&lt;/span&gt;name&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; print2Console&lt;span style='color:#808030; '&gt;(&lt;/span&gt;String txt&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;txt&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Result:&lt;br /&gt;&lt;blockquote&gt;scribe&lt;br /&gt;Call from anonymous func: scribe&lt;br /&gt;Call from Lambda: scribe&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;var g0 = new printNameDelegate(printName);&lt;br /&gt;g0 += delegate(String n, consoleDelegate p) { p("Call from anonymous func: " + n); };&lt;br /&gt;g0 += (n, p) =&gt; p("Call from Lambda: " + n);&lt;/blockquote&gt;&lt;br /&gt;上面三行分別以不同的方式創造出委派物件，跟上面範例的不同點是以 += 串接，讓 g0 一次代理多個方法，最後再一次執行。所以 g0() 的結果有三行。這樣就可以呼叫一個委派物件，同時作數件事情了。&lt;br /&gt;&lt;br /&gt;值得一提的是本範例用了兩個 delegate，其中一個用在 print2Console 上，讓其他方法能夠叫用。printName 第二個參數就是 delegate，其實很像是方法的指標之類的。(因為不可以直接指定第二個變數型別為 print2Console，所以使用委派方式)&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;我比較喜歡 delegate{} 建立匿名方法跟直接使用 () 來呼叫委派物件，你呢？&lt;br /&gt;&lt;br /&gt;參考資料：&lt;a href="http://huan-lin.blogspot.com/2009/01/delegate-revisited-csharp-1-to-2-to-3.html"&gt;C# 筆記：重訪委派－從 C# 1.0 到 2.0 到 3.0&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-6106785627287979693?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/6106785627287979693/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-delegate.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6106785627287979693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/6106785627287979693'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-delegate.html' title='C# Delegate 委派 使用方法'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-789143040600338429</id><published>2009-07-07T15:47:00.004+08:00</published><updated>2009-07-07T16:42:58.694+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>在 WPF Application 中使用 Timer</title><content type='html'>一般來說在 Windows Forms 程式可以使用工具箱的 &lt;a href="http://msdn.microsoft.com/zh-tw/library/system.windows.forms.timer.aspx"&gt;Timer (System.Windows.Forms)&lt;/a&gt; 來進行，另外也有更為精確的 &lt;a href="http://msdn.microsoft.com/zh-tw/library/system.timers.timer.aspx"&gt;System.Timers.Timer&lt;/a&gt; 可以用。但是在 Windows Presentation Foundation 應用程式中，沒有辦法使用 System.Windows.Forms.Timer，而 System.Timers.Timer 雖然仍可以使用，但是在時間觸發的事件中如果你去修改 UI 控制項的文字等等，會警告你只有擁有 UI 控制項的執行緒可以修改屬性。要解決這個方法可以用 Delegate 委派方法，但是這是 C# 的新玩意，Java沒有這種東西，所以不太懂。另一個方法是設定 Timer 的 SynchronizingObject 屬性，讓這個獨立的執行緒跟 UI 執行緒屬於同一個，但是 WPF 程式的頂層 Window 沒有實作 ISynchronizeInvoke 介面的樣子，所以無法使用。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;System.Windows.Forms.Timer:&lt;br /&gt;Windows Forms 程式用&lt;br /&gt;計時執行緒跟 UI 執行緒是同一個 (或者說根本只有一個執行緒)&lt;br /&gt;可能造成主畫面沒有反應的狀況 (因為相同執行緒的關係)&lt;br /&gt;&lt;br /&gt;System.Timers.Timer:&lt;br /&gt;所有 .NET 程式皆可使用&lt;br /&gt;計時執行緒跟 UI 執行緒是不同個 (因此有執行緒同步問題)&lt;br /&gt;不會造成主畫面沒有反應的情況&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;於是拜 Google 大神，得到了 &lt;a href="http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatchertimer.aspx"&gt;System.Windows.Threading.DispatcherTimer&lt;/a&gt; 這個物件，可以用在 WPF 程式上，而且它所產生的執行緒跟擁有 UI 的執行緒是同一個，就不必擔心無法修改的問題。&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;private&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; btnTimer_Click&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;object&lt;/span&gt; sender&lt;span style='color:#808030; '&gt;,&lt;/span&gt; RoutedEventArgs e&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#696969; '&gt;// 設定 Timer 以自動讀取&lt;/span&gt;&lt;br /&gt;    DispatcherTimer t &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; DispatcherTimer&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    t&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Tick &lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; EventHandler&lt;span style='color:#808030; '&gt;(&lt;/span&gt;t_Elapsed&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    t&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Interval &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; TimeSpan&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;1000000&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    t&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Start&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;private&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; t_Elapsed&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;object&lt;/span&gt; sender&lt;span style='color:#808030; '&gt;,&lt;/span&gt; EventArgs e&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#696969; '&gt;// ... do something...&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;值得注意的是 TimeSpan 建構元接受的數字是 100 奈秒單位，上面的 1000000 為 100 毫秒的意思。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;System.Windows.Threading.DispatcherTimer:&lt;br /&gt;所有 .NET 程式皆可使用&lt;br /&gt;計時執行緒位於 Dispatcher 佇列之中，可以存取 UI 控制項&lt;br /&gt;不會造成主畫面沒有反應的情況 (未測試，可能是因為統一由 Dispatcher 管理)&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-789143040600338429?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/789143040600338429/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/wpf-application-timer.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/789143040600338429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/789143040600338429'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/wpf-application-timer.html' title='在 WPF Application 中使用 Timer'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-4290343802230720058</id><published>2009-07-07T11:03:00.003+08:00</published><updated>2009-07-07T11:04:19.954+08:00</updated><title type='text'>DB&amp;RFID所存資料</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_gVD4GG_1J10/SlK7EIIeJqI/AAAAAAAAAAU/C_gZDoxv7ck/s1600-h/Table+List.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5355548586473825954" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 240px; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_gVD4GG_1J10/SlK7EIIeJqI/AAAAAAAAAAU/C_gZDoxv7ck/s320/Table+List.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;目前想到的暫定版應該是這樣&lt;/div&gt;&lt;div&gt;大家有意見或有問題請講~~~~&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-4290343802230720058?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/4290343802230720058/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/db.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/4290343802230720058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/4290343802230720058'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/db.html' title='DB&amp;RFID所存資料'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_gVD4GG_1J10/SlK7EIIeJqI/AAAAAAAAAAU/C_gZDoxv7ck/s72-c/Table+List.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-4160403184673229213</id><published>2009-07-06T14:20:00.004+08:00</published><updated>2009-07-06T14:45:01.292+08:00</updated><title type='text'>關於在 VS 中為網頁嵌入式件處理程序的方~法</title><content type='html'>在 VS 當中, 對於在專案理加入事件處理程序.&lt;br /&gt;&lt;br /&gt;有幾種方式.&lt;br /&gt;&lt;br /&gt;首先 A) 就是直接寫在 其附屬的 C# 檔中;&lt;br /&gt;&lt;br /&gt;如下例:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_bxfSWigfwpk/SlGcHkVzm-I/AAAAAAAAAAU/Nfst13oMulo/s1600-h/page01.bmp"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 190px;" src="http://1.bp.blogspot.com/_bxfSWigfwpk/SlGcHkVzm-I/AAAAAAAAAAU/Nfst13oMulo/s320/page01.bmp" alt="" id="BLOGGER_PHOTO_ID_5355233085748386786" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;在右邊的這個欄位中選擇 *.cs 檔,&lt;br /&gt;&lt;br /&gt;直接在其中加入 function.&lt;br /&gt;&lt;br /&gt;整體跟 java 有一定程度的相似度.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;不然的話,&lt;br /&gt;&lt;br /&gt;可以用方法 B) , 另外新增一個 *.js 檔.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_bxfSWigfwpk/SlGckv44TfI/AAAAAAAAAAc/SMHBIpWRfNk/s1600-h/page02.bmp"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 190px;" src="http://2.bp.blogspot.com/_bxfSWigfwpk/SlGckv44TfI/AAAAAAAAAAc/SMHBIpWRfNk/s320/page02.bmp" alt="" id="BLOGGER_PHOTO_ID_5355233587064491506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;這樣的話就跟撰寫一般 javascript 檔的寫法就一模一樣了. 嘿嘿.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;以上這兩個方法都可以使用.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-4160403184673229213?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/4160403184673229213/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/vs.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/4160403184673229213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/4160403184673229213'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/vs.html' title='關於在 VS 中為網頁嵌入式件處理程序的方~法'/><author><name>馬各</name><uri>http://www.blogger.com/profile/05112202218372116737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_bxfSWigfwpk/SlGcHkVzm-I/AAAAAAAAAAU/Nfst13oMulo/s72-c/page01.bmp' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-665108089979013193</id><published>2009-07-06T14:12:00.002+08:00</published><updated>2009-07-06T14:15:08.436+08:00</updated><title type='text'>程式存取部分簡圖</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_gVD4GG_1J10/SlGWH4BqL3I/AAAAAAAAAAM/fLuYiT7YCR0/s1600-h/diagram.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5355226493962825586" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 226px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_gVD4GG_1J10/SlGWH4BqL3I/AAAAAAAAAAM/fLuYiT7YCR0/s320/diagram.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;嗯...如果沒理解錯誤的話&lt;/p&gt;&lt;p&gt;我們的基本運作方式(終端電腦省略掉了 還是也要畫上去呢~?)&lt;/p&gt;&lt;p&gt;算第一張簡圖吧~比之前我們討論時的還簡略了不少&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-665108089979013193?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/665108089979013193/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/665108089979013193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/665108089979013193'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/blog-post.html' title='程式存取部分簡圖'/><author><name>伊達京介</name><uri>http://www.blogger.com/profile/16311622001458886707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_gVD4GG_1J10/SlGWH4BqL3I/AAAAAAAAAAM/fLuYiT7YCR0/s72-c/diagram.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-3504126009810327803</id><published>2009-07-03T15:46:00.005+08:00</published><updated>2009-07-03T18:28:06.025+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>.NET 字串轉 Byte 、Byte 轉字串解法</title><content type='html'>因為 RFID 的 Block 讀寫是採用低階的 byte，一般使用不太可能直接使用 byte 而會是 String 一類的東西，是故我們必須學會如何把字串轉成 byte，反過來 byte 轉成 String 的方法。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"張京介" → Write to Block Ｘ&lt;br /&gt;"張京介" → Convert to byte[] → {177, 105, 168, 202, 164, 182} → Write to Block Ｏ&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;.NET Framework 的 &lt;a href="http://msdn.microsoft.com/zh-tw/library/system.text.encoding.aspx"&gt;System.Text.Encoding&lt;/a&gt; 類別庫提供一系列的字碼頁轉換方式，其中有 Default (環境預設編碼，例如正體中文便是 Big5)、UTF7、UTF8、Unicode (UTF-16)、UTF32、ASCII 等編碼。要把字串變成 byte，則可以使用 GetBytes() 方法，以下是例子：&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Text&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;String name &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;張京介&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;Encoding&lt;span style='color:#808030; '&gt;.&lt;/span&gt;UTF8&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetBytes&lt;span style='color:#808030; '&gt;(&lt;/span&gt;name&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// {229, 188, 181, 228, 186, 172, 228, 187, 139}&lt;/span&gt;&lt;br /&gt;Encoding&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Default&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetBytes&lt;span style='color:#808030; '&gt;(&lt;/span&gt;name&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// {177, 105, 168, 202, 164, 182}&lt;/span&gt;&lt;br /&gt;Encoding&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Unicode&lt;span style='color:#808030; '&gt;.&lt;/span&gt;GetBytes&lt;span style='color:#808030; '&gt;(&lt;/span&gt;name&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// {53, 95, 172, 78, 203, 78}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;要從 byte 轉回來，也有 GetString() 方法可以用，細節就不再說明。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-3504126009810327803?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/3504126009810327803/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/byte.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3504126009810327803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3504126009810327803'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/byte.html' title='.NET 字串轉 Byte 、Byte 轉字串解法'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-4637613705331363133</id><published>2009-07-02T14:35:00.004+08:00</published><updated>2009-07-09T13:34:51.988+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>MySQL Prepare() 使用法 + UTF-8 亂碼解決</title><content type='html'>MySqlCommand 提供的 Prepare() 可以讓你避免自行組合字串的不便性和 SQL Injection 的防止。前面提到過 &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/connector-net-programming-prepared.html"&gt;21.2.4.6 節&lt;/a&gt;有範例可以參考。&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;MySqlConnection conn &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; MySqlConnection&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;server=localhost;user=root;database=test;port=3306;charset=utf8;&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;MySqlCommand cmd &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; MySqlCommand&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;INSERT INTO test VALUES (@ID, @Name)&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; conn&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;cmd&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Prepare&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;cmd&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Parameters&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Add&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;@ID&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; MySqlDbType&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Int16&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;cmd&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Parameters&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Add&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;@Name&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; MySqlDbType&lt;span style='color:#808030; '&gt;.&lt;/span&gt;String&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;for&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;int&lt;/span&gt; i &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;6&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; i &lt;span style='color:#808030; '&gt;&amp;lt;&lt;/span&gt; &lt;span style='color:#008c00; '&gt;10&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; i&lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    cmd&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Parameters&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;@ID&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Value &lt;span style='color:#808030; '&gt;=&lt;/span&gt; i&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    cmd&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Parameters&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;@Name&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Value &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;修羅パンツ&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; i&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    cmd&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ExecuteNonQuery&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;只要下好 SQL Command 後呼叫 Prepare()，再塞入 Parameters，最後 Execute 就可以完成了。這邊範例是先定義好 Parameters 的型態 (ID 是整數、Name 是字串)後，利用迴圈批次新增資料 (Parameters["@ID"].Value) 再呼叫 ExecuteNonQuery 新增，就可以達成重複使用。&lt;br /&gt;&lt;br /&gt;另外，如果在 Connection String 時沒有設定 charset=utf8 (注意是 utf8 不是 utf-8！)，寫入時會預設使用 iso-8859-1 (Latin1) 來寫入，非英數字就會變成 ???。另外新增 MySQL 資料表時，Table 跟每個欄位也要設定使用 utf8 (utf8_general_ci) 這樣讀寫才會正常。&lt;br /&gt;&lt;br /&gt;總結，要排除亂碼，在 MySQL 資料表要設定為 utf8 外，程式建立連線時也要明顯定義 charset=utf8 才可以。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-4637613705331363133?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/4637613705331363133/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/mysql-prepare-utf-8.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/4637613705331363133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/4637613705331363133'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/mysql-prepare-utf-8.html' title='MySQL Prepare() 使用法 + UTF-8 亂碼解決'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-3661703762376608013</id><published>2009-07-02T11:26:00.005+08:00</published><updated>2009-07-02T15:29:19.720+08:00</updated><title type='text'>silverlight 的安裝 &amp; 開發環境. 啾咪</title><content type='html'>首先哩,&lt;br /&gt;&lt;br /&gt;silverlight 可以直接用 VS 2008 來編寫&lt;br /&gt;&lt;br /&gt;她可以看做是 wpf 的子集合&lt;br /&gt;&lt;br /&gt;基本程式撰寫方式也很像&lt;br /&gt;&lt;br /&gt;所以只要熟一種, 另一種可以很快上手.&lt;br /&gt;&lt;br /&gt;接下來,&lt;br /&gt;&lt;br /&gt;就來簡單的說一下如何開始屬於 你/妳 的銀光之旅&lt;br /&gt;&lt;br /&gt;================================&lt;br /&gt;&lt;br /&gt;第一步是如何安裝.&lt;br /&gt;&lt;br /&gt;說到要寫一個銀光程式,&lt;br /&gt;&lt;br /&gt;現在一般業界有幾種來寫她的方法.&lt;br /&gt;&lt;br /&gt;有人用 M$ 出的 expression Blend 來寫 ( 要$&lt;br /&gt;&lt;br /&gt;也有人用記事本就幹出來. ( 不用$ 但是要你的肝 &amp;amp; 大量時間&lt;br /&gt;&lt;br /&gt;當然,&lt;br /&gt;&lt;br /&gt;個人最推薦的還是免費的 VS 2008 來玩.&lt;br /&gt;&lt;br /&gt;要在 vs 2008 上來建立編譯環境的話,&lt;br /&gt;&lt;br /&gt;你需要的是以下東西.&lt;br /&gt;&lt;br /&gt;A) VS 2008. [include C#, web developer.]&lt;br /&gt;&lt;br /&gt;B) 將 VS update 到 SP1.&lt;br /&gt;&lt;br /&gt;C) 下載 M$ 的 silverlight tool.&lt;br /&gt;   這是一種插件, 安裝之後就可以在 VS 中開啟屬於 你/妳 的銀光專案.&lt;br /&gt;&lt;br /&gt;* 這裡要注意的是, 如果 你/妳 A)裝的中文版, C) 也要裝中文版喔.&lt;br /&gt;&lt;br /&gt;裝完之後就可以在建立專案的時候看到這樣的圖:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_bxfSWigfwpk/SkwriYT_PoI/AAAAAAAAAAM/3x7Qmzkz5-0/s1600-h/step3.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_bxfSWigfwpk/SkwriYT_PoI/AAAAAAAAAAM/3x7Qmzkz5-0/s320/step3.png" alt="" id="BLOGGER_PHOTO_ID_5353701926678511234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;這樣就可以來玩 你/妳 的銀光專案了.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;先到這裡, 有新心得再 po . 啾咪.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;這裡有個官方的教學 blog, 還不錯.&lt;br /&gt;&lt;br /&gt;有興趣可以參考一下.&lt;br /&gt;&lt;br /&gt;http://www.microsoft.com/taiwan/msdn/silverlightnet/GetStarted/default.aspx&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-3661703762376608013?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/3661703762376608013/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/silverlight.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3661703762376608013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/3661703762376608013'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/silverlight.html' title='silverlight 的安裝 &amp; 開發環境. 啾咪'/><author><name>馬各</name><uri>http://www.blogger.com/profile/05112202218372116737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_bxfSWigfwpk/SkwriYT_PoI/AAAAAAAAAAM/3x7Qmzkz5-0/s72-c/step3.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-1363686687535381761</id><published>2009-07-02T11:21:00.008+08:00</published><updated>2009-07-09T13:35:05.520+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>MySQL Connector/Net 使用法</title><content type='html'>1. 安裝 MySQL Connector/Net (&lt;a href="/2009/07/c-mysql.html"&gt;參考文章&lt;/a&gt;)&lt;br /&gt;2. 開啟 Visual C# 2008，將 MySql.Data 加入物件瀏覽器的自訂元件集(編輯自訂元件集)，在.NET分頁可以找到 MySql.Data。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_YTQXzGpyark/Skwo2qLkvtI/AAAAAAAAAwE/m_fp-7UTWcU/s1600-h/importLib.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 282px; height: 320px;" src="http://1.bp.blogspot.com/_YTQXzGpyark/Skwo2qLkvtI/AAAAAAAAAwE/m_fp-7UTWcU/s320/importLib.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5353698976537558738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3. 在專案要先「參考」MySql.Data才能在專案中使用，快速新增參考的方式很簡單，在 2. 項中我們已經新增了 MySql.Data，只要選取後按下圖中的按鈕就可以快速加入參考。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_YTQXzGpyark/Skwpktw-GWI/AAAAAAAAAwM/D3zPzwOYsBc/s1600-h/addRef.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 108px;" src="http://3.bp.blogspot.com/_YTQXzGpyark/Skwpktw-GWI/AAAAAAAAAwM/D3zPzwOYsBc/s320/addRef.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5353699767773698402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;4. 以下是連接 MySQL 資料庫的範例程式碼：&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;overflow:auto;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Windows&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Forms&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; MySql&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Data&lt;span style='color:#808030; '&gt;.&lt;/span&gt;MySqlClient&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;namespace&lt;/span&gt; WindowsFormsApplication1 &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; partial &lt;span style='color:#800000; font-weight:bold; '&gt;class&lt;/span&gt; Form1 &lt;span style='color:#808030; '&gt;:&lt;/span&gt; Form &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; Form1&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            InitializeComponent&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;private&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; Form1_Load&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;object&lt;/span&gt; sender&lt;span style='color:#808030; '&gt;,&lt;/span&gt; EventArgs e&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            MySqlConnection conn &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; MySqlConnection&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;server=localhost;user=root;database=test;port=3306;charset=utf8;&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;try&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;                conn&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Open&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                MySqlCommand cmd &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; MySqlCommand&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;SELECT * FROM test&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; conn&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                MySqlDataReader rdr &lt;span style='color:#808030; '&gt;=&lt;/span&gt; cmd&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ExecuteReader&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                &lt;span style='color:#800000; font-weight:bold; '&gt;while&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;rdr&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Read&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;                    &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;label1&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Text &lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; rdr&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt; -- &lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; rdr&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#008c00; '&gt;1&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; &lt;span style='color:#808030; '&gt;+&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;\n&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                rdr&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Close&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;                conn&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Close&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800080; '&gt;}&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;catch&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;Exception ex&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;                MessageBox&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Show&lt;span style='color:#808030; '&gt;(&lt;/span&gt;ex&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ToString&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Form1 有個 Label 叫做 label1，作為顯示資料庫的項目用。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-1363686687535381761?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/1363686687535381761/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/mysql-connectornet.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1363686687535381761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/1363686687535381761'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/mysql-connectornet.html' title='MySQL Connector/Net 使用法'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_YTQXzGpyark/Skwo2qLkvtI/AAAAAAAAAwE/m_fp-7UTWcU/s72-c/importLib.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-7837719846137532257</id><published>2009-07-01T22:18:00.001+08:00</published><updated>2009-07-01T22:21:07.783+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>.NET Framework 類別庫</title><content type='html'>雖然 Visual Studio 有內建整個文件了，但網路上的版本說不定比較新比較好。&lt;br /&gt;&lt;br /&gt;這是 .NET Framework 3.5的文件：&lt;a href="http://msdn.microsoft.com/zh-tw/library/ms229335.aspx"&gt;點此開啟&lt;/a&gt;。跟 Java API References 一樣，屬於必讀的內容。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-7837719846137532257?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/7837719846137532257/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/net-framework.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7837719846137532257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7837719846137532257'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/net-framework.html' title='.NET Framework 類別庫'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-2845632309043762271</id><published>2009-07-01T21:54:00.004+08:00</published><updated>2009-07-09T13:35:14.423+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>C# 連接 MySQL 資料庫</title><content type='html'>我們寫的系統預定會連接後端資料庫，是故一定要知道怎麼用程式連接。因為我們選的是 .NET 平台，又因為 .NET 特性，只要函式庫支援 .NET，所有 .NET 語言都可以使用它。所以說 RFID 廠商提供的 .NET 函式庫我們可以在 VB.NET, VC#, VC++ 等語言使用。同樣的，MySQL官方網站有給 .NET 平台的 Connector 可以用：&lt;a href="http://dev.mysql.com/downloads/connector/net/"&gt;下載網址&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;沒解讀錯誤的話，這個套件使用 GPL 授權，這意味著使用的程式也要以 GPL 授權嗎？這值得玩味。&lt;br /&gt;&lt;br /&gt;另外這個 Connector 有 Manual：&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/connector-net.html"&gt;點此開啟&lt;/a&gt;，連結的是 MySQL 5.1 版的文件，但應該相去不遠。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/connector-net-programming.html"&gt;&lt;br /&gt;21.2.4 節&lt;/a&gt;才開始教你如何建立 MySQL 連線並取得資料，這是寫程式時會用到的部分。&lt;br /&gt;&lt;br /&gt;為了防止自行組合 SQL 字串而給駭客有 SQL Injection 隱碼攻擊的機會，很多函式庫會提供 PreparedStatement 等類似的方式來幫助程式設計師來組合字串。MySQL Connector/Net 也不例外，&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/connector-net-programming-prepared.html#connector-net-programming-prepared-preparing"&gt;21.2.4.6 節&lt;/a&gt;有提到使用 Prepare() 方法。&lt;br /&gt;&lt;br /&gt;其他等遇到再說。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-2845632309043762271?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/2845632309043762271/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-mysql.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2845632309043762271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/2845632309043762271'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-mysql.html' title='C# 連接 MySQL 資料庫'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-725987426200612365</id><published>2009-07-01T21:45:00.004+08:00</published><updated>2009-07-01T22:17:43.763+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><category scheme='http://www.blogger.com/atom/ns#' term='參考資料'/><title type='text'>C# 連接 RFID 開發工具</title><content type='html'>一般來說 RFID 開發工具會有讀卡機、幾張卡片 (Tag)，就沒了。好一點的廠商會附送沒啥用的 Manual 和 Demo，但真正重要的還是 SDK。如果沒有 SDK 你知道要怎麼要求讀卡機讀取嗎？&lt;br /&gt;&lt;br /&gt;據我研究，讀卡機利用 COM Port 與電腦以序列埠 (Serial Port) 連結，你只要開啟連線，丟封包給讀卡機，再解讀讀卡機丟回來的封包，就能完成工作。但封包的詳細規格因讀卡機的實作而有不同，我們手上的是 MIFARE 卡，也有書提到如何寫封包。但有輪子的話，何必自己造呢？沒錯，就是 SDK。我們透過廠商拿到了給 .NET 平台的函式庫，只要呼叫預先寫好的方法，就能順利跟讀卡機對談，輕鬆又方便。&lt;br /&gt;&lt;br /&gt;當然，你也可以不使用函式庫，直接生成指定格式的封包以 Serial Port 通訊與讀卡機連線，但既然有更方便的方案，為何不使用呢？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-725987426200612365?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/725987426200612365/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-rfid.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/725987426200612365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/725987426200612365'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/c-rfid.html' title='C# 連接 RFID 開發工具'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2240534525438980735.post-7086565434665322460</id><published>2009-07-01T21:31:00.003+08:00</published><updated>2009-07-01T21:44:26.202+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='開發環境'/><title type='text'>Microsoft Visual Studio.NET 2008 Express Edition</title><content type='html'>我們的畢業專題將會採用 Microsoft 提供的免費開發工具 Visual Studio.NET 2008 Express Edition 來設計，其中 Visual C# 是我們選定的程式語言，因為它近似 Java，對於學過 Java 的我們來說，應該是最快上手的語言了。為什麼不選 VB.NET 的原因是本人認為 VB 的語言結構不夠物件導向，只是單純的硬塞的感覺，這只是本人自 VB6 所得來的印象。&lt;br /&gt;&lt;br /&gt;因為要一次為每個成員都建置好環境，一般提供的線上安裝檔自然就不合用。還好有提供離線安裝 ISO 檔，可以下載後直接以虛擬光碟掛載安裝，十分省事。下載映像檔的地方在&lt;a href="http://www.microsoft.com/express/download/"&gt;這裡&lt;/a&gt;，下方的 Offline Install 即可選擇語系並下載。&lt;br /&gt;&lt;br /&gt;繁體中文版含 SP1 映像檔檔案大小：943MB。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2240534525438980735-7086565434665322460?l=rfid-fantasy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rfid-fantasy.blogspot.com/feeds/7086565434665322460/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/microsoft-visual-studionet-2008-express.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7086565434665322460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2240534525438980735/posts/default/7086565434665322460'/><link rel='alternate' type='text/html' href='http://rfid-fantasy.blogspot.com/2009/07/microsoft-visual-studionet-2008-express.html' title='Microsoft Visual Studio.NET 2008 Express Edition'/><author><name>scribe</name><uri>http://www.blogger.com/profile/05127342542869247723</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-5hTQoiYesm4/TsJJTKTooHI/AAAAAAAABHY/0UZQEnwhZFc/s220/kanon_someone.jpg'/></author><thr:total>0</thr:total></entry></feed>
