原文:https://www.cnblogs.com/you-men/p/14160439.html
加密解密在實際開發中應用比較廣泛,常用加解密分為:“對稱式”、“非對稱式”和”數字簽名“。
對稱式:對稱加密(也叫私鑰加密)指加密和解密使用相同金鑰的加密演算法。具體演算法主要有DES演算法,3DES演算法,TDEA演算法,Blowfish演算法,RC5演算法,IDEA演算法。
非對稱加密(公鑰加密):指加密和解密使用不同金鑰的加密演算法,也稱為公私鑰加密。具體演算法主要有RSA、Elgamal、揹包演算法、Rabin、D-H、ECC(橢圓曲線加密演算法)。
數字簽名:數字簽名是非對稱金鑰加密技術與數字摘要技術的應用。如MD5、SHA1、HMAC等, 主要用於驗證,防止資訊被修改, 如:檔案校驗、數字簽名、鑑權協議;
以下介紹golang語言主要的加密解密演算法實現。
2|0md5
MD5資訊摘要演算法是一種被廣泛使用的密碼雜湊函式,可以產生出一個128位(16進位制,32個字元)的雜湊值(hash value),用於確保資訊傳輸完整一致。
3|0hmac
HMAC是金鑰相關的雜湊運算訊息認證碼(Hash-based Message Authentication Code)的縮寫,
它透過一個標準演算法,在計算雜湊的過程中,把key混入計算過程中。
和我們自定義的加salt演算法不同,Hmac演算法針對所有雜湊演算法都通用,無論是MD5還是SHA-1。採用Hmac替代我們自己的salt演算法,可以使程式演算法更標準化,也更安全。
4|0Base64
4|1base64不是加密演算法
它是一種資料編碼方式,雖然是可逆的,但是它的編碼方式是公開的,無所謂加密。本文也對Base64編碼方式做了簡要介紹。
4|2實現Base64編碼解碼
Base64是一種任意二進位制到文字字串的編碼方法,常用於在URL、Cookie、網頁中傳輸少量二進位制資料。 首先使用Base64編碼需要一個含有64個字元的表,這個表由大小寫字母、數字、+和/組成。採用Base64編碼處理資料時,會把每三個位元組共24位作為一個處理單元,再分為四組,每組6位,查表後獲得相應的字元即編碼後的字串。編碼後的字串長32位,這樣,經Base64編碼後,原字串增長1/3。如果要編碼的資料不是3的倍數,最後會剩下一到兩個位元組,Base64編碼中會採用\x00在處理單元后補全,編碼後的字串最後會加上一到兩個 = 表示補了幾個位元組。
5|0sha1
SHA-1可以生成一個被稱為訊息摘要的160位(20位元組)雜湊值,雜湊值通常的呈現形式為40個十六進位制數。
6|0bcrypt加密
7|0AES
密碼學中的高階加密標準(Advanced Encryption Standard,AES),又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES(Data Encryption Standard),已經被多方分析且廣為全世界所使用。AES中常見的有三種解決方案,分別為AES-128、AES-192和AES-256。如果採用真正的128位加密技術甚至256位加密技術,蠻力攻擊要取得成功需要耗費相當長的時間。
AES有五種加密模式
7|1ECB模式
出於安全考慮,golang預設並不支援ECB模式。
7|2CBC模式
7|3CRT模式
7|4CFB模式
7|5OFB模式
7|6RSA加密簡介
7|7rsa加密演算法簡史
RSA是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。
7|8rsa加密演算法實現原理
學過演算法的朋友都知道,計算機中的演算法其實就是數學運算。所以,再講解RSA加密演算法之前,有必要了解一下一些必備的數學知識。我們就從數學知識開始講解。
7|9必備數學知識
RSA加密演算法中,只用到素數、互質數、指數運算、模運算等幾個簡單的數學知識。所以,我們也需要了解這幾個概念即可
7|10素數
素數又稱質數,指在一個大於1的自然數中,除了1和此整數自身外,不能被其他自然數整除的數。這個概念,我們在上初中,甚至小學的時候都學過了,這裡就不再過多解釋了。
7|11互質數
百度百科上的解釋是:公因數只有1的兩個數,叫做互質數。;維基百科上的解釋是:互質,又稱互素。若N個整數的最大公因子是1,則稱這N個整數互質。
常見的互質數判斷方法主要有以下幾種:
7|12指數運算
7|13模運算
8|0RSA加密演算法
8|1公鑰和金鑰的產生
假設Alice想要透過一個不可靠的媒體接收Bob的一條私人訊息。她可以用以下的方式來產生一個公鑰和一個私鑰:
8|2加密訊息
假設Bob想給Alice送一個訊息m,他知道Alice產生的N和e。他使用起先與Alice約好的格式將m轉換為一個小於N的整數n,比如他可以將每一個字轉換為這個字的Unicode碼,然後將這些數字連在一起組成一個數字。假如他的資訊非常長的話,他可以將這個資訊分為幾段,然後將每一段轉換為n。用下面這個公式他可以將n加密為c:
ne ≡ c (mod N)
計算c並不複雜。Bob算出c後就可以將它傳遞給Alice。
8|3解密訊息
Alice得到Bob的訊息c後就可以利用她的金鑰d來解碼。她可以用以下這個公式來將c轉換為n:
cd ≡ n (mod N)
得到n後,她可以將原來的資訊m重新復原。
8|4解碼的原理是
cd ≡ n e·d(mod N)
以及
ed ≡ 1 (mod p-1)
和ed ≡ 1 (mod q-1)。
由費馬小定理可證明(因為p和q是質數)
n e·d ≡ n (mod p)
和n e·d ≡ n (mod q)
這說明(因為p和q是不同的質數,所以p和q互質)
n e·d ≡ n (mod pq)
8|5簽名訊息
RSA也可以用來為一個訊息署名。假如甲想給乙傳遞一個署名的訊息的話,那麼她可以為她的訊息計算一個雜湊值(Message digest),然後用她的金鑰(private key)加密這個雜湊值並將這個“署名”加在訊息的後面。這個訊息只有用她的公鑰才能被解密。乙獲得這個訊息後可以用甲的公鑰解密這個雜湊值,然後將這個資料與他自己為這個訊息計算的雜湊值相比較。假如兩者相符的話,那麼他就可以知道發信人持有甲的金鑰,以及這個訊息在傳播路徑上沒有被篡改過。
9|0Golang加密解密之RSA
9|1概要
這是一個非對稱加密演算法,一般透過公鑰加密,私鑰解密。
在加解密過程中,使用openssl生產金鑰。執行如下操作:
9|2建立私鑰
9|3建立公鑰
一般地,各個語言也會提供API,用於生成金鑰。在Go中,可以檢視
encoding/pem
包和crypto/x509
包。加密解密這塊,涉及到很多標準
9|4Go RSA加密
- rsa加解密, 必須會去查crypto/ras這個包
這是該包的說明:實現RSA加密技術,基於PKCS#1規範。
對於什麼是PKCS#1,可以查閱相關資料。PKCS(公鑰密碼標準),而#1就是RSA的標準。可以檢視:PKCS系列簡介
從該包中函式的名稱,可以看到有兩對加解密的函式。
這稱作加密方案,詳細可以檢視,PKCS #1 v2.1 RSA 演算法標準
可見,當與其他語言互動時,需要確定好使用哪種方案。
PublicKey和PrivateKey兩個型別分別代表公鑰和私鑰,關於這兩個型別中成員該怎麼設定,這涉及到RSA加密演算法,本文中,這兩個型別的例項透過解析文章開頭生成的金鑰得到。
2 . 解析金鑰得到PublicKey和PrivateKey的例項
這個過程,我也是花了好些時間(主要對各種加密的各種東東不熟):怎麼將openssl生成的金鑰檔案解析到公鑰和私鑰例項呢?
在
encoding/pem
包中,看到了—–BEGIN Type—–這樣的字樣,這正好和openssl生成的金鑰形式差不多,那就試試。在該包中,一個block代表的是PEM編碼的結構,關於PEM,請查閱相關資料。我們要解析金鑰,當然用Decode方法:
這樣便得到了一個Block的例項(指標)。
解析來看
crypto/x509
。為什麼是x509呢?這又涉及到一堆概念。先不管這些,我也是看encoding和crypto這兩個包的子包摸索出來的。
在x509包中,有一個函式:
從該函式的說明:ParsePKIXPublicKey parses a DER encoded public key. These values are typically found in PEM blocks with “BEGIN PUBLIC KEY”。可見這就是解析PublicKey的。另外,這裡說到了PEM,可以上面的encoding/pem對了。
而解析私鑰的,有好幾個方法,從上面的介紹,我們知道,RSA是PKCS#1,剛好有一個方法:
返回的就是rsa.PrivateKey
9|5加密解密實現
加密
解密
使用例子
參考:
https://segmentfault.com/a/1190000024557845
https://www.jb51.net/article/89884.htm