[技術] PGP & GnuPG

Written on 12:32 上午 by Yu Lai

最近需要和國外的客戶合作,
期間有用到PGP的加密來傳送機密文件,用的就是PGP。
PGP是一種混合密碼系統,它結合了傳統密碼法和公開金鑰密碼法的多種最棒的特色。

在加密時,PGP會產生一個階段金鑰,這把階段金鑰是一種只有當時有效的秘密金鑰,
是利用任意的滑鼠移動以及鍵盤輸入所產生的亂數。
它以非常秘密而快速的傳統加密演算法來加密純文字,而產生出密文。
當資料加密完成後,這把階段金鑰接著就會開始以收信者的公鑰被加密。
這個被公鑰加密過的階段金鑰將會與密文一併交付給收信者。

解密的過程就是反向運作了。
收信者的PGP會利用他的私鑰來還原那把暫時的階段金鑰,
然後PGP再利用這把階段金鑰來將傳統加密過的密文解密。

在此我用的是Gnu所提供的GnuPG,
GnuPG是GNU由RFC4880所訂出來的OpenPGP的實做。
以下是GnuPG在使用上的說明。

1. 產生鑰匙:

gpg --gen-key

一開始一定沒有自己的一對公私鑰,我們可以透過--gen-key來產生。

2. 輸出鑰匙:

gpg -a -o [Filename] --export [USERID]

其中-a是指輸出成ASCII格式,-o則是指定輸出到檔案,
--export則是將[USERID]的公鑰輸出。
一般我們是將一開始產生出來的公私鑰的公鑰export出檔案來,
然後就可以將公鑰傳送給別人了。

3. 輸入鑰匙

gpg --import [Filename]

當你收到一把別人的公鑰(或好幾把公鑰)時,為了能使用它們,
你得把它們加進你的鑰匙數據庫。

4. 列出公鑰

gpg --list-keys

5. 列出私鑰

gpg --list-secret-keys

6. 刪除公鑰

gpg --delete-key [USERID]

7. 刪除私鑰

gpg --delete-secret-key [USERID]

8. 鑰匙簽名

gpg --sign-key [USERID]

PGP在使用上有一個最大的弱點,那就是公鑰的真實性問題。
如果用的是錯誤的公鑰,你加密的價值就全沒了。
要克服這種風險,必須確信這把鑰匙是真實的,並在上面簽名,
簽名就表示承認鑰匙上的用戶身份確實是這把鑰匙的主人。

9. 加密

gpg -r [Recipient] -e [filename]

系統會用[Recipient]的公鑰對[filename]這個檔案加密,
並產生出[filename].pgp檔來。
這樣[Recipient]即可用自己的私鑰進行解密的動作,
還原出檔案來。

10. 解密

gpg -d [filename].pgp

當你收到別人用你的公鑰加密的檔案時,即可用-d來進行解密,
還原出檔案來。

[技術] Boost C++ Libraries的shared_ptr

Written on 12:18 上午 by Yu Lai

Ref: http://msnlite.org/thread-365-1-1.html

C++是使用pointer來靈活方便地控制memory與instance的,這是它強大的原因之一,
但它缺乏像Java一樣的Garbage Collector機制來回收instance,
因此Programmer必須要自己手動delete掉new出來的instance。

這在軟體規模小的時候還好,但在規模大、多人協同工作、多線程環境加入時,
往往memory與instance的分配和釋放變的越來越難控制。

因此Boost C++ Libraries提供了shared_ptr,
shared_ptr實際上是一個Template Class,
透過instance成不同Class,為Class提供Pointer操作。

例如:

shared_ptr<int> p1(new int);
shared_ptr<int> p2=p1;

這樣p1和p2都可以point到int。
shared_ptr Class內有2個variable,一個是原始pointer,
可以用get()取得,用reset(T* p)可以重新設置。
另一個是instance的引用次數,其值可以用use_count()獲得。
它會隨著引用的shared_ptr來增加,當shared_ptr銷毀時,
引用次數也會減少,當減少到0時,shared_ptr會呼叫delete function來delete instance。

使用方法:
shared_ptr<Object> p1(new Object);        //Use constructor
shared_ptr<Object> p2=p1;        //assign
shared_ptr<Object> p3.reset(p1);        //reset function

p1.reset();        //放棄引用

另外shared_ptr也可以配合malloc()來使用,但這樣point到的空間沒辦法被正常釋放掉,
必須額外定義delete function才行,malloc()的delete function即為free()。
所以使用如下:
shared_ptr p(malloc(100),free);

最後,我想坦白說句我心理的話: "C++搞成這樣,實在只是讓人覺得更難用而已。= ="