日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
如何正確區(qū)分并使用加密與認證技術?

在密碼學專家之中,“加密并不是認證”是一個簡單的共識。但很多不了解密碼學的開發(fā)者,并不知道這句話的意義。如果這個知識更廣為人知和深入理解,那么將會避免很多的設計錯誤。

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設,伊犁企業(yè)網(wǎng)站建設,伊犁品牌網(wǎng)站建設,網(wǎng)站定制,伊犁網(wǎng)站建設報價,網(wǎng)絡營銷,網(wǎng)絡優(yōu)化,伊犁網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

這一概念本身并不困難,但在表面之下,還有更多豐富的細節(jié)和玄妙之處有待發(fā)現(xiàn)。本文就是講述開發(fā)者對于加密和認證二者的混淆與誤用,并附上了優(yōu)秀的解決方案。

0x01 加密與認證之間有哪些區(qū)別?

加密是呈現(xiàn)信息,使其在沒有正確的密鑰情況下,變得難以卒讀的過程。在簡單的對稱加密中,同一個密鑰被用于加密和解密。在非對稱加密中,可以使用用戶的公鑰對信息加密,使得只有對應私鑰的擁有者才能讀取它。

認證是呈現(xiàn)信息,使其抗篡改(通常在某一非常低的概率之內(nèi),小于1除以已知宇宙中粒子的數(shù)量),同時也證明它起源于預期發(fā)送者的過程。

注意:當本文提及真實性時,是專門指的信息真實性,而不是身份真實性。這是一個PKI和密鑰管理問題,我們可能在未來的博客中詳細說明。

就CIA triad而言:加密提供機密性,認證提供完整性。

加密不提供完整性;被篡改的信息(通常)還能解密,但結果通常會是垃圾。單獨加密也不抑制惡意第三方發(fā)送加密信息。

認證不提供機密性;可以為明文信息提供抗篡改。

在程序員中,常見的錯誤是混淆這兩個概念。你能很容易找到這樣的一個庫或者框架:加密cookie數(shù)據(jù),然后在僅僅解密它之后就無條件地信任與使用之。

0x02 加密

我們之前定義了加密,并且詳細說明了它是提供機密性,但不提供完整性和真實性的。你可以篡改加密信息,并將產(chǎn)生的垃圾給予接收者。而且你甚至可以利用這種垃圾產(chǎn)生機制,來繞過安全控制。

考慮在加密cookie的情況下,有如下代碼:

 
 
  1. function setUnsafeCookie($name, $cookieData, $key)
  2. {
  3.     $iv = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
  4.     return setcookie(
  5.         $name, 
  6.         base64_encode(
  7.             $iv.
  8.             mcrypt_encrypt(
  9.                 MCRYPT_RIJNDAEL_128,
  10.                 $key,
  11.                 json_encode($cookieData),
  12.                 MCRYPT_MODE_CBC,
  13.                 $iv
  14.             )
  15.         )
  16.     );
  17. }
  18. function getUnsafeCookie($name, $key)
  19. {
  20.     if (!isset($_COOKIE[$name])) {
  21.         return null;
  22.     }
  23.     $decoded = base64_decode($_COOKIE[$name]);
  24.     $iv = mb_substr($decoded, 0, 16, '8bit');
  25.     $ciphertext = mb_substr($decoded, 16, null, '8bit');
  26.  
  27.     $decrypted = rtrim(
  28.         mcrypt_decrypt(
  29.             MCRYPT_RIJNDAEL_128,
  30.             $key,
  31.             $ciphertext,
  32.             MCRYPT_MODE_CBC,
  33.             $iv
  34.         ),
  35.         "\0"
  36.     );
  37.  
  38.     return json_decode($decrypted, true);
  39. }

上面的代碼提供了在密碼段鏈接模塊的AES加密,如果你傳入32字節(jié)的字符串作為$key,你甚至可以聲稱,為你的cookie提供了256位的AES加密,然后人們可能被誤導相信它是安全的。

0x03 如何攻擊未經(jīng)認證的加密

比方說,在登錄到這個應用程序之后,你會發(fā)現(xiàn)你收到一個會話cookie,看起來就像

kHv9PAlStPZaZJHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==

讓我們改變一個字節(jié)的第一塊(初始化向量),并反復發(fā)送我們的新的cookie,直到出現(xiàn)一些變化。應該采取共4096次HTTP請求,以嘗試變量IV所有可能的單字節(jié)變化。在上面的例子中,經(jīng)過2405次請求后,我們得到一個看起來像這樣的字符串:

kHv9PAlStPZaZZHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==

相比之下,在base64編碼的cookie中只有一個字符不同(kHv9PAlStPZaZ J vs kHv9PAlStPZaZ Z):

- kHv9PAlStPZaZJHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==

+ kHv9PAlStPZaZZHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==

我們存儲在這個cookie里的原始數(shù)據(jù),是看起來像這樣的數(shù)組:

 
 
  1. array(2) {
  2.   ["admin"]=>
  3.   int(0)
  4.   ["user"]=>
  5.   "aaaaaaaaaaaaa"
  6.  }

但在僅僅改變初始化向量的一個字節(jié)之后,我們就能夠改寫我們的閱讀信息:

 
 
  1. array(2) {
  2.   ["admin"]=>
  3.   int(1)
  4.   ["user"]=>
  5.   "aaaaaaaaaaaaa"
  6. }

根據(jù)底層應用程序的設置方法,你或許可以翻轉一位進而提升成為一名管理員。即使你的cookie是加密的。 如果你想再現(xiàn)我們的結果,我們的加密密鑰是十六進制下的:000102030405060708090a0b0c0d0e0f

#p#

0x04 認證

如上所述,認證旨在提供信息的完整性(我們指顯著抗篡改能力),而這證明它來自預期的源(真實性)。這樣做的典型方法是,為信息計算一個密鑰散列消息認證碼(HMAC的簡稱),并將信息與它連結。

 
 
  1. function hmac_sign($message, $key)
  2. {
  3.     return hash_hmac('sha256', $message, $key) . $message;
  4. }
  5. function hmac_verify($bundle, $key)
  6. {
  7.     $msgMAC = mb_substr($bundle, 0, 64, '8bit');
  8.     $message = mb_substr($bundle, 64, null, '8bit');
  9.     return hash_equals(
  10.         hash_hmac('sha256', $message, $key),
  11.         $msgMAC
  12.     );
  13. }

重要的是,這里使用一個適當?shù)墓9ぞ?,如HMAC,而不僅僅是一個簡單的散列函數(shù)。

 
 
  1. function unsafe_hash_sign($message, $key)
  2. {
  3.     return md5($key.$message) . $message;
  4. }
  5. function unsafe_hash_verify($bundle, $key)
  6. {
  7.     $msgHash = mb_substr($bundle, 0, 64, '8bit');
  8.     $message = mb_substr($bundle, 64, null, '8bit');
  9.     return md5($key.$message) == $msgHash;
  10. }

我在這兩個函數(shù)名前面加了unsafe,是因為它們還是易受到一些缺點的危害:

Timing Attacks

Chosen Prefix Attacks on MD5 (PDF)

Non-strict equality operator bugs (largely specific to PHP)

現(xiàn)在,我們有點接近我們強大的對稱加密認證的目標。目前仍有幾個問題,如:

如果我們的原始信息以空字節(jié)結尾會發(fā)生什么?

有沒有一個比mcrypt擴展庫默認使用的更好的填充策略?

由于使用AES,有哪些通信方面是易受攻擊的?

幸運的是,這些問題在現(xiàn)有的加密函數(shù)庫中已有了解答。我們強烈推薦你使用現(xiàn)有的庫,而不是寫自己的加密功能。對于PHP開發(fā)人員來說,你應該使用defuse/php-encryption(或者libsodium)。

0x05 用Libsodium安全加密Cookies

 
 
  1. /*
  2. // At some point, we run this command:
  3. $key = Sodium::randombytes_buf(Sodium::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES);
  4. */
  5.  
  6. /**
  7.  * Store ciphertext in a cookie
  8.  * 
  9.  * @param string $name - cookie name
  10.  * @param mixed $cookieData - cookie data
  11.  * @param string $key - crypto key
  12.  */
  13. function setSafeCookie($name, $cookieData, $key)
  14. {
  15.     $nonce = Sodium::randombytes_buf(Sodium::CRYPTO_SECRETBOX_NONCEBYTES);
  16.  
  17.     return setcookie(
  18.         $name,
  19.         base64_encode(
  20.             $nonce.
  21.             Sodium::crypto_secretbox(
  22.                 json_encode($cookieData),
  23.                 $nonce,
  24.                 $key
  25.             )
  26.         )
  27.     );
  28. }
  29.  
  30. /**
  31.  * Decrypt a cookie, expand to array
  32.  * 
  33.  * @param string $name - cookie name
  34.  * @param string $key - crypto key
  35.  */
  36. function getSafeCookie($name, $key)
  37. {
  38.     $hexSize = 2 * Sodium::Sodium::CRYPTO_SECRETBOX_NONCEBYTES;
  39.     if (!isset($_COOKIE[$name])) {
  40.         return array();
  41.     }
  42.  
  43.     $decoded = base64_decode($_COOKIE[$name]);
  44.     $nonce = mb_substr($decoded, 0, $hexSize, '8bit');
  45.     $ciphertext = mb_substr($decoded, $hexSize, null, '8bit');
  46.  
  47.     $decrypted = Sodium::crypto_secretbox_open(
  48.         $ciphertext,
  49.         $nonce,
  50.         $key
  51.     );
  52.     if (empty($decrypted)) {
  53.         return array();
  54.     }
  55.  
  56.     return json_decode($decrypted, true);
  57. }

對于沒有l(wèi)ibsodium庫的開發(fā)人員,我們的一個博客讀者,提供了一個安全cookie實現(xiàn)的例子,其使用了defuse/php-encryption(我們推薦的PHP庫)。

0x06 使用關聯(lián)數(shù)據(jù)的認證加密

在我們前面的示例中,我們集中精力于,同時使用加密和認證,使其作為必須小心使用的單獨組件,以避免加密的悲劇。具體而言,我們專注于密碼段鏈接模塊的AES加密。

然而,密碼學家已經(jīng)開發(fā)出更新,更具有彈性的加密模型,其加密和認證信息在同一操作。這些模型被稱為AEAD模型(Authenticated Encryption with Associated Data)。關聯(lián)數(shù)據(jù)意味著,無論你的應用程序需要什么進行認證,都不加密。

AEAD模型通常用于有狀態(tài)的目的,如網(wǎng)絡通信中,其中一個隨機數(shù)可以很容易地管理。

AEAD兩個可靠的實現(xiàn)是AES-GCM和ChaCha20-Poly1305。

AES-GCM是Galois/Counter模式中的高級加密標準(又名Rijndael算法加密)。這種模式在OpenSSL的最新版本中加入,但它目前在PHP中還不被支持。

ChaCha20-Poly1305結合了ChaCha20流密碼與Poly1305消息認證碼。這種模式在libsodium PHP擴展可用。Sodium::crypto_aead_chacha20poly1305_encrypt() Sodium::crypto_aead_chacha20poly1305_decrypt()

總結一下,你該記住的

加密不是認證

加密提供機密性

認證提供完整性

將兩者混為一談你就得自擔風險

為了完成CIA triad,你需要單獨解決可用性。這通常不是一個加密問題。

更重要的是:在密碼學專家的監(jiān)督下,使用具有韌性被證實記錄的庫,而不是自己在那里閉門造車,你會好得多。

原文:https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly


本文標題:如何正確區(qū)分并使用加密與認證技術?
文章來源:http://www.dlmjj.cn/article/dpehocc.html