最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言使用openSSL庫AES模塊實現(xiàn)加密功能詳解

 更新時間:2017年05月22日 11:29:42   作者:erlang_hell  
這篇文章主要介紹了C語言使用openSSL庫AES模塊實現(xiàn)加密功能,詳細分析了C語言加密的相關概念、原理及AES模塊加密具體實現(xiàn)技巧,需要的朋友可以參考下

本文實例講述了C語言使用openSSL庫AES模塊實現(xiàn)加密功能。分享給大家供大家參考,具體如下:

概述

在密碼學里面一共有3中分類:

1.對稱加密/解密

對稱加密比較常見的有DES/AES。加密方和解密方都持有相同的密鑰。對稱的意思就是加密和解密都是用相同的密鑰。

2.非對稱加密/解密

常見的加密算法DSA/RSA。如果做過Google Pay的話,應該不會陌生。非對稱意味著加密和解密使用的密鑰不是相同的。這種應用的場合是需要保持發(fā)起方的權威性,比如Google中一次支付行為,只能Google通過私鑰來加密產(chǎn)出來,但是大家都能通過公鑰來認證這個是真的。打個更加淺顯的比方:私鑰可以理解成美聯(lián)儲的印鈔機,公鑰可以理解成在民間無數(shù)的美元驗鈔機。

還有一個場合也是https使用證書方式登錄的時候,也是使用的雙向的非對稱加密模式來做的。

3.離散

這種只能被稱為驗簽,而不是加密。因為這類算法只能一個方向(將輸入數(shù)據(jù)離散到某個特定的數(shù)字,反向解密是無法做到的。)。最常見的算法就是MD5。在寫php的時候大量的使用這種驗簽來做認證。他可以將字符串離散成32byte的16進制的數(shù)字。

本次使用AES CBC方式來加密。CBC模式加密是SSL的通訊標準,所以在做游戲的時候經(jīng)常會使用到。openSSL的基本用法可以參考這個

兩個細節(jié)

這種加密的需要了解下面兩個細節(jié):

1.加密的內(nèi)存塊一般按照16字節(jié)(這個也可以調(diào)整)對齊;當原始內(nèi)存塊沒有對齊字節(jié)數(shù)的時候,需要填充;

2.加密解密不會引發(fā)內(nèi)存的膨脹或者縮?。?/p>

最近在使用Python,Java,c#都去看過AES的接口,最輕松的是c#,java。當使用C來寫,才能明顯感受到在這些操作過程中,有多少次內(nèi)存的分配,多少的內(nèi)存拼接。啥事都有成本,封裝良好的語言損失掉的效率可能來自于這些便利。

準備知識

函數(shù)接口

int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
// 設置加密key
AES_KEY aes;
AES_set_encrypt_key(key,128,&aes);// 這里填寫的128是bit位,128bit=(128/8)bytes=16bytes,這個換算和32bit對應int為內(nèi)存指針的原理一樣。
// 初始化自己的key
char key[16];
// 加密函數(shù)
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc);
# define AES_BLOCK_SIZE 16 // aes.h 71 lines
# define AES_ENCRYPT   1 // aes.h 63 lines
# define AES_DECRYPT   0 // aes.h 64 lines
// 定義一個加密的初始化向量
unsigned char iv[AES_BLOCK_SIZE];
// 加密
AES_cbc_encrypt(raw_buf,encrypt_buf,buf_size,&aes,iv,AES_ENCRYPT);
// 解密
AES_cbc_encrypt(raw_buf,encrypt_buf,buf_size,&aes,iv,AES_DECRYPT);

字串轉(zhuǎn)換

// 16進制的字串轉(zhuǎn)換成16byte存儲起來
// hex string to byte in c
const char hexstring[] = "deadbeef10203040b00b1e50", *pos = hexstring;
unsigned char val[12];
size_t count = 0;
/* WARNING: no sanitization or error-checking whatsoever */
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) {
    sscanf(pos, "%2hhx", &val[count]);
    pos += 2;
}
printf("0x");
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++)
    printf("%02x", val[count]);
printf("\n");

padding算法

char *raw_buf = ...;
int raw_size = ...;
char *final_buf = NULL;
int pidding_size = AES_BLOCK_SIZE - (raw_size % AES_BLOCK_SIZE);
int i;
final_buf = (char *)malloc(raw_size+pidding_size);
if (pidding_size!=0) {
    memcpy( final_buf, raw_buf, raw_size);
    for (i =raw_size;i < (raw_size+pidding_size); i++ ) {
      // zero padding算法:
      final_buf[i] = 0;
      or
      // PKCS5Padding算法
      final_buf[i] = pading;
    }
}

完整的代碼

c語言代碼

// main.c
#include <aes.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
unsigned char* str2hex(char *str) {
    unsigned char *ret = NULL;
    int str_len = strlen(str);
    int i = 0;
    assert((str_len%2) == 0);
    ret = (char *)malloc(str_len/2);
    for (i =0;i < str_len; i = i+2 ) {
        sscanf(str+i,"%2hhx",&ret[i/2]);
    }
    return ret;
}
char *padding_buf(char *buf,int size, int *final_size) {
    char *ret = NULL;
    int pidding_size = AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE);
    int i;
    *final_size = size + pidding_size;
    ret = (char *)malloc(size+pidding_size);
    memcpy( ret, buf, size);
    if (pidding_size!=0) {
        for (i =size;i < (size+pidding_size); i++ ) {
            ret[i] = 0;
        }
    }
    return ret;
}
void printf_buff(char *buff,int size) {
    int i = 0;
    for (i=0;i<size;i ++ ) {
        printf( "%02X ", (unsigned char)buff[i] );
        if ((i+1) % 8 == 0) {
            printf("\n");
        }
    }
    printf("\n\n\n\n");
}
void encrpyt_buf(char *raw_buf, char **encrpy_buf, int len ) {
    AES_KEY aes;
    unsigned char *key = str2hex("8cc72b05705d5c46f412af8cbed55aad");
    unsigned char *iv = str2hex("667b02a85c61c786def4521b060265e8");
    AES_set_encrypt_key(key,128,&aes);
    AES_cbc_encrypt(raw_buf,*encrpy_buf,len,&aes,iv,AES_ENCRYPT);
    free(key);
    free(iv);
}
void decrpyt_buf(char *raw_buf, char **encrpy_buf, int len ) {
    AES_KEY aes;
    unsigned char *key = str2hex("8cc72b05705d5c46f412af8cbed55aad");
    unsigned char *iv = str2hex("667b02a85c61c786def4521b060265e8");
    AES_set_decrypt_key(key,128,&aes);
    AES_cbc_encrypt(raw_buf,*encrpy_buf,len,&aes,iv,AES_DECRYPT);
    free(key);
    free(iv);
}
int main(int argn, char *argv[] ) {
    char *raw_buf = NULL;
    char *after_padding_buf = NULL;
    int padding_size = 0;
    char *encrypt_buf = NULL;
    char *decrypt_buf = NULL;
    // 1
    raw_buf = (char *)malloc(17);
    memcpy(raw_buf,"life's a struggle",17);
    printf("------------------raw_buf\n");
    printf_buff(raw_buf,17);
    // 2
    after_padding_buf = padding_buf(raw_buf,17,&padding_size);
    printf("------------------after_padding_buf\n");
    printf_buff(after_padding_buf,padding_size);
    // 3
    encrypt_buf = (char *)malloc(padding_size);
    encrpyt_buf(after_padding_buf,&encrypt_buf, padding_size);
    printf("------------------encrypt_buf\n");
    printf_buff(encrypt_buf,padding_size);
    // 4
    decrypt_buf = (char *)malloc(padding_size);
    decrpyt_buf(encrypt_buf,&decrypt_buf,padding_size);
    printf("------------------decrypt_buf\n");
    printf_buff(decrypt_buf,padding_size);
    free(raw_buf);
    free(after_padding_buf);
    free(encrypt_buf);
    free(decrypt_buf);
    return 0;
}

編譯scons腳本:

# SConstruct
import glob
env = Environment()
env["CPPPATH"] = [ '/usr/include/openssl' ]
env['LIBPATH'] = [ '/home/abel/lib/openssl-1.0.2f' ]
env['CPPDEFINES'] = ['LINUX', '_DEBUG' ]
env['CCFLAGS'] = '-g -std=gnu99'
env['LIBS'] = [ 'm', 'crypto', 'dl' ]
env.Program( target = "./test_aes", source = ( glob.glob( './*.c' ) ) )

輸出結果:

:!./test_aes
------------------raw_buf
6C 69 66 65 27 73 20 61
20 73 74 72 75 67 67 6C
65

------------------after_padding_buf
6C 69 66 65 27 73 20 61
20 73 74 72 75 67 67 6C
65 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

------------------encrypt_buf
DB 63 28 C5 2C 6A 3F 1B
FD 4B C5 47 94 4E 24 9D
D2 15 4C F2 6B 3B 1D C0
E7 D2 7B D6 1E 78 60 EA

------------------decrypt_buf
6C 69 66 65 27 73 20 61
20 73 74 72 75 67 67 6C
65 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

總結

代碼中還是有很多地方都是直接malloc內(nèi)存出來,這些點都能扣得更加細。在每次加密調(diào)用的時候IV內(nèi)存將會改變。

PS:關于加密解密感興趣的朋友還可以參考本站在線工具:

文字在線加密解密工具(包含AES、DES、RC4等):
http://tools.jb51.net/password/txt_encode

MD5在線加密工具:
http://tools.jb51.net/password/CreateMD5Password

在線散列/哈希算法加密工具:
http://tools.jb51.net/password/hash_encrypt

在線MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密工具:
http://tools.jb51.net/password/hash_md5_sha

在線sha1/sha224/sha256/sha384/sha512加密工具:
http://tools.jb51.net/password/sha_encode

希望本文所述對大家C語言程序設計有所幫助。

相關文章

  • C語言開發(fā)實現(xiàn)貪吃蛇游戲

    C語言開發(fā)實現(xiàn)貪吃蛇游戲

    這篇文章主要為大家詳細介紹了C語言開發(fā)實現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C++ 封裝 DLL 供 C# 調(diào)用詳細介紹

    C++ 封裝 DLL 供 C# 調(diào)用詳細介紹

    這篇文章主要介紹了C++ 封裝 DLL 供 C# 調(diào)用(以C# 調(diào)用C++ 二次封裝的VLC播放庫為介質(zhì),支持回調(diào)函數(shù)的封裝),需要的朋友可以參考下面我文章的具體內(nèi)容
    2021-09-09
  • C語言實現(xiàn)雙人反彈球游戲

    C語言實現(xiàn)雙人反彈球游戲

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)雙人反彈球游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++中的delete不會將操作數(shù)置0

    C++中的delete不會將操作數(shù)置0

    這篇文章主要介紹了C++中的delete不會將操作數(shù)置0的相關資料,需要的朋友可以參考下
    2016-05-05
  • 深入Linux grep指令的詳解(實用型)

    深入Linux grep指令的詳解(實用型)

    本篇文章是對Linux下的grep指令進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C/C++深入講解內(nèi)存管理

    C/C++深入講解內(nèi)存管理

    本章主要介紹C語言與C++的內(nèi)存管理,以C++的內(nèi)存分布作為引入,介紹C++不同于C語言的內(nèi)存管理方式(new?delete對比?malloc?free),感興趣的朋友來看看吧
    2022-05-05
  • c++實現(xiàn)簡單的線程池

    c++實現(xiàn)簡單的線程池

    這里給大家介紹了C++中對于pthread線程的一個簡單應用以及使用繼承CDoit,實現(xiàn)其中的start和end,有需要的小伙伴可以參考下
    2015-11-11
  • C語言實現(xiàn)掃雷游戲詳細代碼實例

    C語言實現(xiàn)掃雷游戲詳細代碼實例

    這篇文章主要介紹了C語言實現(xiàn)掃雷游戲詳細代碼實例,有感興趣的同學可以借鑒參考下
    2021-02-02
  • 使用C++獲取邏輯執(zhí)行毫秒數(shù)的方法

    使用C++獲取邏輯執(zhí)行毫秒數(shù)的方法

    這篇文章主要為大家詳細介紹了如何使用C++獲取邏輯執(zhí)行毫秒數(shù)的方法,文中借助c++11提供的steady_clock,實現(xiàn)了精確獲取邏輯執(zhí)行時間的方法,需要的可以參考下
    2024-02-02
  • C++析構函數(shù)內(nèi)部工作機制詳解

    C++析構函數(shù)內(nèi)部工作機制詳解

    析構函數(shù)(Destructor)也是一種特殊的成員函數(shù),沒有返回值,不需要程序員顯式調(diào)用(程序員也沒法顯式調(diào)用),而是在銷毀對象時自動執(zhí)行。構造函數(shù)的名字和類名相同,而析構函數(shù)的名字是在類名前面加一個~符號
    2023-02-02

最新評論

彭山县| 道孚县| 昌都县| 金沙县| 砚山县| 诸暨市| 林西县| 黄龙县| 临朐县| 眉山市| 德阳市| 津市市| 大庆市| 永昌县| 鄂托克前旗| 醴陵市| 西乌| 富平县| 尼勒克县| 安阳市| 思南县| 黄浦区| 靖州| 伊宁县| 涿州市| 福泉市| 玉门市| 遂溪县| 岗巴县| 公安县| 常熟市| 汕尾市| 茌平县| 依安县| 涡阳县| 淅川县| 垦利县| 桦甸市| 冕宁县| 南川市| 富锦市|