在PHP中加密和解密數據會是一對不錯的常用函數嗎?普通人的PHP加密?
假設:
- 你必須充當不會改變
- 你有敏感數據的字符串進行加密的密鑰字符串
- 加密功能應該只接受密鑰和明文數據
- 解密函數應該只接受密鑰和加密數據
- PHP 5.5可用
- 個你可以安全地假設被安裝只有PHP模塊可用於
當有人說:「我只想加密一些數據」,你要告訴他們做他們的研究和理解這種決定的後果在實施之前,但他們有一個截止日期,所以你必須提供一個片段:)
在PHP中加密和解密數據會是一對不錯的常用函數嗎?普通人的PHP加密?
假設:
當有人說:「我只想加密一些數據」,你要告訴他們做他們的研究和理解這種決定的後果在實施之前,但他們有一個截止日期,所以你必須提供一個片段:)
我已經使用成功通過Web URL這兩個自定義功能,如對一些敏感的信息..你可以採取alook,看參數,它是否符合你的需求:)
這很容易僅在後端,或者你什麼都喜歡使用,,
https://gist.github.com/mkdizajn/88a528f2a9ecee880c2e#file-php-encode_decode-helper-function-php
$key = 'your password for encryption';
function hideinfo($key, $string){ return rawurlencode(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))))); }
function showinfo($key, $string){ return rawurldecode(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(rawurldecode($string)), MCRYPT_MODE_CBC, md5(md5($key))), "\0")); }
我一直通荷蘭國際集團這個函數數組的東西,如:
的print_r(my_array(),真)並用各種字符編碼的和偉大工程也,,
心連心,K
下面就讓我們來對的功能(實際上,他們三個人),我只是寫了應滿足您的規格:
// Simple PHP encryption code by Ilmari Karonen, v1.0
// http://stackoverflow.com/a/30239440
// This code is released into the public domain; use it any way you want.
$enc_algo = 'rijndael-128'; // Rijndael-128/256 = AES-256
$key_len = 32; $iv_len = 16; // key and IV lengths for AES-256
$enc_mode = 'ctr'; // CTR and OFB modes don't need padding
$hash_algo = 'sha256'; // for HMAC; must output at least $key_len bytes
$nonce_len = 16; // length of random nonce; arbitrary, 16 bytes = 128 bits
function encrypt($key, $plaintext, $metadata = "") {
global $enc_algo, $enc_mode, $key_len, $iv_len, $hash_algo, $nonce_len;
// derive two subkeys from the original key
$mac_key = hash_hmac($hash_algo, 'mac', $key, true);
$enc_key = hash_hmac($hash_algo, 'enc', $key, true);
$enc_key = substr($enc_key, 0, $key_len);
// derive a "synthetic IV" from the nonce, plaintext and metadata
$temp = $nonce = ($nonce_len > 0 ? mcrypt_create_iv($nonce_len) : "");
$temp .= hash_hmac($hash_algo, $plaintext, $mac_key, true);
$temp .= hash_hmac($hash_algo, $metadata, $mac_key, true);
$mac = hash_hmac($hash_algo, $temp, $mac_key, true);
$siv = substr($mac, 0, $iv_len);
// encrypt the message
$enc = mcrypt_encrypt($enc_algo, $enc_key, $plaintext, $enc_mode, $siv);
return base64_encode($siv . $nonce . $enc);
}
function decrypt($key, $ciphertext, $metadata = "") {
global $enc_algo, $enc_mode, $key_len, $iv_len, $hash_algo, $nonce_len;
// derive two subkeys from the original key
$mac_key = hash_hmac($hash_algo, 'mac', $key, true);
$enc_key = hash_hmac($hash_algo, 'enc', $key, true);
$enc_key = substr($enc_key, 0, $key_len);
// unpack MAC, nonce and encrypted message from the ciphertext
$enc = base64_decode($ciphertext);
$siv = substr($enc, 0, $iv_len);
$nonce = substr($enc, $iv_len, $nonce_len);
$enc = substr($enc, $iv_len + $nonce_len);
// decrypt message
$plaintext = mcrypt_decrypt($enc_algo, $enc_key, $enc, $enc_mode, $siv);
// verify MAC, return null if message is invalid
$temp = $nonce;
$temp .= hash_hmac($hash_algo, $plaintext, $mac_key, true);
$temp .= hash_hmac($hash_algo, $metadata, $mac_key, true);
$mac = hash_hmac($hash_algo, $temp, $mac_key, true);
if($siv !== substr($mac, 0, $iv_len)) return null;
return $plaintext;
}
// extra function for password-based encryption
function password2key($password, $count = 100000, $salt = "") {
global $hash_algo;
return hash_pbkdf2($hash_algo, $password, $salt, $count, 0, true);
}
下面是一個簡單的測試用例/使用示例:
$key = password2key('password');
echo "key (in hex): "; var_dump(bin2hex($key));
$enc = encrypt($key, 'a quick brown fox jumps over the lazy dog');
echo "encrypted: "; var_dump($enc);
$dec = decrypt($key, $enc);
echo "decrypted: "; var_dump($dec);
# try to modify one bit of the encrypted message, see if decryption fails
$fake_enc = base64_decode($enc);
$fake_enc = substr($fake_enc, 0, -1) . (substr($fake_enc, -1)^"\001");
$fake_enc = base64_encode($fake_enc);
$dec = decrypt($key, $fake_enc);
echo "tampered message: "; var_dump($dec);
# decoding with wrong metadata should also fail
$dec = decrypt($key, $enc, 'wrong');
echo "wrong metadata: "; var_dump($dec);
上面的代碼實現了基於所述AES-256密碼在CTR mode 定製authenticated encryption模式,具有HMAC組合 - SHA-256進行消息驗證。它使用Mcrypt和Hash模塊,我相信這兩個模塊都應該是相當常用的。
的接口被故意保持儘可能簡單:
encrypt($key, $message)
使用給定的密鑰加密所述消息,並返回生成的Base64 -encoded密文。decrypt($key, $ciphertext)
使用相同的密鑰解密encrypt()
的輸出,並且如果消息驗證失敗(這可能意味着消息已被篡改,或者密鑰不正確),則返回明文消息或null
。兩個函數也可以採取可選$metadata
參數爲「相關聯的數據」,諸如發送/接收器ID或其他信息的標頭。簡而言之,如果傳遞給decrypt()
的元數據字符串與傳遞給encrypt()
的元數據字符串不匹配,則認爲該消息已被篡改(例如,攻擊者試圖修改頭文件),驗證將失敗。
底部的額外幫手函數password2key()
僅僅是Mcrypt實現PBKDF2時的一個薄包裝。如果「密鑰」不是高熵的隨機字符串,則應該致電password2key()
從中推導出實際加密密鑰。 $count
參數控制推導過程的慢度,應該儘可能高地設置; 100,000的默認值提供了略高於16位的價值extra resistance against brute force attacks。
我用的部件結合的具體方法是鬆散的基礎上SIV建設由Rogaway和施林普,但使用的,而不是他們的CMAC *算法HMAC。請注意,這是而不是一個經典的Encrypt-then-MAC方案,而是一個Encrypt-and-MAC之一;而E & M不具有與EtM相同的通用安全性證明,我相信這個實例化應該仍然是安全的,因爲HMAC與安全散列函數一起使用被稱爲隱私保護(即它不會泄露有關明文)。
這種類似SIV結構的優點是它減少了對nonce的依賴,從而減少了對系統RNG的依賴;即使nonce不總是唯一的,「合成IV」幾乎肯定是(除非明文也恰好相同)。因此,即使使用隨機數(即使是$nonce_len = 0
),該方案仍然只泄漏有關明文(基本上,它們的長度以及兩個明文是否相同)的最少信息。通過確保即使相同的明文以不同的方式進行加密,獨特的隨機數消除了第二次泄漏。
上述代碼還有其他一些方法可用於提高效率的魯棒性。例如,儘管它可能是可能是可以安全地將$key
直接提供給HMAC和AES,但我明確從它中派生出獨立的準獨立子鍵。這樣做的一個優點是,除了一點額外的信心,即不存在基於密鑰重用的不可預見的攻擊之外,輸入密鑰可以具有任意格式;它不必是一個隨機的32字節二進制字符串,就像原始AES密鑰所需要的那樣。
1)PHP這個Mcrypt接口doesn't seem to have a constant for CTR mode,但底層這個Mcrypt庫應該支持。如果您的電話沒有,出於某種原因,請嘗試將OFB模式設置爲$enc_mode = 'nofb';
。
2)上面給出的代碼只需要一個元數據字符串,但如果需要的話,將其直接修改爲幾個。
謝謝!我做了一些調整,並創建了https://gist.github.com/richjenks/1cfabb0ce1d089d0e78f –
有趣的是,看到用於創建IV的密鑰可能對安全性不太好,但實際上它是保持用法的一種好方法簡單。這是我第一次看到雙重哈希,並沒有被嚇到:) –
謝謝,我很高興你喜歡它,歡呼:) –