When I see you again(加密原理介紹,代碼實現DES、AES、RSA、Base64、MD5)

来源:http://www.cnblogs.com/mddblog/archive/2016/06/13/5582430.html
-Advertisement-
Play Games

關於網路安全的數據加密部分,本來打算總結一篇博客搞定,沒想到東西太多,這已是第三篇了,而且這篇寫了多次,熬了多次夜,真是again and again。起個名字: 數據加密三部曲 ,前兩部鏈接如下: 1. 整體介紹: "網路安全——數據的加密與簽名,RSA介紹" 2. 編碼與哈希實現: "網路安全— ...


關於網路安全的數據加密部分,本來打算總結一篇博客搞定,沒想到東西太多,這已是第三篇了,而且這篇寫了多次,熬了多次夜,真是again and again。起個名字:數據加密三部曲,前兩部鏈接如下:

  1. 整體介紹:網路安全——數據的加密與簽名,RSA介紹
  2. 編碼與哈希實現:網路安全——Base64編碼、MD5、SHA1-SHA512、HMAC(SHA1-SHA512)哈希
  3. 本篇DES、AES、RSA加密的介紹與實現

github下載地址

https://github.com/mddios/EncryptionTools

代碼提供兩種加解密方法:

一、DES對稱加密

關於DES 3DES加密解密原理不再介紹,現在已經用的不多,如果你的項目還在使用DES加密,還是趕快換吧,換做AES或者更強的非對稱RSA加密。

另外它與AES有很多的相似性,也可以參照AES介紹。下麵是具體的用法。

對"123"加密,密鑰為16進位的3031323334353637(01234567)

使用電腦終端:

echo -n "123" | openssl enc -des-ecb -a -K 3031323334353637

結果:
MV5dUGKtzbM=

代碼加密解密使用:

首先引入頭文件NSString+Encryption.h
/*
 DES加密 key為NSString形式 結果返回base64編碼
 */
- (NSString *)desEncryptWithKey:(NSString *)key;

/*
 DES加密 key為NSData形式 結果返回NSData
 */
- (NSData *)desEncryptWithDataKey:(NSData *)key;

#pragma mark - DES解密

/*
 DES解密,字元串必須為base64格式,key為字元串形式
 */
- (NSString *)desDecryptWithKey:(NSString *)key;

/*
 DES解密
 */
+ (NSData *)desDecryptWithData:(NSData *)data dataKey:(NSData *)key;

二、AES對稱加密

AES是高級加密標準Advanced Encryption Standard的縮寫,有多種模式,下麵介紹使用最多的兩種

ECB(Electronic Code Book,電子密碼本)模式

是一種基礎的加密方式,要加密的數據被分割成分組長度相等的塊(不足補齊,補齊方式下文介紹),然後單獨的一個個組加密,合在一起輸出組成密文。

電腦終端:

echo -n "123" | openssl enc -aes-128-ecb -a -K 30313233343536373839414243444546
加密結果:
0b6ikfq9CQs11aSCnNXIog==

代碼加密解密使用:

首先引入頭文件NSString+Encryption.h

/**
 AES-ECB模式加密
 @param key Hex形式,密鑰支持128 192 256bit,16、24、32位元組,轉換為16進位字元串長度為32、48、64,長度錯誤將拋出異常
 @return 加密結果為base64編碼
 */
- (NSString *)aesECBEncryptWithHexKey:(NSString *)key;

/**
 AES-ECB模式加密
 @param key 字元串形式,密鑰支持128 192 256bit,16、24、32位元組,長度錯誤將拋出異常
 @return 加密結果為base64編碼
 */
- (NSString *)aesECBEncryptWithKey:(NSString *)key;

/**
 AES-ECB模式加密
 @param key 密鑰支持128 192 256bit,16、24、32位元組,長度錯誤將拋出異常
 */
- (NSData *)aesECBEncryptWithDataKey:(NSData *)key;

/*
 ECB模式解密,返回base64編碼
 */
- (NSString *)aesECBDecryptWithHexKey:(NSString *)key;

/*
 ECB模式解密,返回NSData
 */
- (NSData *)aesECBDecryptWithDataKey:(NSData *)key;

CBC(Cipher Block Chaining,加密塊鏈)模式

http://7xs4tc.com1.z0.glb.clouddn.com/cipher01.png

是一種迴圈模式,也將要加密的數據分割為長度相等的組(不足補齊,補齊方式下文介紹),前一個分組的密文和當前分組的明文異或操作後再加密,這樣做的目的是增強破解難度,會比ECB安全一點。但是也因為他們的關聯性,造成以下三個缺點:

  • 不利於並行計算:很明顯第一組完成才能計算第二組然後第三組。。。
  • 誤差傳遞:也是依次傳遞
  • 需要初始化向量IV:第二組根據第一組的結果來加密,那第一組根據誰呢?那就是需要額外提供初始化向量

可以在電腦終端(openssl):

echo -n "123" | openssl enc -aes-128-cbc -a -K 30313233343536373839414243444546 -iv 30313233343536373839414243444546

結果:
5IQJlqxa2e5NGzGqqPpoSw==

代碼加密解密使用:

首先引入頭文件NSString+Encryption.h

/**
 AES-CBC模式加密,預設模式
 @param key Hex形式,密鑰支持128 192 256bit,16、24、32位元組,轉換為16進位字元串長度為32、48、64,長度錯誤將拋出異常
 @param iv 進位字元串形式;初始化向量iv為16位元組。如果為nil,則初始化向量為0
 @return 加密結果為base64編碼
 */
- (NSString *)aesEncryptWithHexKey:(NSString *)key hexIv:(NSString *)iv;

/**
 AES-CBC模式加密,預設模式
 @param key 密鑰支持128 192 256bit,16、24、32位元組,長度錯誤將拋出異常
 @param iv 進位字元串形式;初始化向量iv為16位元組。如果為nil,則初始化向量為0
 @return 加密結果為base64編碼
 */
- (NSString *)aesEncryptWithKey:(NSString *)key iv:(NSString *)iv;

/**
 AES-CBC模式加密,預設模式
 @param data 要加密的數據
 @param key 密鑰支持128 192 256bit,16、24、32位元組,長度錯誤將拋出異常
 @param iv 初始化向量iv為16位元組。如果為nil,則初始化向量為0
 @return 加密結果為NSData形式
 */
- (NSData *)aesEncryptWithDataKey:(NSData *)key dataIv:(NSData *)iv;

/**
 AES-CBC模式解密,要求NSString為base64的結果
 @param key 密鑰支持128 192 256bit,16、24、32位元組,長度錯誤將拋出異常
 @param iv 進位字元串形式;初始化向量iv為16位元組。如果為nil,則初始化向量為0
 */
- (NSString *)aesBase64StringDecryptWithHexKey:(NSString *)key hexIv:(NSString *)iv;

/**
 AES-CBC模式解密
 @param key 密鑰支持128 192 256bit,16、24、32位元組,長度錯誤將拋出異常
 @param iv 初始化向量iv為16位元組。如果為nil,則初始化向量為0
 */
+ (NSData *)aesDecryptWithData:(NSData *)data dataKey:(NSData *)key dataIv:(NSData *)iv;

三、RSA非對稱加密

關於介紹,之前的博客已經給出,具體可以參考:網路安全——數據的加密與簽名,RSA介紹

openssl 生成的密鑰PEM文件為Base64編碼(這裡的Base64格式,長度超過64字元插有換行,生成的私鑰為PKCS#1格式),下麵是具體的openssl生成公私鑰步驟:

  • 1 生成私鑰,1024bit,PKCS1Padding格式,Base64編碼
命令行:openssl genrsa -out rsa_private_key.pem 1024

結果如下:
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDOxoZIsFbFMeR0OWnc/sF5A3Gj0BWsoClQW3BKgvMQ85ZXVCM6
7g6XItl5sSW2EyMaIeQ8tRsM0HI4oCvlOMjSVgdyZmqbUfaZDoDYPW2pDbLqMDr/
o1eKxYpssbAyH6ZDyJeTOEu9yF7XUsIilokzc0D9i+uPc8yp/vLYTPDJEQIDAQAB
AoGAFUMevcy8L2zQ9A6PTzU3Cc2L2u9juyuA9A1i/5Z1jhGuLO6u7Llb8LiZqkTH
/u/61Q4VHRT2YhvxEteNi/WJ2L+1wTZYWbE/NIHBls4dTDt4aiMGUG2y6uBcFPmB
97sjT3ofcOHVZuFc80ktyhVuvx5osB8obZHbjn+3hn/pIF0CQQDx1bollu3XXL08
YJrS1mpB3F/87HXcxDa0dWUoqBRUCPjqC+8SuxaddPK6RFvkb1UyWJNzQ5Mb3OZt
65/sipdDAkEA2uMWf0ukTRhxiEYhZIJDSaERYeaWFU+mc6mC2//Tcvy7hldBe15n
7UQNKWl7DbI3Z7NmuKPa+rWqwASqtBAHGwJAOav7iW1V6Q8fvd9X7MHfczdn2LxX
Wz+bwCti5XA38NZ27fHMoM3nFcPHAu68b1yxl6ESAOHzmihy93HCoLloWwJARodX
j2rTJRhUNMHMLrOedNIWZMJE59cDXk9nX/X9rxZqYi4pZlQUDqqXxxk60j3zhlGT
Lrl1bMUuoLKgQmbLswJAIfv1Vw18YcEexWPBkn5iKufu0Fo7+Z776lDLYP1kNyQZ
eohofAAWYNQvHZ4WTpiIxi2FZ9xIRu+M7smsIs0h2g==
-----END RSA PRIVATE KEY-----
  • 2 根據上面的私鑰生成公鑰
命令行:openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

結果如下:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOxoZIsFbFMeR0OWnc/sF5A3Gj
0BWsoClQW3BKgvMQ85ZXVCM67g6XItl5sSW2EyMaIeQ8tRsM0HI4oCvlOMjSVgdy
ZmqbUfaZDoDYPW2pDbLqMDr/o1eKxYpssbAyH6ZDyJeTOEu9yF7XUsIilokzc0D9
i+uPc8yp/vLYTPDJEQIDAQAB
-----END PUBLIC KEY-----
  • 3 將私鑰生成pkcs8格式,可在iOS工程中直接使用
openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

結果:
-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAM7GhkiwVsUx5HQ5
adz+wXkDcaPQFaygKVBbcEqC8xDzlldUIzruDpci2XmxJbYTIxoh5Dy1GwzQcjig
K+U4yNJWB3JmaptR9pkOgNg9bakNsuowOv+jV4rFimyxsDIfpkPIl5M4S73IXtdS
wiKWiTNzQP2L649zzKn+8thM8MkRAgMBAAECgYAVQx69zLwvbND0Do9PNTcJzYva
72O7K4D0DWL/lnWOEa4s7q7suVvwuJmqRMf+7/rVDhUdFPZiG/ES142L9YnYv7XB
NlhZsT80gcGWzh1MO3hqIwZQbbLq4FwU+YH3uyNPeh9w4dVm4VzzSS3KFW6/Hmiw
HyhtkduOf7eGf+kgXQJBAPHVuiWW7ddcvTxgmtLWakHcX/zsddzENrR1ZSioFFQI
+OoL7xK7Fp108rpEW+RvVTJYk3NDkxvc5m3rn+yKl0MCQQDa4xZ/S6RNGHGIRiFk
gkNJoRFh5pYVT6ZzqYLb/9Ny/LuGV0F7XmftRA0paXsNsjdns2a4o9r6tarABKq0
EAcbAkA5q/uJbVXpDx+931fswd9zN2fYvFdbP5vAK2LlcDfw1nbt8cygzecVw8cC
7rxvXLGXoRIA4fOaKHL3ccKguWhbAkBGh1ePatMlGFQ0wcwus5500hZkwkTn1wNe
T2df9f2vFmpiLilmVBQOqpfHGTrSPfOGUZMuuXVsxS6gsqBCZsuzAkAh+/VXDXxh
wR7FY8GSfmIq5+7QWjv5nvvqUMtg/WQ3JBl6iGh8ABZg1C8dnhZOmIjGLYVn3EhG
74zuyawizSHa
-----END PRIVATE KEY-----

可以在終端對"123"RSA加密,由於使用PKCS#1生成隨機碼,所以每次加密結果會不一樣

echo "123" | openssl rsautl -encrypt  -inkey rsa_public_key.pem -pubin | Base64

加密結果(Base64):
ZDBtICMxy2JHg6QDqolyAeqBRMseqJQ33tYQRE26c69/dGlS3TJ2xzMRZlsww+NnQH48KVthyCJ6nIhgAvhmAOaG+MvMqhZT/G180euH3OfLX8/VcIWqelxm8IYzA3NRD8n2jWbWoxZHh8Sp3n+YM7vor+8Q3SsFXMuurwT+xPI=

常式RSA加密使用了第三方框架,鏈接如下:https://github.com/ideawu/Objective-C-RSA,在使用時公鑰可以直接使用,私鑰需要使用pkcs8格式。公私鑰可以加-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----,也可以不加,程式會自動處理。

四、實際使用

選擇哪種演算法當然是根據自己的需求來定

  • 如果不是關鍵的數據可以使用DES加密,或者Base64編碼不直接看到數據即可,這樣速度快
  • 稍微重要的數據,可以用AES加密,一定要保護好密鑰
  • 關於錢、用戶登陸之類的比較重要,數據量也少,可以使用RSA加密

另外,我們也可以對稱加密和非對稱加密結合使用,對數據進行AES或DES加密,AES或DES的密鑰隨機生成,並使用RSA將其加密。對方收到信息後,先RSA解密得到密鑰,然後在解密得到加密的數據。這樣的話,隨機演算法就比較重要。

五、關於Padding

  • 數據長度

AES和DES在ECB或者CBC模式下,要加密的數據必須是分組長度的整數倍,比如AES是128位16位元組,而DES是64位8位元組,那麼加密數據必須是16(AES)或者8(DES)的整數倍,如果不是那麼就需要填充(pad)。

  • 密鑰長度

不像數據長度必須是block的整數倍,密鑰長度是固定的。

AES有三種:128、192、256bit

pad的方式有很多種,而且你也可以自定義,用的比較多的有PKCS7Padding、PKCS1Padding和PKCS5Padding。

  • PKCS7Padding:用十六進位0x07來填充,下麵為一個簡單的實現方法(其實很多加密工具已經實現,這裡只是舉個例子)
// plainData為要加密的數據,“16”是block大小
while (plainData.length % 16 != 0) {
    // PKCS7Padding模式
    Byte PKCS7Pad = 0x07;
    [plainData appendData:[[NSData alloc] initWithBytes:&PKCS7Pad length:1]];
}
  • PKCS5Padding:稍麻煩一點,比如需要填充7個位元組就填充0x07,需要填充6個位元組就是0x06。。。需要填充1個位元組就是0x01

加解密雙方必須使用相同的方式,不然解密就會失敗。

關於電腦終端Openssl加密解密命令

對"123"加密,密鑰為"30313233343536373839414243444546"(16進位,對應ASCII碼為0~F),初始化向量為"30313233343536373839414243444546"(16進位,對應ASCII碼為0~F)

echo -n "123" | openssl enc -aes-128-cbc -a -A -K 30313233343536373839414243444546 -iv 30313233343536373839414243444546

下麵對參數做說明:

  • echo -n "123" |:輸出123且不換行,“|”是管道符號,將前面的輸出作為後面的輸入,即"123"作為後面要加密的數據。openssl命令是對文件加密,這樣做好處是直接可以對字元串加密。
  • enc:對稱加密
  • -aes-128-cbc:演算法名字模式
  • -a:加密結果進行base64編碼
  • -A:輸出不換行,預設情況下,base64編碼結果換行
  • -K:後面跟密鑰,16進位形式
  • -iv:初始化向量(CBC模式有)

另外,預設pad為PKCS5Padding

如果想對openssl有更詳細的瞭解,可以參考 趙春平寫的《Openssl編程》裡面有很多實用東西,另外也將書的pdf格式上傳到了github工程裡面,鏈接見文章最後


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在學關係型資料庫相關,MySQL 和 Postgre,捎帶著學了 PHP,為了練手這幾天就忙著自己搭博客,項目部署在某雲上,該雲算是良心,給的空間自己搭博客用足夠了。本來想著每日一bo的,所以有的時候實在來不及就只能隔天更新了。以後儘量發點東西出來,等博客搭完寫一寫 SQL 資料庫基礎相關的分享 ...
  • ...
  • js斷點調試心得 雖然網上已經有多的數不清的調試教程了,但仍然沒有發現哪篇文章寫的通俗易懂,索性自己嘗試寫寫自己的一些使用習慣或者說是心得,希望對那些還不是很懂得使用斷點調試的孩子有一些幫助(大神請無視~)。 1.斷點調試是啥?難不難? 斷點調試其實並不是多麼複雜的一件事,簡單的理解無外呼就是打開瀏 ...
  • 在有全屏側滑的情況下,頁面上有個slider需要左右滑動的時候,經常在滑動slider的時候頁面也跟著滑動 解決辦法一:關閉當前頁面的全屏側滑,開啟系統側滑 self.fd_interactivePopDisabled = YES; //關閉全屏側滑 self.navigationControlle ...
  • 代碼: RootViewController.h RootViewController.m ...
  • IOS之網路數據下載和JSON解析 簡介 在本文中筆者將要給大家介紹IOS中如何利用URLConnection從網路上下載數據,如何解析下載下來的JSON數據格式,以及如何顯示數據和圖片的一部下載顯示 涉及到的知識點: 1.URLConnection非同步下載和封裝 2.JSON格式和JSON格式解析 ...
  • Android開發的過程中,我想要通過代碼來實現數據連接的開啟和關閉,最初我將目標鎖定為ConnectivityManager類,但是在翻閱了Android官方API後並沒有找到相關的方法,如圖1。 圖1 但是據說Android的一些類的某些方法的API是非公開的,所以我又做瞭如下嘗試:獲得Conn ...
  • 效果 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...