10/23/2008

Unix下為你的檔案加密

如果你有使用過WinRAR,那你應該知道WinRAR在壓縮時提供一項功能,可以為壓縮檔加上密碼,這樣子一來沒有密碼就 無法解開檔案,也就可以防止資訊外流。在Unix下壓縮通常我們會使用tar+gzip來達成,但是想為檔案多加一層保護時,通常就不知該如何下手了。
其實做法很簡單,所要使用的指令就只有openssl,只要你有裝openssl的套件就可以了。在Linux下預設就會安裝,如果你的是其他的Unix like的系統,你就得要自己檢查了。openssl中我們要用到的是enc(Encoding And Cipher)這個子功能,使用的方式如下。
openssl enc -e -cipher_method -in input_file -out output_file
其中-e表示要加密、-d表示解密、-in表示輸入的檔案、-out表示輸出的檔案、-cipher_method要看你選擇什麼加密方法,可以是-des、-des3、-bf......等。我們看個範例先。

# openssl enc -e -des3 -in /etc/hosts -out /tmp/hosts.cpt
enter des-ede3-cbc encryption password:12345
Verifying - enter des-ede3-cbc encryption password:12345

上面的範例使用des3的加密法將/etc/hosts加密,然後輸出成/tmp/hosts.cpt。過程中你所輸入密碼,也是你解開檔案 時的密碼。
那要如何解開檔案呢?剛有講到-e表示要加密(encrypt),-d就表示要解密(decrypt)了。我們看一下解密的範例。

# openssl enc -d -des3 -in /tmp/hosts.cpt
enter des-ede3-cbc decryption password:12345
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
192.168.0.1 rac1-priv
192.168.0.2 rac2-priv
192.168.0.101 rac1-vip
192.168.0.102 rac2-vip

上面的例子和加密幾乎沒什麼差別。把-e換-d,-in變成了剛加密時所產生的/tmp/hosts.cpt。然後-out不見了,openssl 如果沒有指定-out或是-in的話,它會接受從stdin輸入或是輸出到stdout。所以上面的範例中,解密後你會看到原本/etc/hosts的內容輸出到螢幕上。
因為openssl可以使用stdin和stdout,所以只要透過幾個命令的組合,就可以很容易的做到像WinRAR的加密功能。下面的例子將/etc下所有的檔案變成一個加密過的壓縮檔。因為有的tar並不支援-z這個壓縮的參數,所以必須要拆成tar+gzip。Linux下的tar則都有這個功能,所以你也可以直接用tar zcf - | openssl....來取代。要解壓縮時,怎麼去,就怎麼回來,把原來的動作倒著作一次就可以了。

# cd /etc
# tar cf - * | gzip -c | openssl enc -e -des3 -out /tmp/hosts.tar.gz.cpt
enter des-ede3-cbc encryption password:12345
Verifying - enter des-ede3-cbc encryption password:12345
# file /tmp/hosts.tar.gz.cpt
/tmp/hosts.tar.gz.cpt: data
# openssl enc -d -des3 -in hosts.tar.gz.cpt |gzip -dc | tar -xf -
enter des-ede3-cbc decryption password:12345

如果不喜歡手動敲密碼,那也可以。openssl允許你可以把密碼存成一個檔案,只要在命令列多加-k的參數告訴它密碼檔案在那裡就可以了。有時候想密碼也是一件很惱人的事情,每次我換密碼的時候總是要想很久。如果你跟我一樣有這種困擾的話,有一個方法可以幫上忙。
我們可以利用/dev/random這個系統的亂數裝置來幫我們產生key檔,也就是我們要的密碼。如下面所示,用dd產生一個 crypt.key的檔,你可以自己看一下它的內容是什麼,然後就利用這個檔案來做加解密的動作。如此一來你只要保謢好這個檔案不要遺失,你就可以不用再記密碼了。

# dd if=/dev/random of=/tmp/crypt.key bs=256 count=1
0+1 records in
0+1 records out
# openssl enc -e -bf -k /tmp/crypt.key -in /etc/hosts -out /tmp/host.cpt2
# openssl enc -d -bf -k /tmp/crypt.key -in /tmp/host.cpt2
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
192.168.0.1 rac1-priv
192.168.0.2 rac2-priv
192.168.0.101 rac1-vip
192.168.0.102 rac2-vip

很多時候會需要把資料備份到磁帶去,但是萬一磁帶遺失的話該如何是好,尤其如果裡面是敏感性資料,如信用卡客戶資料 、病歷資料......等,那可就不得了了。別怕!我們可以把要備到磁帶資料加密。

# tar cf - /report/* | openssl enc -e -bf -k /tmp/crypt.key | dd of=/dev/st0
# dd if=/dev/st0 | openssl enc -d -bf -k /tmp/crypt.key | tar -xf -

在Solaris 10以前,如果有需要通常我也會安裝openssl的套件。但現在如果只是為了要加密檔案的話Solaris就內建了功能差不多的指令,encrypt和decrypt。參數和openssl也差不多。
encrypt -l會列出可用的演算法和key的大小的資訊。如果要用來加密檔案的話要使用-a(algorithm)加上演算法的名稱,如3des。

# encrypt -l
Algorithm Keysize: Min Max (bits)
------------------------------------------
aes 128 128
arcfour 8 128
des 64 64
3des 192 192

看看下面加密和解密的指令和openssl是不是還挺像的呢?

# encrypt -a 3des -i /etc/hosts -o /tmp/hosts.cpt
Enter key:
# decrypt -a 3des -i /tmp/hosts.cpt
Enter key:
#
# Internet host table
#
127.0.0.1 localhost

當然也可以使用key檔,如果你要用dd產生的話,請注意key的長度限制。如3des的長度為192,故dd的count要等於24(192/8) ,如果是arcfour則為8到128。

# dd if=/dev/random of=/tmp/3des.key bs=24 count=1
# tar cf - * | gzip -c | encrypt -a 3des -k /tmp/3des.key -o /tmp/etc.tar.gz.cpt
# decrypt -a 3des -k /tmp/3des.key -i /tmp/etc.tar.gz.cpt|gzip -dc|tar tf -

再來要談的和檔案的加解密沒什麼關係,不過和加密倒是有關。算了,不知道自己在講什麼。在Linux下我們常會使用md5sum 來驗證檔案是否有更動過或是下載的檔案是否完整。如,

# md5sum /etc/hosts
dd7b3e9f10bbbd510a4637e7f29d3533 /etc/hosts

但在Solaris裡並沒有相對應的指令,不過現在Solaris 10提供了一個指令可以做到一樣的事情,那就是digest。digest和剛談到的encrypt一樣都是SCF(Solaris OS Cryptographic Framework)的指令,所以參數也很類似。-l也是列出支援的演算法,-a則是要使用的演算法。要使用像md5sum的查驗功能的話,那當然就是用md5的演算法囉。

# digest -l
sha1
md5
sha256
sha384
sha512
# digest -a md5 /etc/hosts
26cc2a22d93ecf862c8849ecaa29739c

如果習慣使用md5sum的話,你可以建個alias來代替。

# alias md5sum='digest -va md5'
# md5sum /etc/hosts
md5 (/etc/hosts) = 26cc2a22d93ecf862c8849ecaa29739c

如果你懷疑你的系統遭到入侵,程式有可能遭到竄改時,我們可以用digest取得md5的hash值,然後到Sun的filefingerprint 網站(http://sunsolve.sun.com/pub-cgi/fileFingerprints.pl)去做檢查。

# md5sum /bin/passwd
md5 (/bin/passwd) = f8a67ae893f0ced25b2bd7fd1ccc9b4e

我在Solaris 10 x86的系統下,以/usr/passwd為例,取得md5的值後,將f8a67ae893f0ced25b2bd7fd1ccc9b4e貼到上述 的網址,應該會得到如下的訊息。

 f8a67ae893f0ced25b2bd7fd1ccc9b4e -  - 1 match(es)

* canonical-path: /usr/bin/passwd
* package: SUNWcsu
* version: 11.10.0,REV=2005.01.21.16.34
* architecture: i386
* source: Solaris 10/x86

這表示passwd這一支程式的內容並沒有變動過,如果得到的訊息是如下的話,

 f8a67ae893f0ced25b2bd7fd1ccc9b4a -  - 0 match(es)
Not found in this database.

你的程式要不是因某些原因變動過,那就可能是系統已經有出現問題了。快檢查硬體或確認是否有人入侵吧。

1 則留言:

D. 提到...

大陸真的有極多的黑客聯盟人才輩出
不論是黑客防線, nohack雜誌, 邪惡八禁制, 看雪 都有他們的長處

台灣就是須要有板住這種人的support