2015-05-14 55 views
2

在PHP中加密和解密數據會是一對不錯的常用函數嗎?普通人的PHP加密?

假設:

  • 你必須充當不會改變
  • 你有敏感數據的字符串進行加密的密鑰字符串
  • 加密功能應該只接受密鑰和明文數據
  • 解密函數應該只接受密鑰和加密數據
  • PHP 5.5可用
  • 個你可以安全地假設被安裝只有PHP模塊可用於

當有人說:「我只想加密一些數據」,你要告訴他們做他們的研究和理解這種決定的後果在實施之前,但他們有一個截止日期,所以你必須提供一個片段:)

回答

2

我已經使用成功通過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

+0

謝謝!我做了一些調整,並創建了https://gist.github.com/richjenks/1cfabb0ce1d089d0e78f –

+0

有趣的是,看到用於創建IV的密鑰可能對安全性不太好,但實際上它是保持用法的一種好方法簡單。這是我第一次看到雙重哈希,並沒有被嚇到:) –

+0

謝謝,我很高興你喜歡它,歡呼:) –

1

下面就讓我們來對的功能(實際上,他們三個人),我只是寫了應滿足您的規格:

// 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進行消息驗證。它使用McryptHash模塊,我相信這兩個模塊都應該是相當常用的。

的接口被故意保持儘可能簡單:

  • 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)上面給出的代碼只需要一個元數據字符串,但如果需要的話,將其直接修改爲幾個。