base64加密的圖片
大家好,我是阿薩。昨天和開發同學一起開會的時候。開發同學說到了用Base64編碼,我立即說 不能使用Base64加密。然後開發來了一句Base64不是加密演算法。當時懵了。默默記下這個知識點,回來學習下。
先給大家講解下我為什麼會有不能使用Base64加密的意識。很多年前,我遇到的第一個安全問題,就是敏感數據用Base64加密了。 事情起因是,我們接到一個bug,說有個敏感欄位使用Base64在前端加密了,然後傳給後端了。
基於之前的小故事,對於使用了Base64編碼的地方就覺得不安全。這也是為什麼會對開發說不能用Base64加密了,
今天我們就來學習下Base64編碼。
一,Base64編碼的由來。
傳說,最開始互聯網電子郵件都是英文的,後來互聯網傳到中國後,互聯網電子郵件漢字就不認識了。所以就有了Base64編碼,把中文變成可識別的英文。然後Base64編碼被廣泛用到各行各業。
以上只是傳說。真實的由來,就不得而知了。
下面我們從計算機的底層傳輸過程中。它分為可見字元和不可見字元。可見字元比如我們熟知的ASCII碼。
還有一些不可見的控制字元(0~31以及127),比如回車,換行等以及一些二進制數據都是不可見字元。
這些不可見字元在一些硬體,比如交換機,路由器以及網關等識別或者解析錯誤,導致錯誤發生,所以就有了Base64編碼的市場。因此Base64產生了。
二,Base64 編碼的原理
Base64編碼就是要把不可見的字元轉換成常見的64個字元的過程。
這64個字元是哪些呢?
那麼它工作原理是啥呢?
1) 首先把整段傳輸內容全部劃分成三個位元組一組。這里就有了24bit了.
2) 然後把24bit 分成四組。每一組就有6bit
3)在6bit的最前面添加2個0,這樣就有了8bit
4)把這8bit 轉換成一個位元組。查找上表中對應字元。所有其他分組內容按照這樣的處理邏輯處理下。就得到了Base64的編碼後字元。
注意,如果不夠三位元組,用0填到三位元組,同時補充了多少個位元組的0,末尾就添加就幾個=。
分別圖示下以上過程:
三個A
2個A,補充一個0
1個A,補充2個0
三,總結
Base64編碼不是用來加密的,也不是加密演算法。它只是用來編碼的。切記不可用於加密。如果敏感信息用Base64編碼加密了,趕緊提bug。
經過今天的學習,希望大家有所收獲。
如果你喜歡今天的內容,歡迎點贊,關注。
② 01加密方式-Base64編碼
說明
HTTP將Base64編碼用於基本的認證和摘要認證。
其可以方便的將用戶的任何輸入轉換成只包含特定字元的安全格式,服務於網路通信過程。
特點
1)可以將任意的二進制數據進行Base64編碼。
2)所有的數據都能被編碼為並只用65個字元就能表示的文本文件。
3)編碼後的65個字元包括A Z,a z,0~9,+,/,=
4)對文件或字元串進行Base64編碼後將比 原始大小增加33% 。
5)能夠逆運算
6)不夠安全,但卻被很多加密演算法作為編碼方式
1)將所有字元轉化為ASCII碼;
2)將ASCII碼轉化為8位二進制;
3)將二進制3個歸成一組(不足3個在後邊補0)共24位,再拆分成4組,每組6位;
4)統一在6位二進制前補兩個0湊足8位;
5)將補0後的二進制轉為十進制;
6)從Base64編碼表獲取十進制對應的Base64編碼;
a.轉換的時候,將三個byte的數據,先後放入一個24bit的緩沖區中,先來的byte占高位。
b.數據不足3byte的話,則剩下的bit用0補足。每次取出6個bit,按照其值選擇查表選擇對應的字元作為編碼後的輸出。
c.不斷進行,直到全部輸入數據轉換完成。
d.如果最後剩下兩個輸入數據,在編碼結果後加1個「=」;
e.如果最後剩下一個輸入數據,編碼結果後加2個「=」;
f.如果沒有剩下任何數據,就什麼都不要加,這樣才可以保證資料還原的正確性。
運行效果圖
③ 偽加密演算法:Base64
做過網路通信的iOSer對Base64都不會很陌生,涉及加密的數據通常會在傳輸之前做一次Base64轉換,一般形式如下 Base64(DES/AES(Data)) ,所以有些iOSer就把Base64當作加密演算法的一種,甚至一些在線工具也直接稱呼Base64為加密/解密,實際上這誤會可大了,本篇回答以下三個問題:
要回答第一個問題,首先來看看Base64的編碼過程,這里以字元串 「1234」 為例,經過Base64編碼後,結果為 "MTIzNA==" ,也是一個字元串,過程如下:
看到這里,你會疑問,這樣的編碼有什麼用?
Base64真正的作用不是將字元串轉換為另一個字元串,而是將任意二進制轉換為字元串,這個字元串的范圍還很小,只有64個,這就為那些只能傳輸字元串的協議傳輸數據帶來方便,比如http,通過一些字元的替換,還可以避免特殊字元的沖突。
蘋果已經提供了原生的API,用Swift做Base64編碼:
NSData.Base64EncodingOptions 有四個可選值:
可以組合使用:
編碼結果按76個字元換行,換行符為\r。
解碼方法如下:
思考題:
編碼過程中,6位補8位的規則是什麼,是高位補0還是低位,為什麼?經過深入思考的結果才是自己的哦,歡迎你的留言👏
④ base64加密比原來的數據長度增加多少
首先Base64不是一種加密方式,只是一種編碼。。然後長度呢,就是原來長度 * (4 / 3),不計最後一個或兩個等於號的話。
⑤ 詳述圖片base64加密的原理,告訴你什麼是"/9j/"
在日常的生活中,我們肯定都經歷過類似這樣的場景:報名考試上傳圖片,網站要求的是上傳的照片不能大於多少,而且要求是「.jpg」的格式。
於是你高高興興地把自己最漂亮的照片上傳上去了,但是網站卻提示你照片格式不正確,讓你重新上傳。這個時候內心不知道有多少疑惑湧上心頭(其實是奔騰)我的照片明明就是「.jpg」結尾的,而且大小也符合規范,為啥就不行呢?
我們通常的會認為(Windows電腦情況下,Mac不知道,畢竟我沒有圖片)「.jpg」圖片結尾的就一定是符合規范的「JPG」文件類型。其實一開始我也是這樣認為的,直到前幾天,我在對接項目的時候踩了一個大坑,很大的坑!
我對接的項目要求的是圖片是「JPG」類型的文件,並且經過base64進行編碼之後要以"/9j"開頭的文件。於是我就把我電腦上保存的看似符合規范的圖片上傳上去了,結果就是一堆報錯信息。於是我再次嘗試,換一些其他的圖片進行測試,發現有的就好使,有的就不好使。說實話,我的內心崩潰了!那種感覺你懂得圖片
回到家之後我思來想去就是不知道為什麼要求什麼"/9j"開頭的?我打開了網路,輸入了關鍵詞「/9j」之後,呵呵!我笑了,都是些什麼?完全跟我的問題不著邊!
什麼玩意?這到底是什麼玩意?竟然連強大的網路都沒有給出結果!就這樣,我搜索到了凌晨12點......
扛不住了,我就去睡覺了。但是躺在床上我輾轉難眠,打開手機繼續各種搜索著......突然!我看了一個關於電腦圖片文件頭信息解析的文章!一道靈光從我腦門上閃過。於是我起床,默默打開了電腦,打開了網路......
原來電腦在存儲的時候是存儲了圖片的基本信息的,比如圖片是什麼類型的,圖片的寬高等基本信息,這些個基本信息叫做圖片頭信息。好吧!原諒我的無知,曾經的我天真的以為是按照文件後綴名區分的呢。
我們應知道,圖片在計算機中存儲是一個一個的像素點,最底層也是二進制文件,所以需要文件頭來保存文件信息。經查找資料,我找到如下對圖片不同格式的文件頭標識信息(16進制標識):
於是我在電腦上保存了一個為「.jpg」後綴結尾的圖片,然後使用UE這個強大的工具打開,果然不出我所料,看看這個文件的內容信息。
不出意外的話,你肯定看不懂這些東西,因為這些是16進制文件。但是重要的我已經給你標注出來了,那就是「FF D8」。
在這里我給大家稍微簡單科普下base64的編碼規則:假如我們有個「hello」這樣的關鍵字進行base64編碼,需要先把「hello」轉換成二進制,也就是"110100011001011101100110 11001101111"。我這里給了一個ASCII表,這里對應的是10進制的,需要把十進制轉化成2進制的。
關於base64 有個規定就是,一個字元轉換之後如果位數不為8位,需要在高位補0,然後再6位截取,最後不夠6位的,低位補0。然後把分割後的2進制轉換成10進制並對照base64編碼表進行解析。那麼上述的「hello」的解析過程就如下:
所以「hello」base64編碼之後的最終結果就是「aGVsbG8=」。也許你會疑惑,為什麼多了個「=」 這個其實是base64的規定,編碼完畢之後自動添加一個或兩個「=」。
那麼再回到「FF D8」,jpg文件的標識頭,他經過base64轉碼之後是什麼呢?
謝天謝地,可算搞明白為什麼是「/9j」開頭的了。其實還有另外一種方式快速查看是不是jpg格式文件。我們可以使用記事本的方式打開一個jpg文件。
打開之後,你肯定還是看不懂這些東西,但是重要的我已經給你標注出來了,那就是「JFIF」,這個是一個很重要的標識,所謂的「JFIF」就是"JPEG File Interchonge Format"即JPEG文件交換格式。
為了還原我之前明明是「.jpg」後綴的文件,但是識別失敗的問題。我們把一個格式為「.png」圖片,通過改後綴名的方式,改成「.jpg」。然後也用記事本打開查看文件的內容。
可以看到,並不是「JFIF」,因此這並不是一個jpg文件,所以上傳無法識別。
帶著問題去睡覺,果然是睡不著的!通過這次的經歷,我知道了base64的編碼原理,明白了文件在電腦中存儲並不是靠簡簡單單的後綴名來區分的,而是有文件頭信息的。文件到底是一個什麼文件,還是要靠文件頭信息來決定的。所以,你以後的程序判斷文件類型千萬不要僅僅判斷後綴名就完事了哦!