iOS逆向實戰--010:RSA加密

密碼學概述

密碼學是指研究信息加密,破解密碼的技術科學。密碼學的起源可追溯到2000年前。而當今的密碼學是以數學為基礎的。

發展歷史

密碼學的歷史大致可以追溯到兩千年前,相傳古羅馬名將凱撒大帝為了防止敵方截獲情報,用密碼傳送情報。凱撒的做法很簡單,就是對二十幾個羅馬字母建立一張對應表。這樣,如果不知道密碼本,即使截獲一段信息也看不懂

凱撒密碼(Caesar cipher):

從凱撒大帝時代到上世紀70年代這段很長的時間里,密碼學的發展非常的緩慢,因為設計者基本上靠經驗,沒有運用數學原理

這種加密方式的弊端

  • 密碼本泄露,密碼將被破解
  • 獲取足夠多的情報,通過大數據分析,統計字母出現頻率,也能找到其中的規則

1976年以前,所有的加密方法都是同一種模式:加密、解密使用同一種算法。在交互數據的時候,彼此通信的雙方就必須將規則告訴對方,否則沒法解密。那么加密和解密的規則(簡稱密鑰),它保護就顯得尤其重要。傳遞密鑰就成為了最大的隱患。這種加密方式被成為對稱加密算法symmetric encryption algorithm

1976年,兩位美國計算機學家迪菲W.Diffie)、赫爾曼M.Hellman) 提出了一種嶄新構思,可以在不直接傳遞密鑰的情況下,完成密鑰交換。這被稱為“迪菲赫爾曼密鑰交換”算法。開創了密碼學研究的新方向

1977年,三位麻省理工學院的數學家羅納德·李維斯特Ron Rivest)、阿迪·薩莫爾Adi Shamir)和倫納德·阿德曼Leonard Adleman)一起設計了一種算法,可以實現非對稱加密。這個算法用他們三個人的名字命名,叫做RSA算法

RSA數學原理

上世紀70年代產生的一種加密算法。其加密方式比較特殊,需要兩個密鑰:公開密鑰簡稱公鑰(publickey)和私有密鑰簡稱私鑰(privatekey)。公鑰加密,私鑰解密;私鑰加密,公鑰解密。這個加密算法就是偉大的RSA

取模算法

通過數學進行加密,必須滿足一個算法,加密容易,但通過加密結果反算原始內容一定要很難

早期的取模算法,在西方稱為時鐘算數

  • 環,即:取模,或者可將取模運算理解是環上的運算
  • 環即是取模,也是周期,取模即是周期
質數

質數又稱素數。一個大于1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做質數;否則稱為合數。規定1既不是質數也不是合數

質數2,是一個特殊的質數

  • 是最小的質數
  • 是質數中唯一的偶數
  • 是偶數中唯一的質數
  • 假如兩個或偶數個質數之和為奇數,則其中必定有一個是2
  • 假如兩個或偶數個質數只差為奇數,則其中必定有一個是2
  • 假如三個或奇數個質數之和為偶數,則其中必定有一個是2
  • 假如三個或奇數個質數之差為偶數,則其中必定有一個是2
  • 假如若干個質數之積為偶數,則其中必定有一個是2
原根

原根是一種數學符號,設n是正整數,m是整數,若mn的階等于φ(n),則稱m為模n的一個原根

原根存在的條件有以下幾個:

  • n是奇質數,則模n的原根存在
  • m是模n的原根,則mm + n是模n ^ 2的原根
  • n是奇質數,則對任意e,模n ^ e的原根存在
  • e >= 1,若m是模n ^ e的一個原根,則mm + n ^ e中的奇數是模2 * n ^ e的一個原根

例如:使用質數17作為模數,再使用一個比17小的質數3模以17

3 % 17,此時31-16次方模以17,得到的如下結果:

  • 31-16次方,模擬17的結果都不一樣。
  • 317次方,模以17的結果為3,和31次方模以17的結果一樣。318次方和2次方的結果一樣...

上述規律,稱之為317原根

離散對數問題

如果使用上述規律作為算法,3x次方的結果,一定是1-16之間的數字,但是通過結果反算x很難

當模數的質數越大,反算的難度就會越大,這種情況被稱之為離散對數問題

歐拉函數φ

互質關系:如果兩個正整數,除了1以外,沒有其他公因數,我們就稱這兩個數是互質關系(coprime

任意給定正整數n,在小于等于n的正整數之中,有多少個數可以與n構成互質關系?

計算這個值的公式叫做歐拉函數,使用:φ(n)表示


案例1:

計算8的歐拉函數,和8互質的1、2、3、4、5、6、7、8
φ(8) = 4


案例2:

計算7的歐拉函數,和7互質的123456、7
φ(7) = 6


歐拉函數特點:

n是質數的時候,φ(n) = n - 1

如果n可以分解成兩個互質的整數之積

  • n = p1 * p2
  • φ(p1 * p2) = φ(p1) * φ(p2)

根據以上兩點得到:

  • 如果n是兩個質數p1p2的乘積,且p1p2互質
  • φ(n) = φ(p1) * φ(p2) = (p1 - 1) * (p2 - 1)

案例3:

計算56的歐拉函數
φ(56) = φ(8) * φ(7) = 4 * 6 = 24

歐拉定理
  • 如果兩個正整數mn互質,那么mφ(n)次方減去1,可以被n整除
  • m ^ φ(n) - 1 % n ≡ 0
  • m ^ φ(n) % n ≡ 1

例如:m = 5n = 8φ(8) = 4

5 ** 4 % 8
-------------------------
1
費馬小定理
  • 歐拉定理的特殊情況:如果兩個正整數mn互質,而且n為質數
  • φ(n)結果就是n - 1
  • m ^ (n - 1) % n ≡ 1

例如:m = 6n = 5

6 ** (5 - 1) % 5
-------------------------
1
公式轉換

費馬小定理

  • m ^ φ(n) % n ≡ 1

由于1 ^ k ≡ 1

  • m ^ φ(n) % n看作一個整體x
  • x ≡ m ^ φ(n) % n ≡ 1
  • x ^ k ≡ 1 ^ k

mn互質

  • x ^ k ≡ m ^ (k * φ(n)) % n
  • m ^ (k * φ(n)) % n ≡ 1

例如:m = 6n = 5k = 3

6 ** (3 * (5 - 1) ) % 5
-------------------------
1

由于1 * m ≡ m

  • m ^ (k * φ(n) + 1) % n ≡ m

例如:m = 6n = 7k = 3

6 ** (3 * (7 - 1) + 1) % 7
-------------------------
6
  • 注:必須m小于n,此公式才成立
模反元素

如果兩個正整數ex互質,那么一定可以找到整數d,使得ed - 1x整除。d就是e對于x的“模反元素

  • e * d - 1 % x ≡ 0
  • e * d % x ≡ 1

由公式推導

  • e * d - 1 % x ≡ 0
  • e * d - 1 / x ≡ k
  • e * d - 1 ≡ k * x
  • e * d ≡ k * x + 1

由公式推導,如果x = φ(n)

  • m ^ (k * φ(n) + 1) % n ≡ m
  • m ^ (k * x + 1) % n ≡ m

由公式推導,exφ(n))互質,得到以下公式:

  • e * d ≡ k * x + 1
  • m ^ (e * d) % n ≡ m

案例:

m = 4n = 15,當x的值等于φ(n)

  • x = φ(n) = φ(15) = φ(3) * φ(5) = 2 * 4 = 8
  • ex互質,e = 3
  • e * d - 1 / x ≡ k
  • e * d - 1 = x * k
  • d = (x * k + 1) / e

計算d的值

  • k = 4(8 * 4 + 1) / 3d = 11
  • k = 7(8 * 7 + 1) / 3d = 19

d = 11,代入公式:m ^ (e * d) % n ≡ m

4 ** (3 * 11) % 15
-------------------------
4

d = 19,代入公式:m ^ (e * d) % n ≡ m

4 ** (3 * 19) % 15
-------------------------
4
迪菲赫爾曼密鑰交換

迪菲赫爾曼密鑰交換是一種安全協議。它可以讓雙方在完全沒有對方任何預先信息的條件下通過不安全信道創建起一個密鑰。這個密鑰可以在后續的通訊中作為對稱密鑰來加密通訊內容

使用對稱加密,假設10密鑰

  • 服務端與客戶端加解密,需要服務端傳遞密鑰給客戶端。如果密鑰被第三方竊取,加密則不再安全

使用迪菲赫爾曼密鑰交換,假設一個傳遞密鑰的場景,算法是3n次方模以17

  • 服務端和客戶端,分別通過算法計算出兩個隨機數,1513
  • 兩端使用相同的算法,計算出612
  • 兩端將結果612傳遞給對方
  • 兩端再次使用相同的算法,都計算出結果10
  • 案例中,10才是對稱加密真正使用的密鑰。在數據傳輸中,第三方只能竊取到612兩個數字。即便知道算法,再得不到1513的情況下,也無法計算出密鑰

迪菲赫爾曼密鑰交換公式原理:

  • 公式成立的條件在于,317的原根
  • 公式3 ^ (13 * 15) % 17就是模反元素公式m ^ (e * d) % n ≡ m,相當于將其拆分成兩步
RSA算法

RSA公開密鑰密碼體制的原理是:根據數論,尋求兩個大質數比較簡單,而將它們的乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰

  • n會非常大,長度一般為1024個二進制位。目前人類已經分解的最大整數,232個十進制位,768個二進制位
  • 由于需要求出φ(n),所以根據歐函數特點,最簡單的方式n由兩個質數相乘得到。質數:p1p2
    φ(n) = (p1 - 1) * (p2 - 1)
  • 最終由φ(n)得到ed

總共生成6個數字:p1p2nφ(n)ed

  • 公鑰:ne
  • 私鑰:nd
  • 明文:m
  • 密文:c

案例:

m = 12,n = 15,φ(n) = 8,e = 3,d = 11

加密:m ^ e % n = c

12 ** 3 % 15
-------------------------
3

解密:c ^ d % n = m

3 ** 11 % 15
-------------------------
12

RSA的安全:

  • 除了公鑰用到了ne,其余的4個數字是不公開的

目前破解RSA得到d的方式如下:

  • 要想求出私鑰d,由于e * d = φ(n) * k + 1。需要知道eφ(n)
  • e是知道的,但是要得到φ(n),就必須知道p1p2
  • 由于n = p1 * p2。只有將n因數分解才能算出

運算速度

  • 由于進行的都是大數計算,使得RSA最快的情況也比DES慢上好幾倍
  • RSA的速度比對應同樣安全級別的對稱密碼算法要慢1000倍左右
  • 速度一直是RSA的缺陷,所以大量數據并不適合RSA,一般來說只用于少量數據加密
  • 日常開發中,大數據采用對稱加密,例如:DES。而對稱加密使用的密鑰,則通過RSA進行加密
終端命令

Mac的終端可以直接使用OpenSSL進行RSA的命令運行。

OpenSSL

由于Mac系統內置開源加密庫OpenSSL,所以在終端上可以直接使用命令運行RSAOpenSSLRSA算法常用指令主要有三個:

命令 含義
genrsa 生成并輸入一個RSA私鑰
result 使用RSA密鑰進行加密、解密、簽名和驗證等運算
rsa 處理RSA密鑰的格式轉換等問題

案例1:

生成RSA私鑰,密鑰長度為1024bit

openssl genrsa -out private.pem 1024
-------------------------
Generating RSA private key, 1024 bit long modulus (2 primes)
...........+++++
..+++++
e is 65537 (0x010001)

私鑰中提取公鑰

openssl rsa -in private.pem -pubout -out public.pem
-------------------------
writing RSA key

生成私鑰公鑰的證書文件

使用cat private.pem命令,查看private.pem內容

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCzxKp3IKq2SHTqJXgZ0aU0lCHJl/f6VWZs5PXsB26yoe6kwqDN
HJWba8hPY7eewAq9/HUyH1MhQUUKwOj8+etwrdfwd0aPwYsRdtT2QzC2LRT1y43A
+IUR0uUbGE1kMROPheyWcBmTA/zcXAINKhGF/Z/pUCzouoUbNh950VHfQQIDAQAB
AoGASMhpVA4Pz/mKDHrbI2j0AFOxUlOK/PmynIge4U8pDH3vhxmdzS2zjNeYpDv1
Tfrm3oDmWkLAf4hTkcUFD9eH8MsNsnORUnn+PbHGIysrArDdwbOtj4LE66YHfQxN
lf/Gi4Zpao4p5wBcsiZYaOWtor5oUsLOf1kKlIqt5/8szZkCQQDjmpVebA34lZFj
7dqXqZsYEB4HWHOnbtnV12UM77BqzPoAZjapAEa2Ofn/ct3RIqvXWrmY3pH6PiQQ
KJUk1+DfAkEAyjJD8vBoUiWH8ktNmHE5ua/H1Vmk6to5MenjKRNj9ACB/BvopfaS
xSr2PuVeQU9AOZNEGduadxaTOLJPCsmj3wJAdJ+n++roOcEB769X+7B3fRv9Fwx2
rot5aT5mU/uZbRA85el6BpzSntsUQ5VrHZdjcATX5wHc0Nn4hqMU0P0hBwJBAJC7
6me8LvCebPHDdYfphKimayUNRj/WdZqFEVYVyzaeJm2QjLhACE+asSnUheO6Fv8f
q1/XEnqsbjXnbS0LqYECQQCi+amvIpqvCUJeFDM9A9noPTEkAHWClBuCmBCeHl8+
RJdYx9ZJj3w81013xir06pX3YTKQvbzWpEUcNMBPl4N/
-----END RSA PRIVATE KEY-----
  • 二進制文件,以Base64編碼格式展示,占887字節

使用cat public.pem命令,查看public.pem內容

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzxKp3IKq2SHTqJXgZ0aU0lCHJ
l/f6VWZs5PXsB26yoe6kwqDNHJWba8hPY7eewAq9/HUyH1MhQUUKwOj8+etwrdfw
d0aPwYsRdtT2QzC2LRT1y43A+IUR0uUbGE1kMROPheyWcBmTA/zcXAINKhGF/Z/p
UCzouoUbNh950VHfQQIDAQAB
-----END PUBLIC KEY-----
  • 二進制文件,以Base64編碼格式展示,占272字節
  • 公鑰私鑰小很多

案例2:

創建message.txt文件,寫入以下內容:

ha ha ha ~

通過公鑰加密

openssl rsautl -encrypt -in message.txt -inkey public.pem -pubin -out enc.txt

使用cat enc.txt命令,查看加密內容

  • enc.txt為二進制文件,顯示亂碼

通過私鑰加密

openssl rsautl -decrypt -in enc.txt -inkey private.pem -out dec.txt

使用cat dec.txt命令,查看解密內容

ha ha ha ~
  • 原文11字節,密文128字節,使用RSA加密,數據增大很多

案例3:

通過私鑰簽名

openssl rsautl -sign -in message.txt -inkey private.pem -out enc.txt

使用cat enc.txt命令,查看加密內容

  • 二進制文件, 無法直接查看

通過公鑰驗證

openssl rsautl -verify -in enc.txt -inkey public.pem -pubin -out dec.txt

使用cat dec.txt命令,查看解密內容

ha ha ha ~

案例4:

私鑰轉換成為明文

openssl rsa -in private.pem -text -out private.txt
-------------------------
writing RSA key

使用cat private.txt命令,查看明文內容

RSA Private-Key: (1024 bit, 2 primes)
modulus:
   00:b3:c4:aa:77:20:aa:b6:48:74:ea:25:78:19:d1:
   a5:34:94:21:c9:97:f7:fa:55:66:6c:e4:f5:ec:07:
   6e:b2:a1:ee:a4:c2:a0:cd:1c:95:9b:6b:c8:4f:63:
   b7:9e:c0:0a:bd:fc:75:32:1f:53:21:41:45:0a:c0:
   e8:fc:f9:eb:70:ad:d7:f0:77:46:8f:c1:8b:11:76:
   d4:f6:43:30:b6:2d:14:f5:cb:8d:c0:f8:85:11:d2:
   e5:1b:18:4d:64:31:13:8f:85:ec:96:70:19:93:03:
   fc:dc:5c:02:0d:2a:11:85:fd:9f:e9:50:2c:e8:ba:
   85:1b:36:1f:79:d1:51:df:41
publicExponent: 65537 (0x10001)
privateExponent:
   48:c8:69:54:0e:0f:cf:f9:8a:0c:7a:db:23:68:f4:
   00:53:b1:52:53:8a:fc:f9:b2:9c:88:1e:e1:4f:29:
   0c:7d:ef:87:19:9d:cd:2d:b3:8c:d7:98:a4:3b:f5:
   4d:fa:e6:de:80:e6:5a:42:c0:7f:88:53:91:c5:05:
   0f:d7:87:f0:cb:0d:b2:73:91:52:79:fe:3d:b1:c6:
   23:2b:2b:02:b0:dd:c1:b3:ad:8f:82:c4:eb:a6:07:
   7d:0c:4d:95:ff:c6:8b:86:69:6a:8e:29:e7:00:5c:
   b2:26:58:68:e5:ad:a2:be:68:52:c2:ce:7f:59:0a:
   94:8a:ad:e7:ff:2c:cd:99
prime1:
   00:e3:9a:95:5e:6c:0d:f8:95:91:63:ed:da:97:a9:
   9b:18:10:1e:07:58:73:a7:6e:d9:d5:d7:65:0c:ef:
   b0:6a:cc:fa:00:66:36:a9:00:46:b6:39:f9:ff:72:
   dd:d1:22:ab:d7:5a:b9:98:de:91:fa:3e:24:10:28:
   95:24:d7:e0:df
prime2:
   00:ca:32:43:f2:f0:68:52:25:87:f2:4b:4d:98:71:
   39:b9:af:c7:d5:59:a4:ea:da:39:31:e9:e3:29:13:
   63:f4:00:81:fc:1b:e8:a5:f6:92:c5:2a:f6:3e:e5:
   5e:41:4f:40:39:93:44:19:db:9a:77:16:93:38:b2:
   4f:0a:c9:a3:df
exponent1:
   74:9f:a7:fb:ea:e8:39:c1:01:ef:af:57:fb:b0:77:
   7d:1b:fd:17:0c:76:ae:8b:79:69:3e:66:53:fb:99:
   6d:10:3c:e5:e9:7a:06:9c:d2:9e:db:14:43:95:6b:
   1d:97:63:70:04:d7:e7:01:dc:d0:d9:f8:86:a3:14:
   d0:fd:21:07
exponent2:
   00:90:bb:ea:67:bc:2e:f0:9e:6c:f1:c3:75:87:e9:
   84:a8:a6:6b:25:0d:46:3f:d6:75:9a:85:11:56:15:
   cb:36:9e:26:6d:90:8c:b8:40:08:4f:9a:b1:29:d4:
   85:e3:ba:16:ff:1f:ab:5f:d7:12:7a:ac:6e:35:e7:
   6d:2d:0b:a9:81
coefficient:
   00:a2:f9:a9:af:22:9a:af:09:42:5e:14:33:3d:03:
   d9:e8:3d:31:24:00:75:82:94:1b:82:98:10:9e:1e:
   5f:3e:44:97:58:c7:d6:49:8f:7c:3c:d7:4d:77:c6:
   2a:f4:ea:95:f7:61:32:90:bd:bc:d6:a4:45:1c:34:
   c0:4f:97:83:7f
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCzxKp3IKq2SHTqJXgZ0aU0lCHJl/f6VWZs5PXsB26yoe6kwqDN
HJWba8hPY7eewAq9/HUyH1MhQUUKwOj8+etwrdfwd0aPwYsRdtT2QzC2LRT1y43A
+IUR0uUbGE1kMROPheyWcBmTA/zcXAINKhGF/Z/pUCzouoUbNh950VHfQQIDAQAB
AoGASMhpVA4Pz/mKDHrbI2j0AFOxUlOK/PmynIge4U8pDH3vhxmdzS2zjNeYpDv1
Tfrm3oDmWkLAf4hTkcUFD9eH8MsNsnORUnn+PbHGIysrArDdwbOtj4LE66YHfQxN
lf/Gi4Zpao4p5wBcsiZYaOWtor5oUsLOf1kKlIqt5/8szZkCQQDjmpVebA34lZFj
7dqXqZsYEB4HWHOnbtnV12UM77BqzPoAZjapAEa2Ofn/ct3RIqvXWrmY3pH6PiQQ
KJUk1+DfAkEAyjJD8vBoUiWH8ktNmHE5ua/H1Vmk6to5MenjKRNj9ACB/BvopfaS
xSr2PuVeQU9AOZNEGduadxaTOLJPCsmj3wJAdJ+n++roOcEB769X+7B3fRv9Fwx2
rot5aT5mU/uZbRA85el6BpzSntsUQ5VrHZdjcATX5wHc0Nn4hqMU0P0hBwJBAJC7
6me8LvCebPHDdYfphKimayUNRj/WdZqFEVYVyzaeJm2QjLhACE+asSnUheO6Fv8f
q1/XEnqsbjXnbS0LqYECQQCi+amvIpqvCUJeFDM9A9noPTEkAHWClBuCmBCeHl8+
RJdYx9ZJj3w81013xir06pX3YTKQvbzWpEUcNMBPl4N/
-----END RSA PRIVATE KEY-----
  • 上面是二進制數據,最后面的是私鑰
  • 其中publicExponent: 65537 (0x10001)就是e
  • 公鑰e,在私鑰中已經存在。公鑰是通過私鑰計算得到的
代碼演示

RSA代碼加解密,iOS無法直接使用.pem證書,需要使用p12der

案例1:

通過私鑰生成.csr請求文件

openssl req -new -key private.pem -out rsacert.csr
  • 按提示輸入信息

目錄下生成rsacert.csr文件

  • 通過私鑰生成.csr請求文件,將其發給頒發證書的機構進行簽名,證明此證書的合法性。例如:https使用的ssl證書

案例2:

.csr文件自簽名,生成.crt證書

openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
-------------------------
Signature ok
subject=C = CN, ST = BJ, L = BJ, O = LG, OU = LG, CN = LG, emailAddress = Zang@163.com
Getting Private key
  • 自簽名證書是未經認證的,不受各類瀏覽器信任。僅用來案例演示,自娛自樂

目錄下生成rsacert.crt證書文件

  • 例如:使用https協議,需要將.crt證書放在服務器上,供客戶端接收

使用cat rsacert.crt命令,查看證書內容

-----BEGIN CERTIFICATE-----
MIICWDCCAcECFGuo1neUJVorMs1aHTn7m+JM79dwMA0GCSqGSIb3DQEBCwUAMGsx
CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkGA1UEBwwCQkoxCzAJBgNVBAoM
AkxHMQswCQYDVQQLDAJMRzELMAkGA1UEAwwCTEcxGzAZBgkqhkiG9w0BCQEWDFph
bmdAMTYzLmNvbTAeFw0yMTA0MTMxMDM5MTNaFw0zMTA0MTExMDM5MTNaMGsxCzAJ
BgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkGA1UEBwwCQkoxCzAJBgNVBAoMAkxH
MQswCQYDVQQLDAJMRzELMAkGA1UEAwwCTEcxGzAZBgkqhkiG9w0BCQEWDFphbmdA
MTYzLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs8SqdyCqtkh06iV4
GdGlNJQhyZf3+lVmbOT17AdusqHupMKgzRyVm2vIT2O3nsAKvfx1Mh9TIUFFCsDo
/PnrcK3X8HdGj8GLEXbU9kMwti0U9cuNwPiFEdLlGxhNZDETj4XslnAZkwP83FwC
DSoRhf2f6VAs6LqFGzYfedFR30ECAwEAATANBgkqhkiG9w0BAQsFAAOBgQAnuiB9
lxiV8ZIzElUx0JMxGXdhdxeKGouTpXysbVpqsppYe258bt9pYddU19ZedGgmOPT3
GVd60CoHCMWAJhMdVNpW+09bC+5hqNLGrAHM38bMEJkhHxAA5NUSwfC594K8j5bT
Plqei6QtutsTZ9FYLiuWhk5EufYgZJMsD9t/TA==
-----END CERTIFICATE-----
  • 二進制文件,直接查看是亂碼,所以使用Base64編碼

案例3:

通過.crt證書,生成.der證書

openssl x509 -outform der -in rsacert.crt -out rsacert.der
  • .der就是公鑰

目錄下生成rsacert.der證書文件

案例4:

通過私鑰.crt證書,導出.p12證書

openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt
-------------------------
Enter Export Password:
Verifying - Enter Export Password:
  • 需要對.p12設置密碼
  • .p12就是私鑰

目錄下生成p.p12證書文件

.p12.der證書是一對,分別對應私鑰公鑰

案例5:

使用RSA代碼加解密

打開RSADemo項目,將.p12.der證書拖進項目中

  • 勾選Add to targets選項

使用RSACryptor庫,提供以下方法:

#import <Foundation/Foundation.h>

@interface RSACryptor : NSObject

+ (instancetype)sharedRSACryptor;

//生成密鑰對
- (void)generateKeyPair:(NSUInteger)keySize;
//加載公鑰
- (void)loadPublicKey:(NSString *)publicKeyPath;
//加載私鑰
- (void)loadPrivateKey:(NSString *)privateKeyPath password:(NSString >*)password;
//加密數據
- (NSData *)encryptData:(NSData *)plainData;
//解密數據
- (NSData *)decryptData:(NSData *)cipherData;

@end

打開ViewController.m文件,加載公鑰私鑰

#import "ViewController.h"
#import "RSACryptor.h"

@implementation ViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   
   [[RSACryptor sharedRSACryptor] loadPublicKey:[[NSBundle mainBundle] pathForResource:@"rsacert.der" ofType:nil]];
   [[RSACryptor sharedRSACryptor] loadPrivateKey:[[NSBundle mainBundle] pathForResource:@"p.p12" ofType:nil] password:@"123456"];
}

@end

touchesBegan方法中,實現RSA加解密代碼

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
   NSString *strText = @"hello";
   
   NSData *dataEncrypt = [[RSACryptor sharedRSACryptor] encryptData:[strText dataUsingEncoding:NSUTF8StringEncoding]];
   NSString *strEncrypt = [dataEncrypt base64EncodedStringWithOptions:0];
   NSLog(@"加密:%@", strEncrypt);
   
   NSData *dataDecrypt = [[RSACryptor sharedRSACryptor] decryptData:dataEncrypt];
   NSString *strDecrypt = [[NSString alloc] initWithData:dataDecrypt encoding:NSUTF8StringEncoding];
   NSLog(@"解密:%@", strDecrypt);
}
  • 加密和解密,返回的都是二進制數據,無法直接查看

運行項目,點擊屏幕,輸出以下內容:

加密:Lw+Qvesbk1QfSyXh/dGoGmGuUngZQVUhnsLA+zFFaAqF8U2NJY/lAArzH2RZ2mdIGA5+ty2SHS+lWUshTsJebteC9JR7lydw31mIlWac4EtEue4ZaJZAYOALBVSGVKlW9q8Ra4hW9KRBFdDfzFa+0BFn0d6P7Xfv5M15IwOuDfc=
解密:hello
  • 將加密后二進制數據,進行Base64編碼,可查看編碼后內容
  • 將解密后二進制信息,進行UTF8編碼,可查看原文內容

案例6:

RSA加密的填充方式

上述案例,每次點擊屏幕,輸出的加密結果都不同,但都能解密成原文hello

加密:NL64/eVWYq7VRS/dqLDTw5WvH1kdLj/ODE5lbeA5C9pT7dDFz2f3hDVN3YjiY6/grMH2QgVvV6sX7mkb+YpmBXHakT13+vtyIw35YJcYb4w9gMzUwyWj6qynS1w3Mg8NioVzFO0diiP5Z/eIPNGS3TX2oeaY7imPSm2awuajO2k=
加密:ajIiKWwXi9OkykqE4nBW8G/hQ1LzyT0+aUqTdiSlQt40Svgj/10mn/gC1OM0Xom6HDX+5R8M9+rHFEK9eM4UrifYKDr+AKsP+rlNFmGEHTyZ5FZwUVVsM7rcNymbCSVvC3S6TPQY3i/G1IuLbiV7rffYufz4ew1b08fnR+tmRHU=
加密:AHth9iyax8banLC7yUJMWxLAZMRY2z/2v7flXoZu/TroPZybT+UzkrSV/haLJDOesqa514BgAnNq7s6vni9uA1yTO0UP2gaTWjvv7CB/TYCPVcALPdd+2FklBvMfXZCcWXpvXZBYQKtt8Fx59REiIKBoVz5tzNR5vz6+5Qj9DPY=

這種現象,和代碼中RSA加密的填充方式有關

#define kTypeOfWrapPadding        kSecPaddingPKCS1

RSA加密的三種填充方式

  • kSecPaddingNone:不填充,每次生成的加密結果都一樣
  • kSecPaddingPKCS1:最常用的填充方式,默認項
  • kSecPaddingOAEPPKCS#1推出的新的填充方式,安全性是最高

假如密鑰長度為1024bit,即:128Byte

  • 當客戶端選擇kSecPaddingNone填充模式時,如果明文不夠128字節,加密時會在明文前面,前向填充零,每次生成的加密結果都一樣。服務端在解密后,用相同的方式把前向填充的零去掉,才能得到真正的明文
  • 當選擇kSecPaddingPKCS1填充模式時,如果明文不夠128字節,會在明文中隨機填充一些數據,所以會導致對同樣的明文每次加密后的結果都不一樣。對加密后的密文,服務端使用相同的填充方式解密
  • kSecPaddingOAEP填充模式, 是PKCS#1推出的新的填充方式,安全性是最高的,和前面kSecPaddingPKCS1的區別就是加密前的編碼方式不一樣
總結

密碼學概述

  • 加密算法,都是數學知識
  • 對稱加密是傳統加密算法
  • RSA非對稱加密是現代加密算法
  • RSA是三位數學家的名字

RSA數學原理

  • 質數
  • 原根
  • 歐拉函數
  • 歐拉定理
  • 費馬小定理(正向計算容易,反算難)
  • 模反元素:m ^ (e * d) % n = m,目的找出ed
  • 迪菲赫爾曼密鑰交換

RSA算法

  • RSA拆解兩個大質數的乘積很難,所以相對安全
  • 加密:m ^ e % n = c
  • 解密:c ^ d % n = m
  • 公鑰:ne
  • 私鑰:nd
  • 明文:m
  • 密文:c

RSA成立條件

  • m必須小于n
  • n是由兩個質數相乘,得到一個很大的數。目的是方便求出φ(n)
  • de相對φ(n)的模反元素
  • n可以公開,但無法計算組成n的兩個質數p1p2,找不出p1p2就無法計算φ(n),找不出φ(n)就無法計算ed
  • e在使用OpenSSL生成私鑰時,設定為65537

RSA的特點

  • 加密安全系數非常高
  • 加密效率低
  • 不適合加密大數據
  • 僅用于加密關鍵數據
  • 配合對稱加密使用

RSA算法常用指令

  • genrsa:生成并輸入一個RSA私鑰
  • result:使用RSA密鑰進行加密、解密、簽名和驗證等運算
  • rsa:處理RSA密鑰的格式轉換等問題

代碼演示

  • 私鑰公鑰使用p12der格式

RSA加密的填充方式

  • kSecPaddingNone:不填充,每次生成的加密結果都一樣
  • kSecPaddingPKCS1:最常用的填充方式,默認項
  • kSecPaddingOAEPPKCS#1推出的新的填充方式,安全性是最高
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容

  • 夜鶯2517閱讀 127,743評論 1 9
  • 版本:ios 1.2.1 亮點: 1.app角標可以實時更新天氣溫度或選擇空氣質量,建議處女座就不要選了,不然老想...
    我就是沉沉閱讀 6,920評論 1 6
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,577評論 28 53
  • 兔子雖然是枚小碩 但學校的碩士四人寢不夠 就被分到了博士樓里 兩人一間 在學校的最西邊 靠山 兔子的室友身體不好 ...
    待業的兔子閱讀 2,616評論 2 9