古代打仗的時候,會要信使騎個馬送信。他們經常會擔心信使被抓。
比較早的一種加密方式
一個布條纏在密碼棒上面,兩邊都有同一規格的密碼棒
也可以用碼錶
不止可以用於文字內容,還可以用於各種二進位制資料。
跟替換式加密很像
使用金鑰和加密演演算法對資料進行轉換,得到的無意義資料即為密文;使用金鑰和解密演演算法對密文進行逆向轉換,得到原資料。
原資料,用加密演演算法以及金鑰,把他改成了看不懂的密文,這個時候對方拿到密文,並且他有金鑰,我有金鑰,其他任何人都沒有。然後他就可以去解密,他使用解密演演算法配合上金鑰,他就能解密,得到原資料。其他任何人拿到這個資料是沒有用的。
這個對計算機很有用,為什麼?因為我們通訊的時候,我們的網路是完全不可信的。從我家到你家這一路上,可能有非常非常多的中間節點,他們想拿我們的中間的資料輕而易舉。為什麼?我們網路傳資料,比如說我給你發一條資訊,不是這個資訊在一條路上走,而是喊話式的,都是輻射式的。
他跟傳統的替換式加密有什麼不同呢?他可以加密二進位制檔案
DES(由於金鑰太短而被棄用了),AES
為什麼金鑰短就被棄用?因為金鑰短就可能會被破解。
什麼叫破解呢?什麼叫對稱加密的金鑰的破解呢?就是這樣的,我們通訊的破解,我們古代戰爭寫信,我知道你的密碼棒是什麼規格,我知道你的碼錶是什麼,當我拿到你加密後的那一封密文,我可以給你恢復回來。那麼我拿到你這個密文或碼錶,就破解了。他的關鍵是什麼呢?你能夠拿到一組原文和密文的對,然後你用你準備好的金鑰對這個密文解密之後,他真的恢復成原文了,這表示破解成功了。
同樣,有破解就有反破解。反破解的思路非常直,就是我讓你破解的方法更加複雜。最優秀的加密演演算法就是,他的金鑰的破解方式只能是窮舉法。你不可能讓別人破解不了,只是成本非常高,比如要一千年,一萬年才能破解,那麼我認為你這個東西不能破解。
使用公鑰對資料進行加密得到密文;使用私鑰對資料進行解密得到後設資料。
延伸用途:數位簽章
RSA(加密解密,簽名驗證都可以)、DSA(專門設計用來簽名的,簽名和驗證的過程特別快,有速度優勢,橢圓曲線全稱就叫ECDSA)
怎麼做到的呢?用的是數學知識。我可以簡單解釋一下,但是我的這個解釋是不足以完全說明非對稱加密的。因為非對稱加密最簡單的演演算法也比較複雜。RSA演演算法就算一種比較簡單的演演算法了,但是還是比較不好理解。所以我跟你舉一個簡單例子。這個例子可能會有漏洞,但是你要知道她是什麼意思。
比如,我們雙方通訊了,我們規定通訊內容只有十個,0-9,只能發這十個。比如我現在給你發一個訊息110,但是我如果被人截獲了那我就完蛋了。所以我要對她做一下轉換。然後我要怎麼轉?我的演演算法是什麼?我的加密金鑰和解密金鑰是什麼?這個時候就體現出來了他的用處了。我的加密演演算法是,對我的每一個字元都做一個加法。而這個加法具體加幾,就是我的金鑰了。那麼我規定,我的加密金鑰是4,我的解密金鑰是6,加密:110–>554,發出去。接下來, 我要解密,我的解密演演算法還是加,但是加的是6,554–>110,恢復了。
這個例子雖然有漏洞,但是她能解釋非對稱加密的原理。他是跟溢位有關的,如果不可以溢位的話,非對稱加密就沒法玩了。你各種溢位,刪掉他前面的點,這個是非對稱加密很關鍵的一個點。
現在,我假設我們路上有壞人,他們會看到我們的訊息。但是現在,我們可以做加密了。而且,我可以把金鑰,就這樣在網上扔給對方。這個扔本身,他也是危險的。對稱加密,不是挺安全的嗎?為什麼又要非對稱加密呢?有一個很重要的原因,就是你的金鑰怎麼給對方。他是一個難題。這可不是你要來我家,天天來我家,我給你配一把鑰匙,見面的時候我把鑰匙給你就可以了。不是這樣的,而是我要把鑰匙寄給你。如果你家的鑰匙真的那麼受人關注,並且快遞員他們都會拆開看一看的話,你敢把鑰匙寄給別人嗎?不敢吧。網上的這種通訊也是一樣。你們兩個通過對稱加密來做通訊是完全沒問題的。可是你怎麼把金鑰給對方呢?這個問題非常難解決。而且各種各樣的情形,有很多是,我們兩個臨時起意,想聊天了,加個好友吧。怎麼加?我跑你家把金鑰給你呀?是吧?這就是非對稱加密他很重要的一個好處了。我可以在網上直接把金鑰進行傳輸,沒有任何安全隱患。
看一下怎麼沒有安全隱患。首先,我把我的加密金鑰從a給到b,b也把她的加密金鑰從b給到a。首先我看a和b能不能通訊,比如a要給b發訊息,我用b的加密金鑰,去加密我的原資料。加密完以後就是密文了,b拿解密金鑰解密,就得到原資料。同樣,b給a發訊息也是這樣。
那我們假設c拿到這個密文他肯定看不懂,但是如果他不僅僅拿到密文,他還拿到了我們傳輸過程中傳送的這個兩個加密金鑰。現在他能看我們的密文嗎?還是不能看的。假如我說可以看,你想想,我怎麼看?我現在有一個密文,是a發給b的,他用b的加密金鑰加密了, 你說c拿哪個金鑰來解?都不行。非對稱加密很關鍵的一個點是,他加密和解密用的不是一個金鑰。所以這個時候你拿我的兩個加密金鑰是沒有用的。解密金鑰是要拿在手裡不能動的,這個是關鍵。一定要拿在手裡面,誰都不能給,不可能往外傳送的。而加密金鑰隨便往外公開。事實上你往外公開的這個加密金鑰他叫公鑰,解密金鑰叫私鑰。
首先有一個問題,私鑰是可以解公鑰的,那麼公鑰可不可以解私鑰呢?是可以的。
但是有一點要注意,公鑰和私鑰是不能反的。因為很多時候公鑰是可以被計算出來的,有一種非對稱加密演演算法叫橢圓曲線演演算法,他是位元幣用的一種演演算法。他的公鑰就是依靠私鑰算出來的,你拿到私鑰就相當於公鑰和私鑰同時拿在手裡。雖然他們在資料轉化上有對等關係,但是很多時候你的公鑰是可以被人算出來的,所以你公佈一個公鑰出去沒關係,本來就要公開,只要私鑰不公開你沒發推算出我的私鑰。
還有一種情況就是RSA,RSA他的公鑰甚至只有一個,你家公鑰是這個值,我家公鑰也是這個值,也不是公鑰完全是一個值,就是公鑰的一部分,公鑰最關鍵的那一部分是一樣的。好像是65537我記得。所以公鑰和私鑰是不能對換的。但是他們在加密上是完全一樣的。你可以解我,我可以解你。
由於有這麼一種特性,我就可以去做簽名和驗證了。
現在有一種比較常見的用法就是在網上進行數位簽章,進行電子簽名。就是我有一個我的金鑰。我對我的資料,比如說我聲稱我欠了小莊一百塊錢,我可以手寫,我也可以使用電子簽名式。他是怎麼簽名呢?就是使用我的某個金鑰,對我寫的文章進行加密演演算法轉化之後,別人拿到之後,再用另外的公鑰解密,一看,可以置換成原資料,就可以證明這個東西確實是我寫的。
另外,還會有這樣一步,你只拿著這個簽名資料很不方便,每次看都要用公鑰解密以後才能看到原資料。所以一般會把原資料和簽名資料一起傳送出來。這個時候你看原資料可以看,你要驗證這個資料可以用簽名資料還原。
將二進位制資料轉換成由64個字元組成的字串的編碼演演算法。(a-z、A-Z、0-9、+、/)
什麼是二進位制資料?非文字資料就是二進位制資料,廣義的,所有的計算機資料都是二進位制資料。因為電訊號只有1010,計算機資料只有兩個位,計算機資料都是二進位制資料,不管什麼文字檔案啊,電影啊,word檔案啊,圖片這些都是二進位制資料。而其中有一種比較特殊的叫做文字資料,就是純文字,比如字串,比如你的一個txt檔案裡面存的一些文字,這些叫文字資料或者叫字元資料。文字資料之外的,就是我們通常溝通的時候所說的二進位制資料,也就是狹義的二進位制資料。所以資料就分兩種,文字資料和二進位制資料。
base64的碼錶:
他是怎麼轉換的呢?他是將你的資料切一下。我們做資料的時候不是一個位元組有8位元嗎?一位是0或者1,只能二選一,八位是一個位元組,但是base64為了能讓你的資料變成字串,他就把你切成了6位放在一起。具體的轉化是這樣的,Man轉化成base64就是TWFu。
怎麼讓你的資料base轉化以後還不增大呢?
那就別用base64,用base256,但是為什麼base64被建立出來?就是因為那些常見字元沒有256個,如果真有256個那還需要什麼base64。base64的目的是什麼?他的目的就是把你的二進位制資料(狹義的)轉化成文字資料,給轉化成字串。
讓原資料具有字串所具有的特性,如可以放在URL中傳輸、可以儲存到文字檔案、可以通過普通聊天軟體進行文字傳輸。(把非字串轉成字串)
把原本人眼可以讀懂的字串變成讀不懂的字串,降低偷窺風險。
什麼時候會需要base64呢?舉一個比較早期的場景,就是郵箱剛被髮明,郵箱不能發圖片的。但是電腦可以存圖片,那麼我怎麼給你發圖片呢?好,我用base64轉一下,檔案變大了,沒關係啊,慢慢傳。然後再用base64的解碼演演算法給他解出來。那麼我們就通過文字的方式傳圖片。再舉一個例,假如我們兩個造了一個新的聊天軟體,但是咱倆技術有限,沒法支援圖片,傳不了圖片,怎麼辦?沒關係,把圖片轉成base64,然後我給你傳base64的文字資料,傳過去之後你再在本地解一下,解碼完就是那個圖片了。這個就是什麼呢?就是有的時候他有限制,不能這麼做,古老的郵箱就是這樣,沒這個功能,不能傳圖片,我又想傳圖片。好,我就用base64轉一下。
base64加密傳輸圖片,可以更安全和高效嗎?不是的。安全只能靠加密,base64不是加密;高效,base64轉化後資料變大了,變長了1/3,那還能高效嗎?你不管是儲存還是傳輸,還是讀取,他的速度都變慢了,而且還佔你頻寬,你可能本來傳這個東西,這個東西傳完以後,傳別的東西,可以更早傳完,但是由於你這東西被base64轉過一遍,完蛋了,你需要延長1/3的傳輸時間。base64絕對沒有什麼高效,相反他是低效的。能不base64一定不要base64,而且這個東西有毒,你每次做這個東西他都會變長。
base64有一個變種,base58,他去掉了0和大寫o,英文的大寫i和小寫l,另外還有兩個+和/。他用在位元幣或者其他虛擬幣的地址上面。這個地址有什麼特點呢?他可能會被手抄。去掉+和/是為了方便雙擊複製。
url地址的編碼是base64 的另一個變種
url的編碼也是base64的,但是他有一點點區別:
將url中的保留字元使用百分號「%」進行編碼
舉例:將保留字元中的&轉化成%26:
目的:消除歧義,避免錯誤
還有就是用於中文顯示
顯示是有中文的,但是複製下來就沒了
https://www.google.com/search?q=%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF%E7%AE%97%E6%B3%95&oq=%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF%E7%AE%97%E6%B3%95&aqs=chrome..69i57j0l2.7739j0j7&sourceid=chrome&ie=UTF-8
壓縮:把資料換一種方式儲存,以減小儲存空間
解壓縮:把壓縮後的資料還原成原先的形式,以便使用
常見的壓縮演演算法:DEFLATE(zip用的壓縮演演算法)、JPEG、MP3
壓縮屬於編碼嗎?
編碼到底是什麼?把a格式轉化成b格式,同時b格式是可以轉回來的,不會損失任何資訊,不會增加任何資訊。壓縮也是屬於編碼的一種。
下面一節舉例詳說
媒體資料是什麼?就是圖片啊、視訊、音訊這些東西,他們的編解碼是什麼呢?他們的編解碼就是把原先的資料轉化成可以儲存的一種編碼格式。比如對於圖片就是把影象資料編成檔案。
舉個栗子,影象怎麼做編碼呢?
比如我有一個圖片,這個圖片是64x64的,他是一個純白的圖片。那麼我怎麼寫,怎麼儲存呢?他在記憶體裡面可能是一個bitmap,當我要把他編碼出來,要儲存的時候,怎麼存?
ffffff表示一個白點
ffffffffffff…64x6個
ffffffffffff…64x6個
ffffffffffff…64x6個
…64行
這個就是編碼後的圖片,但是這樣好煩啊,這麼大。我們可以壓縮,在編碼的同時進行壓縮,怎麼壓縮呢?有各種各樣的壓縮方法。假如我們真的要做壓縮的話,DEFLATE演演算法以及各種其他演演算法他們本質上是什麼呢?
舉例:aaaaaaaaaaaaaaaaa…aaaaaaaaaaaaaaaaaaabbbbbbbb…bbbbbb
某種粗略壓縮後:text:a=100;b=20
上面的圖片也可以:image:64*64;ffffff=[0,0]-[63,63]
同樣音訊視訊的壓縮也是這樣的,上面只是舉例,這個壓縮並不嚴謹,優秀的壓縮演演算法永遠不會讓檔案變大,上面這種一旦種類變多,可能壓縮完後比檔案本體還大。
有失真壓縮和無失真壓縮:可以把她的畫素變小一點,也可以把顏色數改少一點,這樣壓完我的資料就會有損失。
我java記憶體裡面有一個資料,他有幾個屬性
這是在記憶體裡面,我需要把這些東西傳出來,一個是我們的網路上,另外也可能是我們的手機或者本地儲存,但是我們的記憶體裡面是亂亂的,我們怎麼存各種格式?我要把他拿出來,成線性的,可以通用解析的一個格式。這就是序列化。
像上面的我可以序列化出來成json格式。如果序列化出來,我可以選擇json格式,json只是序列化的一個選項,你可以序列化成json、xml…總之你只要把她轉化成可以儲存,可以傳輸,她是一個線性的就可以了。
序列化:把資料物件(一般是記憶體中的,如JVM中的物件)轉化成位元組序列的過程
反序列化:把位元組序列重新轉換成記憶體中的物件。
目的:就是跟外界通訊
序列化嚴格來說不屬於編碼,因為序列化他的原型在記憶體裡面,編碼是什麼a格式變b格式,編碼是已經成型的兩個東西他的格式轉換,但是序列化他的原型就不是格式,是記憶體裡面的一坨。只是嚴格意義上來說不是編碼,其實編碼並沒有一個嚴格規定。
把任意資料轉換成指定大小範圍的資料(通常很小)
比如我們有兩百個同學,我們把每一個學員編一個號,001,003…這個過程就是一個hash過程,而每個人他的編號就是一個hash值。
用作摘要、數位指紋
比如:
直接用字串的長度做hash
「haha」–>4
「pa」–>2
後面是數值就是hash值,這是一種很差勁的hash,因為
「hehe」–>4
hash他會有身份識別的這種要求,所以hash要求有極小的碰撞率,那麼就研究你的hash演演算法要怎麼算,給你的資料可能非常大,也可能非常小。你都需要快速得出結果,並且互相之間不會碰撞。
MD5(在防破解方面已經基本被遺棄了,因為他太容易破解了)、SHA1、SHA256
比如我們要下一個安裝包,那個釋出者可能會在下面給你提供一個用於驗證的hash值,他會給你指明這是一個sha1值還是一個sha256,還是一個md5,他會跟你說,也有可能會給你提供多個驗證的值,這個有什麼作用呢?上傳者這有一個原始檔,他有5個g,他的md5值算完以後是7788, 你下載以後,你這個下載檔案可能已經損壞了,可能下載過程中你的下載工具出錯了,或者有人修改你的網路了,總之你下完以後,這個東西可能是破壞了的,你對她也算一下你的hash值,比如算一下他的md5,如果也是7788,證明你下載的這個檔案他是完整的。如果你算完是2567,那麼你這個檔案下載失敗了。hash就像是在你的一堆資料裡面抽取特徵值一樣。如果你多次計算都是這個結果,那麼他就可以當成一個指紋一樣的存在。
(這一部分理解有問題得修改)
hashCode()和HashMap
java中有用到hash的時候,重寫equals方法的時候也要重寫hashCode方法
hashcode就是用來快速判斷是否對等的(預判斷)
前幾年有一個網站,被脫褲了,技術的部落格網站被脫褲了,被脫褲以後就有很多人說他們是用了明文儲存,所以才導致使用者的隱私被洩漏。這個是什麼原因呢?首先,使用者資料被盜,很容易理解,如果是明文儲存,盜走的人將你的使用者名稱和密碼在別的網站不斷嘗試,就會導致很多使用者資訊被盜取。那麼什麼是非明文儲存呢?就是伺服器收到使用者賬號和密碼以後,用md5轉化後儲存(下次登入就把傳過來的密碼md5加密轉化一次以後再對照本地儲存的密碼),這樣被盜走以後,他也沒辦法去其他網站登入。
同時,有個東西叫加鹽,什麼叫加鹽呢?那些駭客也在進步,我們覺得哪裡比較難破解呢?因為hash不可逆,一,你拿到這個東西不能直接在網站登入驗證,因為在轉一次就是另外一個數值了;二,這個東西還沒法逆向算出他的原密碼。可是那些駭客時間多的是,他們把常用的密碼一個一個存起來再對映,當他們盜了你們的庫以後,逆推,比如密碼是123456,md5轉化後是ddddd,駭客們自己做一個md5對映表,就知道ddddd對應的原密碼是123456了,這個暴力破解的對映表就叫彩虹表,可以一定程度上破解這種使用hash儲存密碼的方式。那麼,使用加鹽就可以破解這個東西。什麼叫加鹽,每個網站自己定義一個鹽,這個鹽是你嚴格保密的,不會被別人拿走,脫褲的時候被人把鹽也拿走也挺慘的。鹽是什麼呢?鹽就是你做md5或者sha1的時候,你不是用123456做hash,而是加個333,123456333,這個333就是你的鹽,他的md5值就完全是另外一個值了。每個網站的鹽都不一樣,這樣就導致彩虹表失效了。一般鹽都不會是333,而是一長串非常規字元。
不是,編碼是什麼?你編過去,編回來任何資料都不損失。hash是什麼?hash是抽取你的特徵,他不能逆向。
Hash是加密嗎?據說MD5是不可逆加密?
不是加密,百度百科都搞錯了,他是一種不可逆的轉化。還有人發明一個不可逆加密,聽著很有道理。但是假如你就是要把這個詞他的意思改掉,加密的意思就是把A格式改成B格式,別人看不懂,並且可以被還原。但是你硬是要把加密這兩個字曲解成別的意思,他的意思是讓別人看不懂,那我承認MD5是一種不可逆加密,但是加密這個詞是有他自己的定義的,這個詞不能亂說的。
這是之前一個圖,這個圖有個缺點,他的簽名資料和原資料是一樣大的,因為簽名資料可以還原回來呀。你檔案小沒關係,一個10G的視訊,他的簽名要10G那麼大,想想就覺得好臃腫啊。事實上簽名的做法,他們會對資料先進行hash,再進行簽名,對那個hash值進行簽名。
含義:一個由整數向現實世界中的文字元號的Map
128個字元,一個位元組(可以使用256個,但是ASCII只用了其中128個)
對ASCII進行擴充,1 位元組
13萬字元,多位元組
UTF-8:Unicode編碼分支
UTF-16:Unicode編碼分支
什麼叫編碼分支呢?
比如我有三個字:中國人
其中「中」他可能對應的是00000001,
「國」對應的是00001111,
「人」對應的是11111111
這是他們對應的編碼,但是實際表達的時候我們可能不會這麼寫
中01
國001111
人11111111
短了一點,這個可能就是UTF-8
另外一種方法,也許是
中0001
國1111
人11111111
這種可能是UTF-16
就是他們的字元集可能一致,但是具體的編碼方式可能不一致,這個就是不同的編碼。當然上面這個例子是不對的,比如UTF-8和UTF-16有一個很明顯的區別,UTF-16是16位元表示一個字元,所以不存在上面這麼短的,上面只是在舉例子。
GBK/GBK2312/GBK18030:中國自研標準,多位元組,字元集+編碼