標籤:用戶端 彩虹 實際應用 資料加密 服務端
數位簽章:對資料和私密金鑰進行hash運算得到訊息摘要,連同訊息本身一塊發給用戶端。資料簽名強調用戶端接收到的資料是來自特定服務端,服務端具有對資料不可否認性。用戶端通過確認此次簽名的正確性來判斷拿到的訊息是否來自特定服務端。
資料加密:對資料進行加密,有對稱式加密和非對稱式加密兩種。PHP中常使用 mcrypt和openssl擴充對資料進行加解密。mcrypt常用在對稱式加密中,openssl常用在非對稱式加密中。另外在編程中還經常使用到一種單項散列密碼編譯演算法,比如MD5,HASH,SHA1,password_hash等對資料(通常是使用者密碼)進行加密,這種加密是不可解密的(理論上沒有不可解密的演算法,只是說解密的機器耗時較長便認為不可解密。一般情況下仍然可採用暴力字典破解和尋找彩虹表的方式破解),hash單向加密一般會有個鹽值。
在實際應用情境中,有只使用資料簽名然後明文傳輸資料的(這是最多的),也有使用資料簽名和加密資料進行傳輸的,一半很少只有資料加密而沒有資料簽名的情況吧。、
MCRYPT加密
首先明確這幾個概念
演算法名稱:即 MCRYPT擴充所支援的密碼演算法,詳細列表可參見php源碼mcrypt.php檔案。mcypt支援的演算法見文末。
演算法模式:MCRYPT_MODE_modename 常量中的一個,或以下字串中的一個:"ecb","cbc","cfb","ofb","nofb" 和 "stream"。
演算法模組:使用mcrypt_module_open()開啟的指定演算法和模式對應的模組,是一個資源類型
初始向量:加密時需要用到的一個參數,使用mcrypt_create_iv()從隨機源建立
初始向量大小:是指由mcrypt_get_iv_size()返回的指定演算法/模式組合的初始向量大小。mcrypt_create_iv()根據初始向量大小建立初始向量。
mcrypt加密解密需要以下幾個步驟
加密:
1 使用mcrypt_module_open()開啟指定演算法和模式的對應模組。
2 mcrypt_get_iv_size()獲得該模組初始向量長度,mcrypt_enc_get_iv_size($td)
3 根據初始向量長度建立初始向量 mcrypt_create_iv()
4 初始化加密所需的緩衝區 mcrypt_generic_init()
5 加密資料 mcrypt_generic()
6 結束加密,執行清理工作 mcrypt_generic_deinit()
解密需要以下幾個步驟
1 初始化解密模組 mcrypt_generic_init()
2 解密資料 mcrypt_decrypt()
3 結束解密,執行清理工作 mcrypt_generic_deinit()
4 關閉開始時開啟的模組 mcrypt_module_close
整個加解密的過程類似建立圖片的過程,首先建立畫布資源,建立顏色,填充,最後image_destroy一樣。
然後來看一下上面提到的幾個函數的用法
1.mcrypt_module_open — 開啟演算法和模式對應的模組
resource mcrypt_module_open ( string $algorithm , string $algorithm_directory , string $mode , string $mode_directory )
返回資源類型
參數說明見表 1-1
表1-1
參數 |
說明 |
algorithm |
MCRYPT_ciphername 常量中的一個,或者是字串值的演算法名稱。見文末 |
algorithm_directory |
algorithm_directory 參數指示加密模組的位置。 如果你提供此參數,則使用你指定的值。 如果將此參數設定為空白字串(""),將使用 php.ini 中的 mcrypt.algorithms_dir 。 如果不指定此參數,則使用 libmcrypt 的編譯路徑 (通常是 /usr/local/lib/libmcrypt)。 |
mode |
MCRYPT_MODE_modename 常量中的一個,或以下字串中的一個:"ecb","cbc","cfb","ofb","nofb" 和 "stream"。 |
mode_directory |
algorithm_directory 參數指示加密模式的位置。 如果你提供此參數,則使用你指定的值。 如果將此參數設定為空白字串(""),將使用 php.ini 中的 mcrypt.modes_dir 。 如果不指定此參數,則使用 libmcrypt 的編譯路徑 (通常是 /usr/local/lib/libmcrypt)。 |
2.mcrypt_get_iv_size — 返回指定演算法/模式組合的初始向量大小
int mcrypt_get_iv_size ( string $cipher , string $mode )
返回初始向量大小
可使用mcrypt_enc_get_iv_size($td) 代替,$td可以是由 mcrypt_module_open() 返回的資源作為參數。
參數說明見表 1-2
表1-2
參數 |
說明 |
cipher |
MCRYPT_ciphername 常量中的一個,或者是字串值的演算法名稱。 |
mode |
MCRYPT_MODE_modename 常量中的一個,或以下字串中的一個:"ecb","cbc","cfb","ofb","nofb" 和 "stream"。 |
3.mcrypt_create_iv — 從隨機源建立初始向量
string mcrypt_create_iv ( int $size [, int $source = MCRYPT_DEV_URANDOM ] )
返回初始向量
表1-3
參數 |
說明 |
size |
初始向量大小。可由mcrypt_get_iv_size或mcrypt_enc_get_iv_size獲得 |
source |
初始向量資料來源。可選值有: MCRYPT_RAND (系統隨機數產生器), MCRYPT_DEV_RANDOM (從 /dev/random 檔案讀取資料) 和 MCRYPT_DEV_URANDOM (從 /dev/urandom 檔案讀取資料)。 在 Windows 平台,PHP 5.3.0 之前的版本中,僅支援 MCRYPT_RAND。 |
4.mcrypt_generic_init — 初始化加密所需的緩衝區
int mcrypt_generic_init ( resource $td , string $key , string $iv )
如果發生錯誤,將會返回負數: -3 表示密鑰長度有誤,-4 表示記憶體配置失敗, 其他值表示未知錯誤, 同時會顯示對應的警告資訊。 如果傳入參數不正確,返回 FALSE。
表1-4
參數 |
說明 |
td |
加密描述符。由mcrypt_module_open獲得的資源類型 |
key |
調用 mcrypt_enc_get_key_size() 函數獲得的密鑰最大長度。 小於最大長度的數值都被視為非法參數。 |
iv |
通常情況下,向量大小等於演算法的分組大小, 但是你應該通過 mcrypt_enc_get_iv_size() 函數 來獲得這個值。在 ECB 模式下,初始向量會被忽略, 在 CFB,CBC,STREAM,nOFB 和 OFB 模式下,必須提供初始向量。 初始向量要求是隨機的,並且是唯一的(不需要是安全的)。 加密和解密必須使用相同的初始向量。 如果你不想使用初始向量,請將其設定為全 0 值,但是不建議你這麼做。 |
5.mcrypt_generic — 加密資料
string mcrypt_generic ( resource $td , string $data )
返回加密後的資料
表1-5
參數 |
說明 |
td |
加密描述符。由mcrypt_module_open獲得的資源類型 |
data |
要加密的資料 |
6.mdecrypt_generic — 解密資料
string mdecrypt_generic ( resource $td , string $data )
返回解密後的字串
請注意,由於存在資料補齊的情況, 返回字串的長度可能和明文的長度不相等
參數 td 加密描述符。由mcrypt_module_open獲得的資源類型,data是需要解密的密文
6.mcrypt_generic_deinit — 對加密模組進行清理工作
bool mcrypt_generic_deinit ( resource $td )
參數 td 加密描述符。由mcrypt_module_open獲得的資源類型
本函數終止由加密描述符(td)指定的加密模組, 它會清理緩衝區,但是並不關閉模組。 要想關閉加密模組, 你需要自行調用 mcrypt_module_close() 函數。 (但是 PHP 會在指令碼末尾為你關閉已開啟的加密模組)
7.mcrypt_module_close — 關閉加密模組
bool mcrypt_module_close ( resource $td )
參數 td 加密描述符。由mcrypt_module_open獲得的資源類型
下面一個例子說明加解密過程
class McryptModel{ protected $td = ‘‘; protected $iv = ‘‘; protected $key = ‘‘; private static $instance = NULL; private function __construct($cipher,$mode,$key) { $this->cipher = $cipher; $this->mode = $mode; $this->key = $key; } public static function getInstance($cipher=MCRYPT_RIJNDAEL_128,$mode=MCRYPT_MODE_CBC, $key=‘H5gOs1ZshKZ6WikN‘) { if (self::$instance == NULL) { self::$instance = new self($cipher,$mode,$key); } return self::$instance; } function encrypt($str) { $td = mcrypt_module_open($this->cipher,‘‘,$this->mode,‘‘);//開啟演算法模組 $this->td = $td; $iv_size = mcrypt_enc_get_iv_size($td);// 擷取向量大小 $iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);//初始化向量 $this->iv = $iv; $num = mcrypt_generic_init($td,$this->key,$iv);//初始化加密空間 //var_dump($num); $encypt = mcrypt_generic($td,$str);//執行加密 mcrypt_generic_deinit($td); // 結束加密,執行清理工作 return base64_encode($encypt);//base64編碼成字串適合資料轉送 } function decyrpt($str) { $str = base64_decode($str); $td = $this->td; mcrypt_generic_init($td,$this->key,$this->iv); $decrypt = mdecrypt_generic($td,$str); mcrypt_generic_deinit($td); mcrypt_module_close($td);//關閉演算法模組 return $decrypt; }}$m = McryptModel::getInstance();echo $s = $m->encrypt(‘hello‘); // 輸出 4cnqrVkCjcr5unW0ySUdWg==echo $m->decyrpt($e); // 輸出 hello
mcrypt加解密屬於對稱式加密,演算法是公開的,其安全性是來自對秘鑰的保密。使用者可選擇不同的演算法名稱和演算法模式。常用的演算法是MCRYPT_RIJNDAEL_128,MCRYPT_DES,rijndael-256等,常用的模式是 cbc,ecb
php中支援的演算法如下:
MCRYPT_3DES
MCRYPT_ARCFOUR_IV ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_ARCFOUR ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_BLOWFISH
MCRYPT_CAST_128
MCRYPT_CAST_256
MCRYPT_CRYPT
MCRYPT_DES
MCRYPT_DES_COMPAT ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_ENIGMA ( 僅 libmcrypt > 2.4.x 可用,MCRYPT_CRYPT 的別名)
MCRYPT_GOST
MCRYPT_IDEA (非免費演算法)
MCRYPT_LOKI97 ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_MARS ( 僅 libmcrypt > 2.4.x 可用,非免費演算法)
MCRYPT_PANAMA ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_RIJNDAEL_128 ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_RIJNDAEL_192 ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_RIJNDAEL_256 ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_RC2
MCRYPT_RC4 ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_RC6 ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_RC6_128 ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_RC6_192 ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_RC6_256 ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_SAFER64
MCRYPT_SAFER128
MCRYPT_SAFERPLUS ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_SERPENT( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_SERPENT_128 ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_SERPENT_192 ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_SERPENT_256 ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_SKIPJACK ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_TEAN ( 僅 libmcrypt 2.2.x 可用 )
MCRYPT_THREEWAY
MCRYPT_TRIPLEDES ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_TWOFISH ( mcrypt 2.x 之前的版本,或者 2.4.x 之後版本可用 )
MCRYPT_TWOFISH128 (TWOFISHxxx 在新的 2.x 版本可用,但在 2.4.x 版本不可用)
MCRYPT_TWOFISH192
MCRYPT_TWOFISH256
MCRYPT_WAKE ( 僅 libmcrypt > 2.4.x 可用 )
MCRYPT_XTEA ( 僅 libmcrypt > 2.4.x 可用 )
使用php mcrypt加密解密