php對稱加密和解密的實(shí)現(xiàn)詳解
為什么我們要加密
加密是為了信息傳遞更加安全!
這樣才能更好的讓信息傳遞更具有保密性,不會被他人隨意篡改、也能夠讓信息真實(shí)有效的到達(dá)指定對象的手里!
我們加密的目的,多數(shù)是圍繞這上面這些情況來的!
舉個栗子
在信息通信過程當(dāng)中,比如你發(fā)送一條重要信息給對方, 在這個過程中其實(shí)有很多人可以利用一些技術(shù)手段接觸到這一段信息! 如果是很重要的信息但個別人利用,說不一定就會產(chǎn)生嚴(yán)重的經(jīng)濟(jì)損失!
例如: 信息中包含了一些敏感信息,如身份證、銀行卡、密碼、而這些敏感信息是最容易被人偷窺的!
如圖
為了避免出現(xiàn)以上的情況,我們就要將信息進(jìn)行加密處理, 這樣子即便是被人拿到了關(guān)鍵信息,他也是在短時間內(nèi)無法查看的,也就是讓任何第三方都無法直接讀取和讀懂的信息!
只有發(fā)送方和接收方能看懂整個數(shù)據(jù)傳輸?shù)男畔ⅰ?/p>
加密系統(tǒng)的簡單架構(gòu)
加密的產(chǎn)生過程,簡單點(diǎn)說其實(shí)就是: 明文+密鑰+算法=密文
如圖
從上面的圖來看,其實(shí)明文和算法都還是比較好理解,但其中有一個叫密鑰的東西,它就好比是像彼此約定好了的暗號一樣, 也是最簡單的加密方式!
舉個栗子
從生活中我們用一個鎖家里的門來舉例的話,就是家中有價值的物品,就是你的明文、那么密鑰就是你的鑰匙,那么算法就是你是通過什么樣的情況來鎖門的! 當(dāng)門鎖好之后,那么一個家就形成了一個加密狀態(tài)了!
所以這個密鑰通常都是需要保密的,就是這個意思,你總不可能把你的鑰匙隨便丟吧!
對稱加密
那么在計(jì)算機(jī)中,我們也一些有比較安全和常見的加密方式, 例如:對稱加密
對稱加密其實(shí)分為兩種形式: 對稱加密和非對稱加密
簡單的說對稱加密也就是加密和解密都會使用同樣密鑰
非對稱加密則恰恰相反,這種加密和解密使用的是不同密鑰
AES對稱加密算法
AES
全稱:advanced encryption standard
它是密碼學(xué)中的高級加密標(biāo)準(zhǔn)
,也是美國聯(lián)邦政府采用的區(qū)塊加密的標(biāo)準(zhǔn),也是當(dāng)下比較流行的對稱密碼算法
!
我們前面提到的對稱加密中就包含了AES 也就是加密和解密都會使用同樣密鑰的加密算法
簡單的說發(fā)送方將明文和密鑰一起經(jīng)過特殊加密算法處理后,使其變成復(fù)雜的加密密文再發(fā)送出去!
接收方如果想解讀明文, 那么需要使用加密用過的密鑰及相同算法然后按照與加密時相反的順序逆推算法對密文進(jìn)行解密,才能使其恢復(fù)成可讀的明文信息!
前面說了,在對稱AES加密算法中,使用的密鑰只有一個, 發(fā)送方和接收方都使用這個密鑰對數(shù)據(jù)進(jìn)行加密和解密,那么這就要求解密的一方事先必須知道加密密鑰對吧!
如圖
這就像是它要求發(fā)送方和接收方在通信之前,約定一個密鑰(暗號)
對稱算法的安全性依賴于密鑰,如果泄漏密鑰就意味著任何人都可以對他們發(fā)送或接收的數(shù)據(jù)進(jìn)行解密
所以密鑰的保密性對AES通信的安全性至關(guān)重要!
對稱加密算法的優(yōu)點(diǎn)在于加密和解密的快速和使用長密鑰時的難破解性,而這種加密算法支持長度為 128比特的密鑰長度, 同時也支持192、256比特一共三種選擇!
我們知道加密的核心在于密鑰而算法本身其實(shí)最終都會被破解的,所以現(xiàn)在流行的密碼算法都是公開的,所以從密碼學(xué)的角度而言也沒有人去保密算法來提高安全性,所以說對于現(xiàn)在某些密碼攻擊手段對于一些高級加密標(biāo)準(zhǔn)算法本身并沒有效果,真正核心的還是密鑰, 這里密鑰的長度直接就會影響到蠻力攻擊要取得成功需要耗費(fèi)相當(dāng)長的時間,而這種對稱加密算法的安全性取決于密鑰的保存情況來決定!
所以普通情況下,沒有特殊需求,基本上首先的是AES加密
應(yīng)用場景
這里我簡單說一個案例
假設(shè)我們現(xiàn)在有一個包含用戶個人信息的JSON對象
,需要進(jìn)行加密處理
如下
{ "name": "張三", "age": 30, "email": "zhangsan@example.com", "phone": "13812345678" }
那么此時我們可以使用一些加密算法,比如:AES、RSA
對這個JSON對象
中的一些數(shù)據(jù)進(jìn)行加密處理。
然后加密之后的數(shù)據(jù)會變成一串密文,用戶是無法直接閱讀和理解。
例如:使用AES算法
加密上述JSON對象
,結(jié)果可能類似于以下形式:
{ "name": "張三", "age": 30, "email": "zhangsan@example.com", "phone": "tv/yxsWlDIPHOnD50WVnFw==" }
現(xiàn)在可以看到,加密后的JSON對象
中的phone
電話字段已經(jīng)被替換為一串看似隨機(jī)的字符串,我們是無法直接讀取原始的手機(jī)號
的, 這樣也對整個JSON對象
也變得難以理解和解析。
這里加密后的JSON數(shù)據(jù)需要解密后才能還原為原始數(shù)據(jù),而解密過程與加密相反,
需要使用相應(yīng)的解密算法和密鑰來還原數(shù)據(jù)。
PHP實(shí)現(xiàn)AES對稱加密
我們來實(shí)現(xiàn)一個簡單的加密案例,有興趣的朋友可以來看看,java、php、python
等等用什么語言都可以!
我用php
中的OpenSSl擴(kuò)展庫
來實(shí)現(xiàn)AES對稱加密與解密
不用我們?nèi)チ私獾讓樱恍枰p松幾步就可以實(shí)現(xiàn)一個簡單加密和解密
數(shù)據(jù)的過程!
代碼如下
<?php function encryptAES($data, $key, $iv) { $encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); $encrypted = base64_encode($encrypted); return $encrypted; } function decryptAES($encryptedData, $key, $iv) { $encryptedData = base64_decode($encryptedData); $decrypted = openssl_decrypt($encryptedData, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); return $decrypted; } // 加密數(shù)據(jù) $data = 'Hello-World!'; $key = '0123456789abcdef'; $iv = '1234567890abcdef'; $encryptedData = encryptAES($data, $key, $iv); echo '加密后的數(shù)據(jù):' . $encryptedData; echo '<hr>'; // 解密數(shù)據(jù) $decryptedData = decryptAES($encryptedData, $key, $iv); echo '解密后的數(shù)據(jù):' . $decryptedData; ?>
效果如下
代碼分析
這里簡單的使用到了php
中OpenSSl擴(kuò)展庫
的openssl_encrypt
和openssl_decrypt
函數(shù)來實(shí)現(xiàn)的AES
openssl_encrypt函數(shù)解釋
如下表
參數(shù)列表 | 含義 |
---|---|
參數(shù)1:data | 待加密的明文信息數(shù)據(jù), 也就是需要加密的數(shù)據(jù),你可以把它想象成你想要鎖起來的秘密信息 |
參數(shù)2:method | 加密方式, 也就是你想要用來加密數(shù)據(jù)的加密算法, 常見的加密算法包括 AES, 具體可以查看官方文檔 例如: 你使用 AES-256-CBC 算法,那么 CBC 表示加密模式,256 表示密鑰的長度 |
參數(shù)3:key | 約定加密和解密的一把鑰匙, 而這把密鑰的長度必須與所選擇的加密算法相匹配.........例如,如果使用 AES-256-xxx,那么你的密鑰應(yīng)該是 256 位長! 所以我們最好要給定相應(yīng)字節(jié)長度的字符串密鑰,雖然有時候我們沒有定義指定長度的字符的密鑰,但仍然能夠成功加密數(shù)據(jù),是因?yàn)镻HP的OpenSSL擴(kuò)展自動處理了密鑰的填充和生成! 但是為了確保最佳的安全性,最好顯式地指定一個符合長度要求的密鑰! 這樣可以避免任何潛在的填充問題,并確保密鑰的長度與所選加密算法的要求相匹配, 比如說: 在 AES-256 算法中,密鑰的長度為 32 字節(jié)(256 位)的字符串就可以了! 這里我采用的是AES,而AES密鑰的長度通常可以是128位、192位、256位 |
參數(shù)4:options | 它可以控制如何處理返回的數(shù)據(jù), 它有兩種常量設(shè)置方式: OPENSSL_RAW_DATA和 OPENSSL_ZERO_PADDING 例如,你可以設(shè)置 OPENSSL_RAW_DATA 常量選項(xiàng),這樣函數(shù)會返回原始的二進(jìn)制數(shù)據(jù),一把也都設(shè)置這個! |
參數(shù)5:iv | 它是一個初始化向量, 用于增加加密的安全性和隨機(jī)性! 這里所謂的初始化向量其實(shí)就是一個隨機(jī)字符串,但是這個隨機(jī)字符串是有一定講究的,它的字符長度通常需要與加密模式的要求相匹配, 也就是說不同的加密模式可能會有不同的iv要求, 例如: 當(dāng)我們使用AES-256-CBC加密模式時,iv參數(shù)應(yīng)該至少為16字節(jié)長度的隨機(jī)字符串, 如果使用AES-128-CBC加密模式時, iv參數(shù)必須為16字節(jié)長度的隨機(jī)字符串,多一個或少一個都會報錯! 所以iv這個參數(shù),最好是要和加密模式中的長度一致就行了! 為了更加安全,這個iv最好不能寫死,用一種算法方式生成指定長度的iv 這樣子在每次加密操作時都會改變加密結(jié)果! |
.................................... |
返回值:成功時返回加密后的字符串
openssl_decrypt函數(shù)解釋
如下表
參數(shù)列表 | 描述 |
---|---|
參數(shù)1:data | 要解密的數(shù)據(jù)字符串,通常是由 openssl_encrypt 函數(shù)加密后的結(jié)果。 |
參數(shù)2:method | 填寫加密方式,既然要解密那么就要知道是如何加密的,所以這里就必須填寫與加密時使用的算法模式相同! 例如: 加密模式為 AES-256-CBC 那么這里就必須填寫AES-256-CBC |
參數(shù)3:key | 解密密鑰。這是用于解密的密鑰,與加密時使用的密鑰相同! 舉個生活上的案例,你用什么鑰匙鎖門,那么你就要用相應(yīng)的鑰匙來開門,對吧! 并且這個密鑰的長度也要一致! |
參數(shù)4:options | 數(shù)據(jù)以什么形式進(jìn)行處理并返回 它有兩種常量設(shè)置方式: OPENSSL_RAW_DATA和 OPENSSL_ZERO_PADDING , 加密時設(shè)置的什么,這里就設(shè)置什么! |
參數(shù)5:iv | 解密時需要使用加密時相同的 iv |
......................................... |
所以在上面的案例中encryptAES
函數(shù)接受要加密的數(shù)據(jù)、密鑰
和初始向量
,并返回加密后的結(jié)果。
而且decryptAES
函數(shù)接受加密后的數(shù)據(jù)、密鑰
和初始向量
,并返回解密后的原始數(shù)據(jù)。
特別注意的是密鑰
和初始向量
的長度,必須要符合加密算法的要求!
大致流程如下圖:
以上就是php對稱加密和解密的實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于php對稱加密解密的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
php站內(nèi)搜索并高亮顯示關(guān)鍵字的實(shí)現(xiàn)代碼
將sql語句中包含的%$info%交給DBMS執(zhí)行的時候,他會查找字段中含有變量$info的值的信息2011-12-12Smarty模板學(xué)習(xí)筆記之Smarty簡介
Smarty是一個使用PHP寫出來的模板PHP模板引擎,是目前業(yè)界最著名的PHP模板引擎之一。它分離了邏輯代碼和外在的內(nèi)容,提供了一種易于管理和使用的方法,用來將原本與HTML代碼混雜在一起PHP代碼邏輯分離。2014-05-05php啟用sphinx全文搜索的實(shí)現(xiàn)方法
這篇文章主要介紹了php啟用sphinx全文搜索的實(shí)現(xiàn)方法,詳細(xì)講述了sphinx相關(guān)的配置與使用技巧,具有一定的參考借鑒價值,需要的朋友可以參考下2014-12-12利用PHP實(shí)現(xiàn)一個MySQL備份和恢復(fù)程序
由于客戶用的阿里云將要到期,需要把項(xiàng)目和阿里云上的數(shù)據(jù)庫都轉(zhuǎn)到政府云,數(shù)據(jù)肯定要轉(zhuǎn)過去,但是阿里云導(dǎo)出數(shù)據(jù)有數(shù)量限制,導(dǎo)出不全,所以就要程序執(zhí)行下,生成sql文件,然后導(dǎo)入政府云數(shù)據(jù)庫,下面分享下具體實(shí)現(xiàn)過程2023-09-09PHP讀取XML文件的方法實(shí)例總結(jié)【DOMDocument及simplexml方法】
這篇文章主要介紹了PHP讀取XML文件的方法,結(jié)合實(shí)例形式總結(jié)分析了php基于DOMDocument及simplexml方法針對xml文件的載入、讀取等相關(guān)操作技巧,需要的朋友可以參考下2019-09-09php獲得客戶端瀏覽器名稱及版本的方法(基于ECShop函數(shù))
這篇文章主要介紹了php獲得客戶端瀏覽器名稱及版本的方法,基于ECShop函數(shù)get_user_browser實(shí)現(xiàn)該功能,非常具有實(shí)用價值,需要的朋友可以參考下2015-12-12