iOS小技能:RSA簽名、驗籤、加密、解密的原理

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第2天,點選檢視活動詳情

引言

  1. 對稱加密演算法:資料傳送方將明文和金鑰一起經過特殊加密演算法處理成密文後,將它傳送出去。接收方收到密文後,若想解讀原文,則需要使用加密用到的相同金鑰及相同演算法的逆演算法對密文進行解密,才能使其恢復成原文。

    最典型的問題就是如何同步這個金鑰,同步過程如果在公網上,不進行加密是可以抓包拿到的,那麼這裡就遇到了要對金鑰加密的問題。

    常見的對稱加密演算法有 AES、DES、Blowfish

  2. 非對稱加密演算法:如果用公鑰進行加密,只有用對應的私鑰才能解密;如果用私鑰進行加密,只有用對應的公鑰才能解密。比如,私鑰簽名、公鑰驗籤;公鑰加密、私鑰解密。

    通常公鑰是公開的,可能同時多人持有。

非對稱加密演算法實現機密資訊的交換過程為:甲方生成一對金鑰並將其中一個作為公鑰向其他方公開;得到該公鑰的乙方使用該金鑰對機密資訊進行加密後傳送給甲方;甲方再用自己的另一個專用金鑰對加密後的資訊進行解密。

I RSA演算法流程

RSA是最有名的非對稱加密演算法,公鑰和私鑰之間是基於數論知識生成的。

1.1 演算法原理

數論知識:給出兩個素數,很容易將它們相乘,然而給出它們的乘積,想得到這兩個素數就顯得尤為困難。

RSA加密演算法的原理是對一極大整數做因數分解的困難性來保證安全性,如果能夠解決大整數(比如幾百位的整數)分解的快速方法,那麼 RSA 演算法將輕易被破解。

非對稱加密隨著金鑰變長,安全性上升的同時效能也會有所下降。

RSA加密對明文的長度有所限制,規定需加密的明文最大長度=金鑰長度-11(單位是位元組,即byte),所以在加密和解密的過程中需要分塊進行。

而金鑰預設是1024位,即1024位/8位-11=128-11=117位元組。所以預設加密前的明文最大長度117位元組,解密密文最大長度為128字。

那麼為啥兩者相差11位元組?是因為RSA加密使用到了填充模式(padding),即內容不足117位元組時會自動填滿,用到填充模式自然會佔用一定的位元組,而且這部分位元組也是參與加密的。

1.2 公鑰和私鑰的生成

步驟: 1. 準備兩個非常大的素數 p和 q(轉換成二進位制後,或者更多位數,位數越多越難破解)。 2. 利用字串模擬計算大素數 p和q的乘積 n=pq。 3. 同樣方法計算 m=(p-1)(q-1),這裡的m 為n 的尤拉函式; 4. 找到一個數e(1<e<m) ,滿足 gcd(m,e)=1(即 e 和 m 互素) 5. 計算e 在模m 域上的逆元d (即滿足 ed mod m=1) 6. (n,e) 為公鑰,(n,d) 為私鑰;

需要的檔案(iOS專用): 由rsa_private_key.pem生成csr -> 生成crt -> 生成der -> 生成p12

```bash ios ==> rsacert.der rsa加密、sha驗籤 ios ==> p.p12 rsa解密、sha加簽

```

RSA金鑰生成命令:

  1. 建立整數請求: openssl>req -new -key rsa_private_key.pem -out rsacert.csr

  2. 生成整數並簽名,10年有效期: openssl>x509 -req -days 3650 -in rsacert.csr -signkey rsa_private_key.pem -out rsacert.crt

  3. 轉換格式:將 PEM 格式檔案轉換成 DER 格式 (公鑰) openssl>x509 -outform der -in rsacert.crt -out rsacert.der

  4. 匯出P12檔案 (私鑰) openssl>pkcs12 -export -out p.p12 -inkey rsa_private_key.pem -in rsacert.crt

注意:“>”符號後面的才是需要輸入的命令。

1.3 RSA 加密

對於明文x ,用公鑰 (n,e) 對x 加密的過程,就是將x 轉換成數字(字串的話取其 ASCII碼、base64b編碼或者 unicode 值),然後通過冪取模計算出密文y 。

1.4 RSA 解密

對於密文y ,用私鑰(n,d) 對y進行解密,和加密類似,同樣是計算冪取模;

1.5 RSA加密、簽名區別

加密和簽名都是為了安全性考慮,加密是為了防止資訊被洩露,而簽名是為了防止資訊被篡改。

1.6 RSA簽名的過程

  1. A生成一對金鑰(公鑰和私鑰),私鑰不公開,A自己保留。公鑰公開,任何人可以獲取。
  2. A用自己的私鑰對訊息加簽,形成簽名sign,並將加簽的訊息和訊息本身一起傳遞給B。
  3. B收到訊息後,在獲取A的公鑰進行驗籤,如果驗簽出來的內容與訊息本身一致,證明訊息是A回覆的。

II 程式碼實現

2.1 RSA簽名演算法和加密演算法的實現

https://blog.csdn.net/z929118967/article/details/126866456

2.2 請求引數按照ASCII碼從小到大排序

iOS 安全規範指南之【對請求引數進行簽名】請求引數按照ASCII碼從小到大排序、拼接、加密(採用遞迴的方式進行實現)應用案例:條碼支付綜合前置平臺申請退款

demo地址:https://download.csdn.net/download/u011018979/15483107

  1. demo 陣列用[]表示,物件(字典)用{} 表示進行排序拼接。
  2. 陣列排序可選,陣列內部,只對字串元素進行排序,並不與字典key參與排序。 字典和陣列獨立排序

———————————————— 版權宣告:本文為CSDN博主「iOS逆向」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請>附上原文出處連結及本宣告。 原文連結:https://blog.csdn.net/z929118967/article/details/108195721

see also

公號:iOS逆向

相關關鍵詞:EncryptsignRSA