20.3 OpenSSL 對稱AES加解密演算法

来源:https://www.cnblogs.com/LyShark/archive/2023/10/30/17797583.html
-Advertisement-
Play Games

AES演算法是一種對稱加密演算法,全稱為高級加密標準(Advanced Encryption Standard)。它是一種分組密碼,以`128`比特為一個分組進行加密,其密鑰長度可以是`128`比特、`192`比特或`256`比特,因此可以提供不同等級的安全性。該演算法採用了替代、置換和混淆等技術,以及多... ...


AES演算法是一種對稱加密演算法,全稱為高級加密標準(Advanced Encryption Standard)。它是一種分組密碼,以128比特為一個分組進行加密,其密鑰長度可以是128比特、192比特或256比特,因此可以提供不同等級的安全性。該演算法採用了替代、置換和混淆等技術,以及多輪加密和密鑰擴展等機制,使得其加密效果優秀,安全性高,被廣泛應用於各種領域中,如數據加密、文件加密、網路安全等。

AES演算法加密和解密使用的密鑰是相同的,該演算法加密和解密速度較快,適用於對大量數據進行加密解密的場景。在實際應用中,通常採用混合加密方式,即使用RSA演算法加密對稱加密演算法中的密鑰,再使用對稱加密演算法加密數據,以保證數據的機密性和加密解密的效率。

AES演算法常用兩種加密模式,即CBC和ECB模式,它們分別具有不同的優缺點。

  • ECB(Electronic Codebook,電子密碼本)模式是最簡單的分組密碼工作模式,將每個明文塊獨立加密,同樣的密鑰加密同樣的明文塊得到的密文也是一樣的,因此容易被攻擊者利用重覆的密文進行分析破解。ECB模式加密效率高,適用於短報文加密,但不適用於長報文加密。

  • CBC(Cipher Block Chaining,密碼塊鏈)模式是一種分組密碼工作模式,先將明文分組,然後對每個分組進行加密,加密時使用上一塊密文作為輸入,因此相同的明文塊在不同位置上得到的密文是不同的,可以防止被攻擊者利用重覆的密文進行分析破解。CBC模式加密效率較低,但適用於長報文加密,因為不同的明文塊之間互相影響,增加了安全性。

在實際應用中,通常採用CBC模式進行加密,因為它比ECB模式更安全,但加密效率較低。此外,還有其他的加密模式,如CFB、OFB、CTR等,不同的加密模式適用於不同的場景,需要根據實際需求進行選擇。

OpenSSL庫提供了對AES加密的支持,但在使用時讀者還是需要自行封裝一些通用加解密函數,如下代碼片段是筆者常用的一些函數總結,其中aes_cbc_encrypt函數用於使用CBC模式對特定字元串加密,aes_cbc_decrypt則使用CBC模式對字元串進行解密,第二個函數AES函數則是使用OpenSSL庫預設的加解密函數二次封裝實現的。

#include <iostream>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/pem.h>

extern "C"
{
#include <openssl/applink.c>
}

#pragma comment(lib,"libssl_static.lib")
#pragma comment(lib,"libcrypto.lib")

// CBC模式加密
int aes_cbc_encrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
        return 0;

    unsigned char iv[AES_BLOCK_SIZE];
    for (int i = 0; i < AES_BLOCK_SIZE; ++i)
        iv[i] = 0;

    AES_KEY aes;
    if (AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }
    int len = strlen(in);
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_ENCRYPT);
    return 1;
}

// CBC模式解密
int aes_cbc_decrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
        return 0;

    // 加密的初始化向量
    unsigned char iv[AES_BLOCK_SIZE];

    // iv一般設置為全0
    for (int i = 0; i < AES_BLOCK_SIZE; ++i)
        iv[i] = 0;

    AES_KEY aes;
    if (AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }
    int len = strlen(in);
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT);
    return 1;
}

// 將加密與解密整合在一起
void AES(unsigned char* InBuff, unsigned char* OutBuff, unsigned char* key, char* Type)
{
    if (strcmp(Type, "encode") == 0)
    {
        AES_KEY AESEncryptKey;
        AES_set_encrypt_key(key, 256, &AESEncryptKey);
        AES_encrypt(InBuff, OutBuff, &AESEncryptKey);
    }
    else if (strcmp(Type, "decode") == 0)
    {
        AES_KEY AESDecryptKey;
        AES_set_decrypt_key(key, 256, &AESDecryptKey);
        AES_decrypt(InBuff, OutBuff, &AESDecryptKey);
    }
}

有了上述演算法封裝,接下來筆者將依次演示這幾種不同的加密函數是如何被應用的,首先簡單介紹一下aes_cbc_encryptaes_cbc_decrypt這兩個函數都是自己封裝的AES加解密演算法,這兩個演算法參數傳遞保持一致,第一個參數都是指定需要加密的緩衝區,第二個參數則是指定加密所使用的key,第三個參數是處理後的結果。

int main(int argc, char* argv[])
{
  char szBuffer[1024] = "hello lyshark";
  char szDst[1024] = { 0 };
  char szSrc[1024] = { 0 };

  // 計算一串密鑰
  char key[AES_BLOCK_SIZE] = { 0 };
  for (int x = 0; x < AES_BLOCK_SIZE; x++)
  {
    key[x] = 32 + x;
  }

  // AES加密
  if (aes_cbc_encrypt(szBuffer, key, szDst) != 0)
  {
    std::cout << "加密後長度: " << strlen(szDst) << std::endl;
  }

  // AES解密
  if (aes_cbc_decrypt(szDst, key, szSrc) != 0)
  {
    std::cout << "解密內容: " << szSrc << std::endl;
  }

  system("pause");
  return 0;
}

上述代碼片段則是通過AES實現對數據加解密處理的功能,如下是這段代碼的輸出效果;

第二種調用方式是採用API實現,其中的AES函數,通過AES_set_encrypt_key設置加密密鑰,並直接調用AES_encrypt實現數據加密,反之,通過AES_set_decrypt_key設置解密密鑰,並調用AES_decrypt解密,這段代碼調用方式如下所示;

int main(int argc, char* argv[])
{
  unsigned char Buffer[1024] = "hello lyshark";
  unsigned char EncodeBuf[1024] = { 0 };
  unsigned char DecodeBuf[1024] = { 0 };
  unsigned char aes_key[32] = { 0 };

  // 隨機生成密鑰
  for (int x = 0; x < 32; x++)
  {
    int ch = rand() % 5;
    aes_key[x] = (char)ch;
  }

  AES(Buffer, EncodeBuf, (unsigned char *)aes_key, (char*)"encode");
  std::cout << "加密數據長度: " << strlen((char *)EncodeBuf) << std::endl;

  AES(EncodeBuf, DecodeBuf, (unsigned char*)aes_key, (char*)"decode");
  std::cout << "解密數據: " << DecodeBuf << std::endl;

  system("pause");
  return 0;
}

如上代碼,通過調用AES函數時,傳入encode實現數據加密,傳入decode實現數據解密,如下圖所示;

文章出處:https://www.cnblogs.com/LyShark/p/17797583.html
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 拉取鏡像 docker pull mongo 使用 docker 安裝 mongodb docker run --restart=always --name mongodb -v ~/docker/mongo:/data/db -d -p 27017:27017 -e MONGO_INITDB_RO ...
  • Lock實現線程間定製化通信 案例 要求 三個線程,AA BB CC AA線程列印5次,BB線程列印10次,CC線程列印15次 代碼實現 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lo ...
  • 基礎代碼 只包含最簡單的代碼,不包含亂碼解決、文件上傳。 import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.client.config.RequestConfig; imp ...
  • 不論是在團隊寫作還是在個人工作中,PDF 文檔往往會經過多次修訂和更新。掌握 PDF 文檔內容的變化對於管理文檔有極大的幫助。通過對比 PDF 文檔,用戶可以快速找出文檔增加、刪除和修改的內容,更好地瞭解文檔的演變過程,輕鬆地管理文檔。本文將介紹如何在 Java 程式中通過代碼快速比較兩個 PDF ...
  • 作者:Escape 來源:https://www.escapelife.site/posts/38c81b25.html 服務日誌收集方案:Filebeat + Graylog! 當我們公司內部部署很多服務以及測試、正式環境的時候,查看日誌就變成了一個非常剛需的需求了。是多個環境的日誌統一收集,然後 ...
  • 一、SpringCloud 簡介 Spring Cloud 是一系列框架的有序集合如服務發現註冊、配置中心、消息匯流排、負載均衡、熔斷器、數據監控等。 SpringCloud 將多個服務框架組合起來,通過Spring Boot進行再封裝,屏蔽掉了複雜的配置和實現原理,最終給開發者提供了一套簡單易懂、易 ...
  • 哈嘍兄弟們,今天來實現一下建築市場公共服務平臺的數據採集,順便實現一下網站的JS解密。 話不多說,我們直接開始今天的內容。 首先我們需要準備這些 環境使用 Python 3.8 Pycharm 模塊使用 requests --> pip install requests execjs --> pip ...
  • 我們在對keycloak框架中的核心項目keycloak-services進行二次開發過程中,發現了一個問題,當時有這種需求,在keycloak-services中需要使用infinispan緩存,我們直接添加infinispan-core引用之後,在啟動keycloak進出錯了,提示我們沒有找到i ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...