當前位置:首頁 » 密碼管理 » copensslrsa加密

copensslrsa加密

發布時間: 2023-05-18 16:02:44

c語言socket加密,用Openssl中的AES+RSA還是SSL

1. 利用RSA安全傳輸aes生成密鑰所需的Seed(32位元組)
2. 利用aes_encrypt/aes_decrypt對Socket上面的業務數據進行aes加密/解密 理論上只需要aes就能保證全部流程,但由於aes加密所需要的aes-KEY是一個結構。
這個一個結構,如果通過網路進行傳輸,就需要對它進行網路編碼,openssl裡面沒有現成的API 所以就引入RSA來完成首次安全的傳輸,保證Seed不會被竊聽。

㈡ OpenSSL之RSA用法

RSA公開密鑰密碼體制是一種使用不同的加密密鑰與解密密鑰,「由已知加密密鑰推導出解密密旅遲鑰在計算上是不可行的」密碼體制 。在公開密鑰密碼體制中,加密密鑰(即公開密鑰)PK是公開信息,而解密密鑰(即秘密密鑰)SK是需要保密的。加密演算法E和解密演算法D也都是公開的。雖然解密密鑰SK是由公開密鑰PK決定的,但卻不能根據PK計算出SK 。
正是基於這種理論,1978年出現了著名的RSA演算法,它通常是先生成一對RSA密鑰,其中之一是保密密鑰,由用戶保存;另一個為公開密鑰,可對外公開,甚至可在網路伺服器中注冊。為提高保密強度,RSA密鑰至少為500位長,一般推薦使用1024位。這就使加密的計算量很大。為減少計算量,在傳送信息時,常採用傳統加密方法與公開密鑰加密方法相結合的方式,即信息採用改進的DES或IDEA對話密鑰加密,然後使用RSA密鑰加密對話密鑰和信息摘要。對方收到信息後,用不同的密鑰解密並可核對信息摘要 。

RSA演算法是一個廣泛使用的公鑰演算法。其密鑰包括公鑰和私鑰。它能用於數字簽名、身份認證以及密鑰交換。RSA密鑰長度一般使用1024位或者更高。RSA密鑰信息主要包括:
n:模數
e:公鑰指數
d:私鑰指數
p:最初的大拆行李素數
q:最初的大素數
其中,公鑰為n和e;私鑰為n和d。

本文假設你已經安裝好了OpenSSL,並且持有一份1.1.1的源碼
RSA相關的頭文件在rsa.h中、源文件在crypto/rsa目錄中。

這個結構定義了RSA內部數據信息。主要欄位含義:
version —— 版本。
meth —— RSA運算抽象方法集合。
n,e,d,p,q,dmp1,dmq1,iqmp —— 密鑰相關的大數。

這個結構定義了RSA內部各種運算抽象方法集合。主要欄位含義:
name —— 名稱描述。
rsa_pub_enc —— 公鑰加密方法。
rsa_pub_dec —— 公鑰解密方法。
rsa_priv_enc —— 私鑰加密方法。
rsa_priv_dec —— 公鑰解密方法。
rsa_sign —— 簽名方法。
rsa_verify —— 驗簽方法。
rsa_keygen —— 生成密鑰對方法。

在1.1.1中,大多數的數據結構已經不再向使用者開放,從封裝的角度來看,這是更合理的。如果你在頭文件中找不到結構定義,不妨去源碼中搜一搜。

RSA *RSA_new(void);
生成一個RSA密鑰結構,採用默認的rsa_pkcs1_ossl_meth方法。

void RSA_free(RSA *r);
釋放RSA結構。

RSA *RSA_generate_key(int bits, unsigned long e, void (*callback) (int, int, void *), void *cb_arg);
生成RSA密鑰(舊版本)。
bits為密鑰位數,e為公鑰指數。
callback為密鑰生成過程中的干預回調函數,通常傳入NULL。cb_arg為回調參數。
成功返回RSA指針,失敗返回NULL。

int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
生成RSA密鑰(新版本)。
rsa為RSA對帶老象指針。bits為密鑰位置,e為公鑰指數的大數形式指針。cb為干預回調函數,通常傳入NULL。
成功返回1,失敗返回0。
關於公鑰指數e,主要有兩個取值:
# define RSA_3 0x3L
# define RSA_F4 0x10001L

RSA *RSAPublicKey_p(RSA *rsa);
復制RSA公鑰部分。
成功返回RSA指針,失敗返回NULL。

RSA *RSAPrivateKey_p(RSA *rsa);
復制RSA私鑰部分。
成功返回RSA指針,失敗返回NULL。

int RSA_bits(const RSA *rsa);
獲取RSA密鑰位數。
int RSA_size(const RSA *rsa);
獲取RSA密鑰長度。

int RSA_check_key(const RSA *);
int RSA_check_key_ex(const RSA *, BN_GENCB *cb);
檢查RSA的有效性,必須為完整的密鑰對。
成功返回1,失敗返回0。

int RSA_print(BIO *bp, const RSA *r, int offset);
int RSA_print_fp(FILE *fp, const RSA *r, int offset);
將RSA信息輸出到bp/fp中,off為輸出信息在bp/fp中的偏移量,比如是屏幕bp/fp,則表示列印信息的位置離左邊屏幕邊緣的距離。

int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
RSA公鑰加密。
成功返回密文的長度,失敗返回-1。

int RSA_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
RSA公鑰解密。
成功返回明文的長度,失敗返回-1。

int RSA_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
RSA私鑰加密。
成功返回密文的長度,失敗返回-1。

int RSA_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
RSA私鑰解密。
成功返回明文的長度,失敗返回-1。

關於padding填充方式,取值:

其中PKCS1填充大小為11位元組,所以加密明文長度必須不大於(密鑰大小-11位元組)。
# define RSA_PKCS1_PADDING_SIZE 11

int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen, RSA *rsa);
對數據m生成RSA簽名,生成的簽名長度與key的長度相同,如512位密鑰生成64位元組簽名。
type指定摘要演算法的NID,如NID_sha1。
成功返回1,失敗返回0。

int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
對數據m驗證RSA簽名。
type指定摘要演算法的NID,如NID_sha1。
成功返回1,失敗返回0。

以下函數在x509.h中定義:

int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
}
將RSA公鑰轉換為DER編碼,並寫入到bp抽象IO中。
成功返回1,失敗返回0。

RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
}
從bp抽象IO中讀取DER編碼,並轉換為rsa結構私鑰。
成功返回有效指定,失敗返回NULL。

int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
}
將RSA公鑰轉換為DER編碼,並寫入到bp抽象IO中。
成功返回1,失敗返回0。

RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
}
從bp抽象IO中讀取DER編碼,並轉換為rsa結構公鑰。
成功返回有效指定,失敗返回NULL。

下面這個例子演示了RSA密鑰對的生成、公私鑰的復制、公鑰加密和私鑰解密的用法。

輸出:

下面這個例子演示了公私鑰的分開保存、讀取,以及使用公私鑰加解密。

輸出:
RSA_generate_key_ex() ret:1
i2d_RSAPrivateKey_bio() ret:1
i2d_RSAPublicKey_bio() ret:1
' private key size:64
' public key size:64
RSA_public_encrypt() ret:64
RSA_private_decrypt() ret:10
text:[1234567890]

下面這個例子演示了簽名的生成和驗證操作。

輸出:
ret:1
RSA_sign() ret:1
sign 64

RSA_verify() ret:1

㈢ 如何用C語言來使用openssl rsa進行公鑰加密,已有公鑰和明文

1. 本程序使用2048位密鑰對,每次加密時,原始數據的最大長度為245位元組,加密後的密文長度為256位元組.(採用打PADDING 的加密方式)

2. 如果所加密數據長度大於245位元組,請分多次加密,後將密文按順序存儲;解密時,每次讀取256位元組,進行解密,將解密後的數據依次按順序存儲,即可還原原始數據.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#define OPENSSLKEY "test.key"
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
char *my_encrypt(char *str, char *path_key); //加密
char *my_decrypt(char *str, char *path_key); //解密
int main(void)
{
char *source = "i like dancing !!!";
char *ptf_en, *ptf_de;
printf("source is :%s\n", source);
//1.加密
ptf_en = my_encrypt(source, PUBLICKEY);
if (ptf_en == NULL){
return 0;
}else{
printf("ptf_en is :%s\n", ptf_en);
}
//2.解密
ptf_de = my_decrypt(ptf_en, OPENSSLKEY);
if (ptf_de == NULL){
return 0;
}else{
printf("ptf_de is :%s\n", ptf_de);
}
if(ptf_en) free(ptf_en);
if(ptf_de) free(ptf_de);
return 0;
}
//加密
char *my_encrypt(char *str, char *path_key)
{
char *p_en = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
int lenth = 0; //flen為源文件長度, rsa_len為秘鑰長度
//1.打開秘鑰文件
if((file = fopen(path_key, "rb")) == NULL)
{
perror("fopen() error 111111111 ");
goto End;
}
//2.從公鑰中獲取 加密的秘鑰
if((p_rsa = PEM_read_RSA_PUBKEY(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
lenth = strlen(str);
p_en = (char *)malloc(256);
if(!p_en)
{
perror("malloc() error 2222222222");
goto End;
}
memset(p_en, 0, 256);
//5.對內容進行加密
if(RSA_public_encrypt(lenth, (unsigned char*)str, (unsigned char*)p_en, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error 2222222222");
goto End;
}
End:
//6.釋放秘鑰空間, 關閉文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_en;
}
//解密
char *my_decrypt(char *str, char *path_key)
{
char *p_de = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
//1.打開秘鑰文件
file = fopen(path_key, "rb");
if(!file)
{
perror("fopen() error 22222222222");
goto End;
}
//2.從私鑰中獲取 解密的秘鑰
if((p_rsa = PEM_read_RSAPrivateKey(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
p_de = (char *)malloc(245);
if(!p_de)
{
perror("malloc() error ");
goto End;
}
memset(p_de, 0, 245);
//5.對內容進行加密
if(RSA_private_decrypt(256, (unsigned char*)str, (unsigned char*)p_de, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error ");
goto End;
}
End:
//6.釋放秘鑰空間, 關閉文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_de;
}

㈣ 如何利用OpenSSL庫進行RSA加密和解密

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/engine.h>

intmain(intargc,char*argv[])
{
printf("openssl_testbegin ");
RSA*rsa=NULL;
charoriginstr[]="hello ";//這是我們需要加密的原始數據
//allocateRSAstructure,首先需要申請一個RSA結構題用於存放生成的公私鑰,這里rsa就是這個結構體的指針
rsa=RSA_new();
if(rsa==NULL)
{
printf("RSA_newfailed ");
return-1;
}

//generateRSAkeys
BIGNUM*exponent;
exponent=BN_new();//生成RSA公私鑰之前需要選擇一個奇數(oddnumber)來用於生成公私鑰
if(exponent==NULL)
{
printf("BN_newfailed ");
gotoFAIL1;
}
if(0==BN_set_word(exponent,65537))//這里選擇奇數65537
{
printf("BN_set_wordfailed ");
gotoFAIL1;
}


//這里molus的長度選擇4096,小於1024的molus長度都是不安全的,容易被破解
if(0==RSA_generate_key_ex(rsa,4096,exponent,NULL))
{
printf("RSA_generate_key_exfailed ");
gotoFAIL;
}
char*cipherstr=NULL;
//分配一段空間用於存儲加密後的數據,這個空間的大小由RSA_size函數根據rsa算出
cipherstr=malloc(RSA_size(rsa));
if(cipherstr==NULL)
{
printf("malloccipherstrbuffailed ");
gotoFAIL1;
}
//下面是實際的加密過程,最後一個參數paddingtype,有以下幾種。
/*
RSA_PKCS1_PADDINGPKCS#1v1.5padding..
RSA_PKCS1_OAEP_PADDING
EME-OAEPasdefinedinPKCS#1v2.0withSHA-1,..
RSA_SSLV23_PADDING
PKCS#1v1.5paddingwithanSSL-.
RSA_NO_PADDING
RawRSAencryption.ntheapplicationcode..
*/
//這里首先用公鑰進行加密,選擇了RSA_PKCS1_PADDING

if(RSA_size(rsa)!=RSA_public_encrypt(strlen(originstr)+1,originstr,cipherstr,rsa,RSA_PKCS1_PADDING))
{
printf("encryptionfailure ");
gotoFAIL2;
}
printf("theoriginalstringis%s ",originstr);
printf("theencryptedstringis%s ",cipherstr);


//Now,let'
//下面來用私鑰解密,首先需要一個buffer用於存儲解密後的數據,這個buffer的長度要足夠(小於RSA_size(rsa))
//這里分配一個長度為250的字元數組,應該是夠用的。
chardecrypted_str[250];
intdecrypted_len;
if(-1=(decrypted_len=RSA_private_decrypt(256,cipherstr,decrypted_str,rsa,RSA_PKCS1_PADDING)))
{
printf("decryptionfailure ");
gotoFAIL2;
}
printf("decryptedstringlengthis%d,decryped_stris%s ",decrypted_len,decrypted_str);
FAIL2:
free(cipherstr);
FAIL1:
BN_free(exponent);
FAIL:
RSA_free(rsa);
return0;
}

以上是源代碼,下面使用下面的編譯命令在源碼所在路徑下生成可執行文件
gcc *.c -o openssl_test -lcrypto -ldl -L/usr/local/ssl/lib -I/usr/local/ssl/include
其中,-lcrypto和-ldl是必須的,前者是OpenSSL中的加密演算法庫,後者是用於成功載入動態庫。

熱點內容
vs編譯找不到指定項目文件 發布:2025-02-08 12:36:54 瀏覽:243
怎樣用windows伺服器搭建網站 發布:2025-02-08 12:27:38 瀏覽:532
android獲取音樂 發布:2025-02-08 12:26:05 瀏覽:962
存儲的數據可以復制嗎 發布:2025-02-08 12:20:22 瀏覽:852
scraino編程 發布:2025-02-08 11:59:41 瀏覽:266
我的世界伺服器進不去該怎麼辦 發布:2025-02-08 11:47:41 瀏覽:236
linux的telnet 發布:2025-02-08 11:47:36 瀏覽:288
壓縮袋打折 發布:2025-02-08 11:46:02 瀏覽:259
c語言結構體題目 發布:2025-02-08 11:46:01 瀏覽:339
如何svn限制一些外網不能訪問 發布:2025-02-08 11:46:00 瀏覽:992