為什麼要這麼做呢? 即便有 https(ssl) 與網站間做資料傳轉協定,也未怕是 100% 安全,最好還是能在資料傳遞間做好加密,確保只有你自己可以看到完整資料…
確保後端(PHP)與前端(iOS, ANdroid)資料傳遞是安全的
你也能選擇另一種加密方式 : [PHP] 範例實做 RSA, 公私鑰非對稱加解密 ( 個人比較推薦的方式 )
為什麼要做資料加密?
除了個資法之外,使用者的行為和信用卡資料也需要加密保護或是不實際儲存…
你也不希望,某天… 你的上網記錄被公佈或是購物記錄曝光吧。
裝置與裝置間或是使用者與伺服器之間的資料傳輸,很容易被監聽或是被側錄
前陣子很紅的文章
看完這駭客四部曲,保證你以後再也不敢連到公共 Wi-Fi 了
即便你的系統很安全,你也不能保證使用者的網路環境是安全的!
https 憑證也分很多種等級的…
無論如何, https 傳輸己經是基本了
如何做 AES 加密?
資料加密的方式很多,我認為使用 AES 或是公鑰、私鑰 public, private Key 的方式是比較有效又快效的解決方案!
今天就說明一下 AES 在 PHP 上的做法…
(我並不是資安專長,簡單說明方法與 Example Code)
首先,先瞭解一下 PHP mcrypt_encrypt 與 mcrypt_decrypt
ps: 記得為 php 安裝 php mcrypt extension
確保加密、解密兩方的編碼模式相同:CBC 與 EBC
最好能與 mobile APP 工程師一塊處理、決定
選擇 128 或 256 位元方式,愈複雜被破解的機率就愈低!但是相對解密時速度也就愈慢
PHP 實做 AES 資料加密
首先 定義 key 與 iv
$hash_string = 'test';
$hash = hash('SHA384', $hash_string, true);
$app_cc_aes_key = substr($hash, 0, 32);
$app_cc_aes_iv = substr($hash, 32, 16);
上述將 金鑰 設定為 test
利用 hash() 將 純文字 轉為 binary
使用 SHA384,hash 出來的 binary 長度為 48
若不帶入 true 參數,則會回傳純文字,長度為 96
這個部份注意一下即可
接著要實做 AES 256 所以將 key 與 iv 的長度設為 32 與 16
ps: binary 與 純文字要處理的 key, iv 長度也會不同,要注意一下哦!
$data = 'cola is bear';
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
$encrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $app_cc_aes_key, $data, MCRYPT_MODE_CBC, $app_cc_aes_iv);
$encrypt_text = base64_encode($encrypt);
設定要加密的內容為 cola is bear
最後使用 base64_encode() 將加密後內容轉為純文字方便傳遞
如果把 $encrypt 輸出畫面上會顯示…
��@���'�����'�)
這就是 binary 資料
經過 base64_encode() 之後的 $encrypt_text
這串文字就能更方便的在後端與前端之間傳遞了
PHP 實做 AES 資料解密
接下來是解密的部份…
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $app_cc_aes_key, $encrypt, MCRYPT_MODE_CBC, $app_cc_aes_iv);
$padding = ord($data[strlen($data) - 1]);
$decrypt_text = substr($data, 0, -$padding);
解密的部份就相對簡單了,最後的 $decrypt_text 就是解密後的結果了
ps:之後記得在解密前先把傳入值做 base64_decode() 哦
範例結果
這次測試的 example code 和結果
測試用 example code
echo '<pre>';
$hash_string = 'test';
$hash = hash('SHA384', $hash_string, true);
echo "hash : ";
var_dump($hash);
echo '<hr>';
$app_cc_aes_key = substr($hash, 0, 32);
$app_cc_aes_iv = substr($hash, 32, 16);
echo "app_cc_aes_key : ";
var_dump($app_cc_aes_key);
echo '<br>';
echo "app_cc_aes_iv :";
var_dump($app_cc_aes_iv);
echo '<hr>';
$data = 'cola is bear';
echo "data : {$data}";
echo '<hr>';
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
$encrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $app_cc_aes_key, $data, MCRYPT_MODE_CBC, $app_cc_aes_iv);
$encrypt_text = base64_encode($encrypt);
echo "encrypt :";
var_dump($encrypt);
echo '<br>';
echo "encrypt_text :";
var_dump($encrypt_text);
echo '<hr>';
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $app_cc_aes_key, $encrypt, MCRYPT_MODE_CBC, $app_cc_aes_iv);
$padding = ord($data[strlen($data) - 1]);
$decrypt_text = substr($data, 0, -$padding);
echo "decrypt_text : {$decrypt_text}";
echo '<hr>';
exit('--done--');
精美版 example code
<?php namespace App\Library;
Class MyAES
{
private $app_cc_aes_key;
private $app_cc_aes_iv;
function __construct()
{
$hash_string = 'cola-secret-key'; // 可以由外部帶入
if(is_null($hash_string)) {
return false;
}
$hash = hash('SHA384', $hash_string, true);
$this->app_cc_aes_key = substr($hash, 0, 32);
$this->app_cc_aes_iv = substr($hash, 32, 16);
}
public function encrypt($data)
{
return base64_encode(self::aes256_cbc_encrypt($data, $this->app_cc_aes_key, $this->app_cc_aes_iv));
}
// return false for failure
public function decrypt($data)
{
return self::aes256_cbc_decrypt(base64_decode($data), $this->app_cc_aes_key, $this->app_cc_aes_iv);
}
// this for AES-256
private function check_key_and_iv_len($key, $iv)
{
if(32 !== strlen($key)) {
return false;
}
if(16 !== strlen($iv)) {
return false;
}
return true;
}
private function aes256_cbc_encrypt($data, $key, $iv)
{
if(!self::check_key_and_iv_len($key, $iv)) {
return false;
}
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
}
private function aes256_cbc_decrypt($data, $key, $iv)
{
if(!self::check_key_and_iv_len($key, $iv)) {
return false;
}
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
$padding = ord($data[strlen($data) - 1]);
return substr($data, 0, -$padding);
}
}
其中也有 PKCS7、PKCS5 等補零的問題
記得和前端工程師說定就好了!
iOS、android 的部份很容易就能在 Google 上找到範到了
https://www.google.com.tw/search?newwindow=1&safe=off&q=php+aes+ios+android&oq=php+aes+ios+android
用POST的話,HTTPS會連同內容一起加密吧,對於不同SSL憑證,安全性是相同的;PKI體系的用意在於驗證身分,所以公用WIFI下面也是可以確保安全性的(雖然我都連VPN回家裡)。
不過這實作非常好,多一分保障就少一分危險
請教各位大大,我用esp8266做了一個wifi家電控制,但它是純html,沒PHP,要如何做AES-128的加解密,然後我是用android手機的wifi來發出命令,要如何做加密嗎?是在手機app端做加密,然後esp8266做解密嗎?具體作法,是還需要買什麼硬體嗎,還是純軟體就可以做, .NET新手, 還請各位大神 賜教! 感謝觀看.
不一定使用 PHP 才能做 AES, .NET 也可以哦!
> 是在手機app端做加密,然後esp8266做解密嗎?
是的!
> 是還需要買什麼硬體嗎,還是純軟體就可以做
不需要另外添購硬體哦,純軟體程式就可以完成了!
非常實用,剛好工作需要用到。非常感謝!!