1. 程式人生 > >windows下vc呼叫openssl實現RSA加密

windows下vc呼叫openssl實現RSA加密

     拿到了linux下c實現的RSA呼叫原始碼,想在windows下程式設計實現相同的結果,查了查資料,在vc6和vs2010除錯通過,在win7 x64和winXP 32 執行結果一致,記錄下來,以備日後查詢。

一、安裝openssl

1、進入Win32 OpenSSL下載頁面,選擇適合自己的版本進行下載。建議選擇win32版本,程式通用性強,選擇非light版本。

2、安裝,有個lib位置選項,選在system那個選項比較好。

二、修改工程屬性

1、vc6.0:include和lib包含目錄中新增openssl安裝資料夾下的include和lib

2、vs2010:配置屬性--VC++目錄--包含目錄,新增openssl下的include資料夾

                    連結器--常規--附加庫目錄,新增openssl下的lib和bin

三、除錯原始碼

因為我只需要加密結果,以便對照linux結果是否一致,所以沒有寫解密

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#include <openssl/applink.c>

#pragma comment(lib, "libeay32.lib")

#define PUBLICKEY "test.pub"   //公鑰檔案
#define BUFFSIZE 1024

char* my_encrypt(char *str, char *path_key);//加密

int main(void) {
	char *source = "12345678";
	char *ptr_en, *ptr_de;
	FILE *frsa;
	printf("source is    :%s\n", source);
	ptr_en = my_encrypt(source, PUBLICKEY);

	if (ptr_en != NULL) {
		free(ptr_en);
	}
	return 0;
}
char *my_encrypt(char *str, char *path_key) {
	errno_t err;
	char *p_en;
	RSA *p_rsa;
	FILE *file,*frsa;
	int flen, rsa_len,i,enlen;


	if ((err = fopen_s(&file, path_key, "r")) != 0) {
		perror("open key file error");
		return NULL;
	}
	
	if ((p_rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL)) == NULL) {
		ERR_print_errors_fp(stdout);
		return NULL;
	}
	flen = strlen(str);
	rsa_len = RSA_size(p_rsa);
	p_en = ( char *)malloc(rsa_len +1);
	memset(p_en, 0, rsa_len +1);
	if (RSA_public_encrypt(strlen(str), (unsigned char *)str, (unsigned char*)p_en, p_rsa, RSA_PKCS1_PADDING)<0) {
		return NULL;
	}
	err=fopen_s(&frsa,"ps_rsa","wb");
	enlen=strlen(p_en);
	fwrite((void *)p_en,1,rsa_len,frsa);
	printf("rsa_len:%d\n",rsa_len);
	fclose(frsa);
	RSA_free(p_rsa);
	fclose(file);
	return p_en;
}

四、注意事項

1、公鑰檔案讀取函式的選擇

網上查的資料,公鑰檔案有兩種格式,對應兩個函式

PEM公鑰格式檔案

1

2

-----BEGIN PUBLIC KEY-----

-----END PUBLIC KEY-----

上面這種格式,使用函式  PEM_read_RSA_PUBKEY

 PEM RSAPublicKey公鑰格式檔案

1

2

-----BEGIN RSA PUBLIC KEY-----

-----END RSA PUBLIC KEY-----

這種格式,使用函式   PEM_read_RSAPublicKey

2、這裡使用的 RSA_PKCS1_PADDING 方式,這種方式在輸入資訊不夠一塊時,會隨機填充,因此每次加密,即使明文相同,密文也會不同,解密時演算法會使用相同的填充方式填充,實現解密。

另外,這種加密引數,明文長度要求小於  塊長-11,第一個引數是明文的實際長度。