前情概述
由于后續(xù)會持續(xù)更新
iOS
應用安全系列文章 , 在此先更幾篇密碼學 , 應用簽名 , 為后續(xù)展開代碼注入 , 匯編 , 砸殼等文章打下基礎.
密碼學
密碼學概述
密碼學是研究編制密碼和破譯密碼的技術科學斟赚。研究密碼變化的客觀規(guī)律,應用于編制密碼以保守通信秘密的织中,稱為編碼學笆呆;應用于破譯密碼以獲取通信情報的,稱為破譯學侨拦,總稱密碼學殊橙。
密碼學的起源可追溯到2000年前。而當今的密碼學是以數(shù)學為基礎的狱从。
密碼學溯源
密碼學的歷史大致可以追溯到兩千年前膨蛮,相傳古羅馬名將凱撒大帝為了防止敵方截獲情報,用密碼傳送情報季研。凱撒的做法很簡單敞葛,就是對二十幾個羅馬字母建立一張對應表。這樣与涡,如果不知道密碼本惹谐,即使截獲一段信息也看不懂持偏。
從凱撒大帝時代到上世紀70年代這段很長的時間里,密碼學的發(fā)展非常的緩慢氨肌,因為設計者基本上靠經(jīng)驗鸿秆。沒有運用數(shù)學原理。
重要節(jié)點:
- 在
1976
年以前怎囚,所有的加密方法都是同一種模式:加密卿叽、解密使用同一種算法。在交互數(shù)據(jù)的時候桩了,彼此通信的雙方就必須將規(guī)則告訴對方附帽,否則沒法解密。那么加密和解密的規(guī)則( 簡稱密鑰 )井誉,它保護就顯得尤其重要蕉扮。傳遞密鑰就成為了最大的隱患。這種加密方式被成為 對稱加密算法(symmetric encryption algorithm
)
1976
年颗圣,兩位美國計算機學家 迪菲( W.Diffie )喳钟、赫爾曼( M.Hellman ) 提出了一種嶄新構思,可以在不直接傳遞密鑰的情況下在岂,完成密鑰交換奔则。這被稱為“ 迪菲赫爾曼密鑰交換 ”算法。開創(chuàng)了密碼學研究的新方向.
1977
年三位麻省理工學院的數(shù)學家 羅納德·李維斯特( Ron Rivest )蔽午、阿迪·薩莫爾( Adi Shamir )和倫納德·阿德曼( Leonard Adleman )一起設計了一種算法易茬,可以實現(xiàn)非對稱加密。這個算法用他們三個人的名字命名及老,叫做RSA
算法抽莱。
RSA 加密算法
RSA
上世紀 70
年代產(chǎn)生的一種加密算法。其加密方式比較特殊骄恶,需要兩個密鑰:公開密鑰簡稱公鑰( publickey
)和私有密鑰簡稱私鑰( privatekey
)食铐。公鑰加密,私鑰解密僧鲁;私鑰加密虐呻,公鑰解密。這個加密算法就是偉大的 RSA
.
這種算法非衬海可靠斟叼,密鑰越長,它就越難破解春寿。根據(jù)已經(jīng)披露的文獻犁柜,目前被破解的最長 RSA
密鑰是 768
個二進制位。也就是說堂淡,長度超過 768
位的密鑰馋缅,還無法破解(至少沒人公開宣布)。因此可以認為绢淀,1024
位的 RSA
密鑰基本安全萤悴,2048
位的密鑰極其安全。
( 當然 RSA 的缺陷也很容易想到 : 效率相對較低 , 字節(jié)長度限制等 . 因此實際應用中我們往往會結合對稱性加密一起使用 , 關鍵內容使用 RSA
)
RSA 數(shù)學原理
本小節(jié)內容了解即可
1. 離散對數(shù)問題
問: 三的多少次方模 17
等于 12
?
顯然 , 對于離散對數(shù)問題 , 其正向計算得到右邊
12
很簡單. 但是反向運算時 , 就無從下手. 只能窮舉 .而且當模數(shù)使用質數(shù)
17
時 , 結果固定在1 ~ 17
之間. 而當17
這個模數(shù)足夠大時 , 就算知道采用的是這個算法 , 也知道17
這個質數(shù)和答案 , 想要再計算出來上圖中這個問號值 , 可以想象到其難度和計算量有多大 .
2. 歐拉函數(shù) φ
歐拉函數(shù) :
給定任意正整數(shù) n , 在小于等于 n 的正整數(shù)中 , 能與 n 構成互質關系的正整數(shù)個數(shù).
計算這個值的方式叫做歐拉函數(shù)皆的,使用:φ(n)
表示
- 例 ??:
φ(8)
有 1,3,5,7
即是 φ(8) = 4
φ(7)
有 1,2,3,4,5,6
即是 φ(8) = 6
- 問 :
那么 φ(56)
是多少 ?
先別急著一個個去數(shù) , 我們來看下 歐拉函數(shù)的特點 .
- 當
n
是質數(shù)的時候覆履,φ(n) = n-1
- 當
n
可以分解成兩個互質的整數(shù)之積,如n = A*B
則 :φ(A*B)=φ(A)* φ(B)
因此 :
如果 N
是兩個質數(shù) P1
和 P2
的乘積則 φ(N) = φ(P1) * φ(P2) = (P1-1)*(P2-1)
那么顯然 φ(56) = φ(7) * φ(8) = 4 * 6 = 24
而 φ(63) = φ(7) * φ(9) = (7-1) * (9-1) = 48
3. 歐拉定理
如果兩個正整數(shù) m
和 n
互質费薄,那么 m
的 φ(n)
次方減去 1
硝全,可以被 n
整除。
小提示: 關于定理 , 不需要我們去證明它 , 只用記住就好.
3.1 費馬小定理
費馬小定理 就是在歐拉定理的基礎上 , 而當 n 為質數(shù)時 ( φ(n)結果就是n-1.)
那么 :
如果兩個正整數(shù) m
和 n
互質 , 且 n
是質數(shù) 楞抡,那么 m
的 n-1
次方減去 1
伟众,可以被 n
整除。
4. 公式轉換
-
首先根據(jù)歐拉定理
image - 由于
1
的k
次方恒等于1
, 那么
- 由于
1*m ≡ m
, 那么
- 在接下來第四部之前 , 我們要先提一個概念 : 模反元素
如果兩個正整數(shù)
e
和x
互質召廷,那么一定可以找到整數(shù)d
凳厢,使得ed-1
被x
整除。那么d
就是e
對于x
的模反元素 .
那么換算成公式 就是:
- 轉換一下寫法
注意比較第五步和第三步中紅框部分. 也就是說當 x
等于 Φ(n)
時 :
( 其中 d 是 e 相對于 φ(n) 的模反元素 , 因為 x =
Φ(n)
嘛 )
注意 : 公式推導第一步時 我們歐拉定理的前提是 m
和 n
互質 , 但是由于模反元素的關系 , 其實只要滿足 m < n
上述結果依然成立.
重頭戲來了 , 用實際場景來看下迪菲赫爾曼密鑰交換過程
原理:
結合我們剛剛第五步之后得出的
因此:
( 其中 d 是 e 相對于 φ(n) 的模反元素 , 因為 x = Φ(n)
, 那么同樣 , e 和 φ(n) 是互質關系 )
大家可以自己去實驗一下 .
例如: m = 3 , n = 15 , φ(n) = 8 , e = 3 , d = 11
.
到了這里 , 我們就得到了RSA算法的原理 . 那么我們對應起來介紹一下
RSA算法的原理
1竞慢、
n
會非常大先紫,長度一般為1024
個二進制位。(目前人類已經(jīng)分解的最大整數(shù)筹煮,232
個十進制位遮精,768
個二進制位)2、由于需要求出
φ(n)
败潦,所以根據(jù)歐函數(shù)特點本冲,最簡單的方式n
由兩個質數(shù)相乘得到: 質數(shù):p1
、p2
. 那么
Φ(n) = (p1 -1) * (p2 - 1)
3变屁、最終由
φ(n)
得到e
和d
眼俊。
總共生成 6 個數(shù)字:p1、p2粟关、n疮胖、φ(n)、e闷板、d
- 其中
n
和e
組成公鑰 .n
和d
組成私鑰 .m
為明文 .c
為密文 .
( 除了公鑰用到了 n
和 e
其余的 4 個數(shù)字是不公開的澎灸。)
HASH 算法
HASH 介紹
Hash
,一般翻譯做 “ 散列 ”遮晚,也有直接音譯為“ 哈希 ”的性昭,就是把任意長度的輸入通過散列算法變換成固定長度的輸出,該輸出就是散列值县遣。這種轉換是一種壓縮映射糜颠,也就是汹族,散列值的空間通常遠小于輸入的空間,不同的輸入可能會散列成相同的輸出其兴,所以不可能從散列值來確定唯一的輸入值顶瞒。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數(shù)
HASH 特點
- 算法是公開的
- 對相同數(shù)據(jù)運算,得到的結果是一樣的
- 對不同數(shù)據(jù)運算,如
MD5
得到的結果默認是128
位,32
個字符(16
進制標識) - 這玩意沒法逆運算 ( 因此
HASH
并不用于加解密) - 信息摘要,信息“指紋”元旬,是用來做數(shù)據(jù)識別的
HASH 主要用途
用戶密碼的加密
搜索引擎 ( 根據(jù) hash 值來匹配搜索內容 等)
版權
數(shù)字簽名
云盤文件審核 / 同文件識別
...等等
HASH 安全性探討
由于相同數(shù)據(jù) hash
得到的結果是一樣的 . 那么市面上大量萬億級 hash
結果記錄數(shù)據(jù)庫的存在 , 這個不可逆的算法 也另類的變成了可解密的存在.
因此 , 我們使用時經(jīng)常有以下幾種操作 :
- 加鹽 ( 早期比較普遍的做法 )
- 嵌套 hash
- 動態(tài)鹽
- HMAC ( 也可以說成動態(tài)鹽的一種吧 )
- ... 等等
HMAC 加密方案
HMAC
使用一個密鑰加密 , 并且做了兩次散列 . 在實際開發(fā)中 , 密鑰往往來自于服務器下發(fā)給客戶端 并且可能是根據(jù)賬戶綁定的 . 并需要結合實際業(yè)務需求來設定注冊與登錄邏輯 ( 新設備授權等方式來決定服務器是否可以下發(fā)密鑰給客戶端 )
看到這可能大家也跟我一樣 都有個疑問 .
疑問
我不管你是如何
嵌套
加鹽
HMAC
等什么方式去對密碼做處理. 既然你登錄是一個賬號一個加密后的密碼. 我抓包工具抓到就可以直接調用接口實現(xiàn)登錄.
是啊 , 那不就 GG
了?
這就牽扯到接口安全的問題 , 其處理方法有很多種, 例如所有請求用HTTPS
, 并且使用對稱性加密和非對稱性加密結合等等方式對數(shù)據(jù)進行加密.
當然再安全的加密算法也有被破解的風險. 因此以下這種方式 , 大家可以理解參考一下 , 它能比較有效的解決抓包問題 :
解答
-
- 注冊時
- 同樣使用
HMAC
的模式 , 也就是注冊時 , 客戶端把用戶名傳給服務器 . - 服務器隨機生成一個密鑰返回給客戶端 , 并綁定這個密鑰到用戶表該用戶中.
- 客戶端拿這個
key
將用戶明文密碼進行HMAC
散列后發(fā)給服務器保存.
-
- 登錄時
- 登錄時將用戶
HMAC
之后的hash
值 加上精確到分的時間戳 (時間統(tǒng)一為服務器下發(fā)時間 , 相信大家項目也都是使用了服務器時間.
) 然后進行散列. - 服務器收到請求 , 分別驗證當前時間和前一分鐘時間加上之前存儲的
HMAC
后的密碼進行hash
. 兩次有一次成功即為登錄成功.
思考:
為什么以上方式可以有效防護到接口被抓包的情況 ?
- 用戶
HMAC
之后的hash
值 只有在注冊該賬戶時被傳輸過一次 . - 抓到接口中 時間戳加
HMAC
之后的hash
值進行散列 很難猜出嵌套方式. - 使用抓到的接口中的源數(shù)據(jù) ( 時間戳加
HMAC
之后的hash
值 ) 每次都不一樣 , 而且有效期只有最多 1 分 59 秒,最少一分鐘 ( 有效期可靈活控制 ) 也就是說抓包人員抓到請求源數(shù)據(jù)后 , 必須在兩分鐘以內登錄 , 否則就會失效.
HASH 題外話
可能有小伙伴碰到過上傳云盤的文件被和諧的情況 , 并且改了名字或者后綴名重新傳還是不行. 其實這就是 HASH
的一種運用場景 . 要 理解 HASH
是對二進制數(shù)據(jù)進行散列 . 那么改名字和后綴名其文件二進制是不會變化的 .
但是壓縮是可以的 .
也就是說壓縮是會改變內存大小 , 其內部二進制散列之后的結果也會變化 . 同樣
base64
也是會改變二進制數(shù)據(jù)的.