c++ openssl 使用 DES(數據加密標準)進行加密和解密的基本操作

使用 DES(數據加密標準)進行加密和解密的基本操作,重點展示了 ECB 和 CBC 模式,并且通過篡改密文的方式來進行攻擊。下面是對每個部分的詳細解析。

1. 結構體 Slip

struct Slip
{char from[16] = { 0 };  // 交易的發起者(例如 A => B)char to[16] = { 0 };    // 交易的接收者(例如 B => A)long long amount = 0;    // 交易金額
};
  • Slip 結構體存儲了三部分數據:發起者 (from)、接收者 (to) 和交易金額 (amount)。
  • 這段數據需要加密并在后續的操作中進行篡改。

2. 全局變量:DES 密鑰和密鑰調度

static const_DES_cblock key = "1234567";
static DES_key_schedule key_sch;
  • key 是一個 8 字節的 DES 密鑰,硬編碼為 “1234567”。
  • key_sch 是 DES 密鑰調度,它將密鑰轉換為 DES 算法可用的形式。

3. 加密函數 EnSlip

void EnSlip(const Slip& s, unsigned char* out, int &out_size)
{int size = sizeof(s);auto p = (const unsigned char*)&s;auto o = out;DES_set_key(&key, &key_sch);for (int i = 0; i < size; i += 8){DES_ecb_encrypt((const_DES_cblock*)p, (DES_cblock*)o, &key_sch, DES_ENCRYPT);p += 8;o += 8;out_size += 8;}
}
  • EnSlip 負責對 Slip 數據進行加密。
  • 以 8 字節為單位處理 Slip 結構體的數據(DES 是塊加密算法,每次處理 8 字節)。
  • DES_ecb_encrypt 用于在 ECB 模式下加密數據。
  • 每次加密后,將輸入數據指針 p 和輸出數據指針 o 移動 8 字節。

4. 解密函數 DeSlip

void DeSlip(const unsigned char* in, int size, Slip& s)
{auto p = (const unsigned char*)in;auto o = (unsigned char*)&s;DES_set_key(&key, &key_sch);for (int i = 0; i < size; i += 8){DES_ecb_encrypt((const_DES_cblock*)p, (DES_cblock*)o, &key_sch, DES_DECRYPT);p += 8;o += 8;}
}
  • DeSlip 用于解密加密后的 Slip 數據。
  • 它與 EnSlip 類似,不過使用了 DES_DECRYPT 進行解密。

5. 篡改密文函數 AttackSlip

void AttackSlip(unsigned char* out)
{// 修改密文:交換 from 和 tounsigned char tmp[1024] = { 0 };memcpy(tmp, out, 16);            // 復制 from 部分memcpy(out, out + 16, 16);       // 將 to 部分放到 from 的位置memcpy(out + 16, tmp, 16);       // 將原來的 from 部分放到 to 的位置
}
  • AttackSlip 是一個簡單的篡改密文的攻擊方法,它交換了加密后的 from 和 to 字段。
  • 這種攻擊顯示了 ECB 模式的弱點,因為 ECB 模式在加密相同的數據塊時會生成相同的密文,攻擊者可以直接修改密文。

6. CBC 模式的加密函數 EnSlipCBC

void EnSlipCBC(const Slip& s, unsigned char* out, int& out_size)
{int size = sizeof(s);auto p = (const unsigned char*)&s;auto o = out;DES_set_key(&key, &key_sch);DES_cblock iv = { 0 };  // 初始化向量,設置為全零out_size = size;if (size % 8 != 0){// 補充0到 8 的倍數out_size = size + (8 - size % 8);}DES_cbc_encrypt(p, o, sizeof(s), &key_sch, &iv, DES_ENCRYPT);
}
  • EnSlipCBC 使用 CBC 模式對 Slip 數據進行加密。
  • 如果數據長度不是 8 的倍數,則會填充零(補充到 8 字節的倍數)。
  • 使用 DES_cbc_encrypt 進行加密,其中需要提供初始化向量(IV)。在此處,IV 被初始化為全零。

7. CBC 模式的解密函數 DeSlipCBC

void DeSlipCBC(const unsigned char* in, int size, Slip& s)
{DES_cblock iv = { 0 };  // 初始化向量DES_set_key(&key, &key_sch);DES_cbc_encrypt(in, (unsigned char*)&s, size, &key_sch, &iv, DES_DECRYPT);
}
  • DeSlipCBC 用于解密 CBC 模式加密的數據。
  • 它使用與加密相同的 IV(此處為全零),并使用 DES_cbc_encrypt 解密數據。

8. 主函數 main

int main(int argc, char* argv[])
{unsigned char out[1024] = { 0 };int out_size = 0;Slip  s1 = { "USER_A", "USER_B", 10000 };cout << "s1 from:" << s1.from << endl;cout << "s1 to:" << s1.to << endl;cout << "s1 amount:" << s1.amount << endl;EnSlip(s1, out, out_size);cout << "En: " << out_size << " | " << out << endl;// 攻擊密文AttackSlip(out);Slip s2;DeSlip(out, out_size, s2);cout << "s2 from:" << s2.from << endl;cout << "s2 to:" << s2.to << endl;cout << "s2 amount:" << s2.amount << endl;Slip s3;EnSlipCBC(s1, out, out_size);// 攻擊密文AttackSlip(out);DeSlipCBC(out, out_size, s3);cout << "s3 from:" << s3.from << endl;cout << "s3 to:" << s3.to << endl;cout << "s3 amount:" << s3.amount << endl;getchar();return 0;
}
  • 在主函數中,首先創建了一個交易數據 s1(發起者 “USER_A”、接收者 “USER_B”、金額 10000)。
  • 對 s1 使用 ECB 模式進行加密,并輸出加密后的密文。
  • 然后,調用 AttackSlip 攻擊密文,交換 from 和 to 字段,并解密密文。
  • 同樣,對 s1 使用 CBC 模式進行加密,攻擊密文后,再使用 CBC 解密。

9. 攻擊分析

  • ECB 模式的漏洞: 因為 ECB 模式對每個數據塊獨立加密,導致相同的數據塊加密后密文相同,攻擊者可以直接修改密文(例如交換 from 和 to 字段),從而篡改交易數據。
  • CBC 模式的優勢: 雖然 CBC 模式對每個數據塊進行依賴加密,增強了安全性,但在此代碼中并沒有使用認證機制,攻擊者仍然可以通過篡改密文的一部分(如改變密文中的塊順序)影響解密結果。

完整代碼

#include <iostream>
#include <openssl/des.h>
#include <cstring>
using namespace std;// 交易數據
struct Slip
{char from[16] = {0}; // A=>B 10000char to[16] = {0};   // 篡改為 B=>A 10000long long amount = 0;
};
static const_DES_cblock key = "1234567";
static DES_key_schedule key_sch;void EnSlip(const Slip &s, unsigned char *out, int &out_size)
{int size = sizeof(s);auto p = (const unsigned char *)&s;auto o = out;DES_set_key(&key, &key_sch);for (int i = 0; i < size; i += 8){DES_ecb_encrypt((const_DES_cblock *)p, // 輸入數據(DES_cblock *)o,       // 輸出數據&key_sch,              // 秘鑰DES_ENCRYPT            // 1 加密);p += 8;o += 8;out_size += 8;}// 補充數據。。。
}void DeSlip(const unsigned char *in, int size, Slip &s)
{auto p = (const unsigned char *)in;auto o = (unsigned char *)&s;DES_set_key(&key, &key_sch);for (int i = 0; i < size; i += 8){DES_ecb_encrypt((const_DES_cblock *)p, (DES_cblock *)o, &key_sch, DES_DECRYPT);p += 8;o += 8;}
}void AttackSlip(unsigned char *out)
{// 修改密文 from 和to 對調unsigned char tmp[1024] = {0};// frommemcpy(tmp, out, 16);// to copy frommemcpy(out, out + 16, 16);memcpy(out + 16, tmp, 16);
}void EnSlipCBC(const Slip &s, unsigned char *out, int &out_size)
{int size = sizeof(s);auto p = (const unsigned char *)&s;auto o = out;DES_set_key(&key, &key_sch);DES_cblock iv = {0}; // 初始化向量out_size = size;// 數據如果不是8的倍數,會補0if (size % 8 != 0){// 補充0out_size = size + (8 - size * 8);}DES_cbc_encrypt(p,         // 輸入o,         // 輸出sizeof(s), // 輸入數據的大小&key_sch,  // 秘鑰&iv,       // 初始化向量 DES_cbc_encrypt 調用后值不變// DES_ncbc_encrypt 保存上次的值DES_ENCRYPT // 加密);
}
void DeSlipCBC(const unsigned char *in, int size, Slip &s)
{DES_cblock iv = {0}; // 初始化向量DES_set_key(&key, &key_sch);// 如果補0了 解密后無法知道實際大小,需要用戶存儲原數據大小DES_cbc_encrypt(in, (unsigned char *)&s, size, &key_sch, &iv, DES_DECRYPT);
}
int main(int argc, char *argv[])
{unsigned char out[1024] = {0};int out_size = 0;Slip s1 = {"USER_A", "USER_B", 10000};cout << "s1 from:" << s1.from << endl;cout << "s1 to:" << s1.to << endl;cout << "s1 amount:" << s1.amount << endl;EnSlip(s1, out, out_size);cout << "En:" << out_size << "|" << out << endl;// 攻擊密文AttackSlip(out);Slip s2;DeSlip(out, out_size, s2);cout << "s2 from:" << s2.from << endl;cout << "s2 to:" << s2.to << endl;cout << "s2 amount:" << s2.amount << endl;Slip s3;EnSlipCBC(s1, out, out_size);// 攻擊密文AttackSlip(out);DeSlipCBC(out, out_size, s3);cout << "s3 from:" << s3.from << endl;cout << "s3 to:" << s3.to << endl;cout << "s3 amount:" << s3.amount << endl;getchar();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86369.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86369.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86369.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenWrt:使用ALSA實現邊錄邊播

ALSA是Linux系統中的高級音頻架構&#xff08;Advanced Linux Sound Architecture&#xff09;。目前已經成為了linux的主流音頻體系結構&#xff0c;想了解更多的關于ALSA的知識&#xff0c;詳見&#xff1a;http://www.alsa-project.org 在內核設備驅動層&#xff0c;ALSA提供…

【.net core】天地圖坐標轉換為高德地圖坐標(WGS84 坐標轉 GCJ02 坐標)

類文件 public static class WGS84ToGCJ02Helper {// 定義一些常量private const double PI 3.14159265358979324;private const double A 6378245.0;private const double EE 0.00669342162296594323;// 判斷坐標是否在中國范圍內&#xff08;不在國內則不進行轉換&#x…

Matlab自學筆記五十七:符號運算、可變精度運算、雙精度浮點型運算,三種運算精度的概念、比較、選擇和應用

1.可變精度算術的概念 默認的&#xff0c;Matlab雙精度浮點數使用16位數字精度&#xff0c;而符號數學工具箱的vpa函數&#xff0c;提供了無限大的可變精度&#xff0c;它默認使用32位數字精度&#xff0c;32位指的是有效數字的位數&#xff1b; 2.具體用法 程序示例&#x…

由匯編代碼確定switch語句

int switch2(int x) {int result0;switch(x){/* switch語句主體缺失 */}return result; }在編譯函數時&#xff0c;GCC為程序的初始部分以及跳轉表生成了如下匯編代碼。 1 MOVL 8(%ebp), %eax ;x位于相對于寄存器%ebp偏移量為8的地方。 2 ADDL $2, %eax …

java 使用HanLP 入門教程

1. 安裝 HanLP Maven 依賴 <dependency><groupId>com.hankcs</groupId><artifactId>hanlp</artifactId><version>portable-1.8.4</version> <!-- 最新版本請查看官網 --> </dependency>注意&#xff1a;portable 版本…

vm虛擬機添加虛擬機無反應,獲取所有權

問題描述 虛擬機忘記關機&#xff0c;就把電腦關了&#xff0c;早上打開用不了了&#xff0c;重新添加&#xff0c;也沒反應&#xff0c;獲取所有權后就沒了 問題解決 將虛擬機文件目錄下的.lck文件夾&#xff0c;刪除&#xff0c;或者改個名&#xff0c;我是改為了.backup方…

為何選擇Spring框架學習設計模式與編碼技巧?

&#x1f4cc; 結論先行 推薦項目&#xff1a;Spring Framework 推薦理由&#xff1a;設計模式覆蓋全面 編碼技巧教科書級實現 Java 生態基石地位 &#x1f3c6; 三維度對比分析 維度SpringMyBatisXXL-JOB設計模式??????????代碼抽象??????????生態價…

MySQL 索引:聚集索引與二級索引

在數據庫性能優化的征途中&#xff0c;索引無疑扮演著至關重要的角色。正確理解和使用索引&#xff0c;能夠顯著提升查詢效率&#xff0c;為應用帶來絲滑般的操作體驗。今天&#xff0c;我們將深入 MySQL 的心臟&#xff0c;重點探討 InnoDB 存儲引擎中兩種核心的索引類型&…

【Elasticsearch】映射:詳解 _source store 字段

映射&#xff1a;詳解 _source & store 字段 1._source 字段1.1 特點1.2 示例 2.store 字段2.1 特點2.2 示例 3.兩者對比3.1 使用建議3.2 實際應用示例 1._source 字段 _source 是 Elasticsearch 中一個特殊的元字段&#xff0c;它存儲了文檔在索引時的原始 JSON 內容。 …

新建網站部署流程

1. 新建 Node 服務&#xff0c;指定端口并代理前端靜態資源 操作步驟&#xff1a; 初始化 Node 項目mkdir my-website && cd my-website npm init -y npm install express創建 app.js&#xff08;示例代碼&#xff09;const express require(express); const app e…

時序數據庫IoTDB結合SeaTunnel實現高效數據同步

益、基本概念介紹 1.1 Apache IoTDB Apache IoTDB是一款專為工業物聯網設計的時序數據庫管理系統&#xff0c;集數據收集、存儲、管理與分析于一體&#xff0c;滿足海量數據存儲、高速讀取及復雜數據分析需求。其架構包括時序文件&#xff08;TsFile&#xff09;、數據庫引擎…

k8s業務程序聯調工具-KtConnect

概述 原理 工具作用是建立了一個從本地到集群的單向VPN&#xff0c;根據VPN原理&#xff0c;打通兩個內網必然需要借助一個公共中繼節點&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;簡化了建立連接的過程&#xff0c;apiserver間接起到了中繼節…

RFID推動新能源汽車零部件生產系統管理應用案例

RFID推動新能源汽車零部件生產系統管理應用案例 一、項目背景 新能源汽車零部件場景 在新能源汽車零部件生產領域&#xff0c;電子冷卻水泵等關鍵部件的裝配溯源需求日益增長。傳統 RFID 溯源方案采用 “網關 RFID 讀寫頭” 模式&#xff0c;存在單點位單獨頭溯源、網關布線…

C#封裝HttpClient:HTTP請求處理最佳實踐

C#封裝HttpClient&#xff1a;HTTP請求處理最佳實踐 在現代的.NET應用程序開發中&#xff0c;與外部服務進行HTTP通信是一項常見需求。HttpClient作為.NET框架中處理HTTP請求的核心組件&#xff0c;為我們提供了強大而靈活的API。然而&#xff0c;直接使用原生的HttpClient可能…

【Redis/2】核心特性、應用場景與安裝配置

文章目錄 一、初識 Redis1.1 Redis 概述1. Redis 簡介2. Redis 的發展歷程 1.2 Redis 核心特性1. 高性能2. 豐富的數據類型3. 持久化4. 原子操作5. 主從復制6. 高可用性與分布式7. 內存存儲與低延遲8. 靈活的過期策略9. 事務支持10. 簡單的 API總結 1.3 Redis 應用場景Redis 適…

AI大模型在測試領域應用案例拆解:AI賦能的軟件測試效能躍遷的四大核心引擎(順豐科技)

導語 5月份QECon深圳大會已經結束&#xff0c;繼續更新一下案例拆解&#xff0c;本期是來自順豐科技。 文末附完整版材料獲取方式。 首先來看一下這個案例的核心內容&#xff0c;涵蓋了測四用例設計、CI/CD輔助、測試執行、監控預警四大方面&#xff0c;也是算大家比較熟悉的…

【HTML】HTML 與 CSS 基礎教程

作為 Java 工程師&#xff0c;掌握 HTML 和 CSS 也是需要的&#xff0c;它能讓你高效與前端團隊協作、調試頁面元素&#xff0c;甚至獨立完成簡單頁面開發。本文將用最簡潔的方式帶你掌握核心概念。 一、HTML&#xff0c;網頁骨架搭建 核心概念&#xff1a;HTML通過標簽定義內…

Redis 集群批量刪除key報錯 CROSSSLOT Keys in request don‘t hash to the same slot

Redis 集群報錯 CROSSSLOT Keys in request dont hash to the same slot 的原因及解決方案 1. 錯誤原因 在 Redis 集群模式下&#xff0c;數據根據 哈希槽&#xff08;Slot&#xff09; 分散存儲在不同的節點上&#xff08;默認 16384 個槽&#xff09;。當執行涉及多個 key …

.Net Framework 4/C# LINQ*

一、什么是 LINQ LINQ 是一種在 C# 等編程語言中集成的查詢功能&#xff0c;它允許開發者使用編程語言本身的語法進行數據查詢&#xff0c;而不是嵌入式的字符串 SQL 語句。LINQ 查詢可以應用于對象、XML 和數據庫等多種數據源。 二、LINQ 查詢的基本構成 LINQ 查詢通常包含以…

【docker】容器技術如何改變軟件開發與部署格局

在當今數字化時代&#xff0c;軟件開發與部署的效率和靈活性至關重要。就像古人云&#xff1a;“工欲善其事&#xff0c;必先利其器。”Docker 作為一款強大的容器技術&#xff0c;正如同軟件開發領域的一把利器&#xff0c;極大地改變了應用的開發、交付和運行方式。本文將深入…