tsl c语言,C语言RSA算法实现(基于Mbedtls)

最近项目中需要通过C语言实现RSA算法,这里我通过Mbedtls库来进行实现。

1、下载Mbedtls

首先我们将Mbedtls代码放入到工程中,相关传送门如下:

官方网址是国外的下载慢,所以也附上本文使用到的Mbedtls代码,传送门如下:

2、引入Mbedtls头文件

这里我们在工程中的CMakeLists.txt中引入Mbedtls的头文件,代码如下:

# for debug

# add_compile_options(-g)

project("device-authentication")

cmake_minimum_required(VERSION 3.5)

INCLUDE_DIRECTORIES(

../include/

../../src/net/mbedtls/include

../../src/smalgo/sms4/include

)

SET(my_src_crypto

../../src/net/mbedtls/library/aes.c

../../src/net/mbedtls/library/aesni.c

../../src/net/mbedtls/library/base64.c

../../src/net/mbedtls/library/rsa.c

../../src/net/mbedtls/library/rsa_internal.c

../../src/net/mbedtls/library/entropy.c

../../src/net/mbedtls/library/entropy_poll.c

../../src/net/mbedtls/library/bignum.c

../../src/net/mbedtls/library/sha1.c

../../src/net/mbedtls/library/sha256.c

../../src/net/mbedtls/library/sha512.c

../../src/net/mbedtls/library/md.c

../../src/net/mbedtls/library/md5.c

../../src/net/mbedtls/library/md_wrap.c

../../src/net/mbedtls/library/ripemd160.c

../../src/net/mbedtls/library/platform_util.c

../../src/net/mbedtls/library/oid.c

../../src/net/mbedtls/library/timing.c

../../src/net/mbedtls/library/net_sockets.c

../../src/smalgo/sms4/cbc128.c

../../src/smalgo/sms4/sms4_cbc.c

../../src/smalgo/sms4/sms4_common.c

../../src/smalgo/sms4/sms4_enc.c

../../src/smalgo/sms4/sms4_setkey.c

)

SET(my_src_crypto_dbg

../../src/net/mbedtls/library/ctr_drbg.c

)

SET(SRC_LIST_ENCRYPT_BIN

oem_porting.c

sdk_porting.c

authref.c

test.c

${my_src_crypto}

${my_src_crypto_dbg}

)

SET(SRC_LIST_DECRYPT_LIB

oem_porting.c

sdk_porting.c

authref.c

auth.c

${my_src_crypto}

${my_src_crypto_dbg}

)

#SET(SRC_LIST_AUTH_DEV

# oem_porting.c

# sdk_porting.c

# authref.c

# ${my_src_crypto}

# ${my_src_crypto_dbg}

#)

add_definitions(-fPIC)

#ADD_LIBRARY(authd STATIC ${SRC_LIST_AUTH_DEV})

ADD_LIBRARY(authoal STATIC ${SRC_LIST_DECRYPT_LIB})

ADD_EXECUTABLE(eaidkAuth ${SRC_LIST_ENCRYPT_BIN})

工程结构如下:

1d484992a0c53e13de98ee79cdfaaada.png

引入完成之后我们就可以开始RSA代码编写。

3、RSA代码编写

authref.h 头文件代码如下:

#ifndef __AUTHREF_H__

#define __AUTHREF_H__

#include

#include

#include

#include

#undef DEBUG

#define RSA_KEY_SIZE 1024 // RSA 公钥的位数

#define EXPONENT 65537

#define BUFFER_SIZE 1024

#define RSA_KEY_LEN 256

#define AES_KEY_DEC_LEN 8

#define LICENSE_DEC_LEN 64

typedef struct __rsa

{

uint8_t buf[BUFFER_SIZE*8];

uint8_t* rsa_n;

uint8_t* rsa_e;

uint8_t* rsa_d;

uint8_t* rsa_p;

uint8_t* rsa_q;

uint8_t* rsa_dp;

uint8_t* rsa_dq;

uint8_t* rsa_qp;

uint32_t n_len;

uint32_t e_len;

uint32_t d_len;

uint32_t p_len;

uint32_t q_len;

uint32_t dp_len;

uint32_t dq_len;

uint32_t qp_len;

}T_rsa;

void generate_rsa(T_rsa* r);

void init_rsa_keys(T_rsa* rsa);

void rsa_encrypt( const T_rsa *r,

const unsigned char* plaintext,

unsigned int plaintext_size,

unsigned char *ciphertext,

size_t *ciphertext_size);

void rsa_decrypt(

const T_rsa *r,

const unsigned char* ciphertext,

//unsigned int ciphertext_size,

unsigned char *plaintext,

size_t *plaintext_size);

#ifdef __cplusplus

}

#endif

#endif //__AUTHREF_H__

authref.c 代码如下:

#include "authref.h"

#include "mbedtls/entropy.h"

#include "mbedtls/ctr_drbg.h"

#include "mbedtls/rsa.h"

#define RSA_KEY_SIZE 1024 // RSA 公钥的位数

#define EXPONENT 65537

#define BUFFER_SIZE 1024

#define RSA_KEY_LEN 256

#define AES_KEY_DEC_LEN 8

#define LICENSE_DEC_LEN 64

void generate_rsa(T_rsa* r)

{

mbedtls_rsa_context rsa;

mbedtls_entropy_context entropy;

mbedtls_ctr_drbg_context ctr_drbg;

mbedtls_entropy_init(&entropy);

mbedtls_ctr_drbg_init(&ctr_drbg);

mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);

mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);

mbedtls_rsa_gen_key(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, RSA_KEY_SIZE, EXPONENT);

mbedtls_mpi_write_binary(&rsa.N, r->rsa_n, BUFFER_SIZE);

mbedtls_mpi_write_binary(&rsa.E, r->rsa_e, BUFFER_SIZE);

mbedtls_mpi_write_binary(&rsa.D, r->rsa_d, BUFFER_SIZE);

mbedtls_mpi_write_binary(&rsa.P, r->rsa_p, BUFFER_SIZE);

mbedtls_mpi_write_binary(&rsa.Q, r->rsa_q, BUFFER_SIZE);

mbedtls_mpi_write_binary(&rsa.DP, r->rsa_dp, BUFFER_SIZE);

mbedtls_mpi_write_binary(&rsa.DQ, r->rsa_dq, BUFFER_SIZE);

mbedtls_mpi_write_binary(&rsa.QP, r->rsa_qp, BUFFER_SIZE);

mbedtls_rsa_free(&rsa);

mbedtls_ctr_drbg_free(&ctr_drbg);

mbedtls_entropy_free(&entropy);

}

void init_rsa_keys(T_rsa *rsa) {

memset(rsa->buf, 0, BUFFER_SIZE * 8);

rsa->rsa_n = &rsa->buf[BUFFER_SIZE * 0];

rsa->rsa_e = &rsa->buf[BUFFER_SIZE * 1];

rsa->rsa_d = &rsa->buf[BUFFER_SIZE * 2];

rsa->rsa_p = &rsa->buf[BUFFER_SIZE * 3];

rsa->rsa_q = &rsa->buf[BUFFER_SIZE * 4];

rsa->rsa_dp = &rsa->buf[BUFFER_SIZE * 5];

rsa->rsa_dq = &rsa->buf[BUFFER_SIZE * 6];

rsa->rsa_qp = &rsa->buf[BUFFER_SIZE * 7];

rsa->n_len = BUFFER_SIZE;

rsa->e_len = BUFFER_SIZE;

rsa->d_len = BUFFER_SIZE;

rsa->p_len = BUFFER_SIZE;

rsa->q_len = BUFFER_SIZE;

rsa->dp_len = BUFFER_SIZE;

rsa->dq_len = BUFFER_SIZE;

rsa->qp_len = BUFFER_SIZE;

}

// 加密

void rsa_encrypt(

const T_rsa *r,

const unsigned char *plaintext,

unsigned int plaintext_size,

unsigned char *ciphertext,

size_t *ciphertext_size) {

mbedtls_rsa_context rsa;

mbedtls_entropy_context entropy;

mbedtls_ctr_drbg_context ctr_drbg;

int rett = 0;

mbedtls_entropy_init(&entropy);

//assert(mbedtls_ctr_drbg_init(&ctr_drbg, mbedtls_entropy_func, &entropy, nullptr, 0) == 0);

mbedtls_ctr_drbg_init(&ctr_drbg);

assert(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) == 0);

mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);

assert(mbedtls_mpi_read_binary(&rsa.N, r->rsa_n, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.E, r->rsa_e, BUFFER_SIZE) == 0);

*ciphertext_size = rsa.len = (mbedtls_mpi_bitlen(&rsa.N) + 7) >> 3;

//assert(mbedtls_rsa_pkcs1_encrypt(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, plaintext_size, plaintext, ciphertext) == 0);

rett = mbedtls_rsa_pkcs1_encrypt(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, plaintext_size,

plaintext, ciphertext);

assert(rett == 0);

mbedtls_rsa_free(&rsa);

mbedtls_ctr_drbg_free(&ctr_drbg);

mbedtls_entropy_free(&entropy);

}

// 解密

void rsa_decrypt(

const T_rsa *r,

const unsigned char *ciphertext,

//unsigned int ciphertext_size,

unsigned char *plaintext,

size_t *plaintext_size) {

mbedtls_rsa_context rsa;

mbedtls_entropy_context entropy;

mbedtls_ctr_drbg_context ctr_drbg;

mbedtls_entropy_init(&entropy);

//assert(mbedtls_ctr_drbg_init(&ctr_drbg, mbedtls_entropy_func, &entropy, nullptr, 0) == 0);

mbedtls_ctr_drbg_init(&ctr_drbg);

assert(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) == 0);

mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);

assert(mbedtls_mpi_read_binary(&rsa.N, r->rsa_n, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.E, r->rsa_e, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.D, r->rsa_d, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.P, r->rsa_p, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.Q, r->rsa_q, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.DP, r->rsa_dp, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.DQ, r->rsa_dq, BUFFER_SIZE) == 0);

assert(mbedtls_mpi_read_binary(&rsa.QP, r->rsa_qp, BUFFER_SIZE) == 0);

rsa.len = (mbedtls_mpi_bitlen(&rsa.N) + 7) >> 3;

assert(mbedtls_rsa_pkcs1_decrypt(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PRIVATE, plaintext_size,

ciphertext, plaintext, *plaintext_size) == 0);

mbedtls_rsa_free(&rsa);

mbedtls_ctr_drbg_free(&ctr_drbg);

mbedtls_entropy_free(&entropy);

}

int do_ras_encrypt(authhandle *hdl, uint8_t contract_id[CONTRACTID_LEN], uint8_t user_id[USERID_LEN],

uint8_t uid[FINAL_UID_LEN]) {

T_rsa r;

uint8_t uid_local[UID_LEN];

uint8_t ciphertext[SN_LEN];

size_t ciphertext_len = SN_LEN;

GenRawUID(hdl, contract_id, user_id, uid_local);

//encryp UID

init_rsa_keys(&r);

if (hdl->callback_func.GetServerPublicKey) {

hdl->callback_func.GetServerPublicKey(r.buf);

} else {

GetServerPublicKey(hdl, r.buf); //load 2048 bytes for public key

}

rsa_encrypt(&r, uid_local, UID_LEN, ciphertext, &ciphertext_len);

//printf("ciphertext_len: %ld\n", ciphertext_len);

//copy SWID

#if 0

int i;

printf("CipherUID: ");

for(i = 0; i < FINAL_UID_LEN; ++i){

printf("%02x, ", uid[i]);

}

printf("\n");

#endif

return 0; //OK

}

生成RSA公私钥的伪代码如下:

T_rsa r;

uint8_t pub_key[2048] = { 0 };

uint8_t prv_key[8192] = { 0 };

init_rsa_keys(&r);

generate_rsa(&r);

//1. public key

memcpy(pub_key, r.buf, 2048);

//2. private key

memcpy(prv_key, r.buf, 8192);

RSA加密代码如下:

int do_ras_encrypt(authhandle *hdl, uint8_t contract_id[CONTRACTID_LEN], uint8_t user_id[USERID_LEN],

uint8_t uid[FINAL_UID_LEN]) {

T_rsa r;

uint8_t uid_local[UID_LEN];

uint8_t ciphertext[SN_LEN];

size_t ciphertext_len = SN_LEN;

//encryp UID

init_rsa_keys(&r);

if (hdl->callback_func.GetServerPublicKey) {

hdl->callback_func.GetServerPublicKey(r.buf);

} else {

GetServerPublicKey(hdl, r.buf); //load 2048 bytes for public key

}

rsa_encrypt(&r, uid_local, UID_LEN, ciphertext, &ciphertext_len);

//printf("ciphertext_len: %ld\n", ciphertext_len);

//copy SWID

#if 0

int i;

printf("CipherUID: ");

for(i = 0; i < FINAL_UID_LEN; ++i){

printf("%02x, ", uid[i]);

}

printf("\n");

#endif

return 0; //OK

}

解密代码如下:

static int SetServerPrivateKey(T_rsa *r, uint8_t *prv_key)

{

memcpy(r->buf, prv_key, 8192);

//memset(&r->buf[0], 0, 1024-128);

//memset(&r->buf[1024], 0, 1024-4);

//memset(&r->buf[2048], 0, 1024-128);

//memset(&r->buf[3072], 0, 1024-64);

//memset(&r->buf[4096], 0, 1024-64);

//memset(&r->buf[5120], 0, 1024-64);

//memset(&r->buf[6144], 0, 1024-64);

//memset(&r->buf[7168], 0, 1024-64);

return 0; //OK

}

JNIEXPORT jbyteArray JNICALL Java_com_openailab_oascloud_security_jni_cloud_CloudAuthJNI_decrypUidOnServer

(JNIEnv *env, jobject obj, jstring uidEnc, jbyteArray privateKey)

{

uint8_t *uid_enc = (*env)->GetStringUTFChars(env, uidEnc, NULL);

uint8_t *private_key = (*env)->GetByteArrayElements(env, privateKey, NULL);

jbyteArray ret = NULL;

T_rsa r;

uint8_t plaintext[UID_LEN];

size_t plaintext_len = 256;

uint8_t UID_Recover[SN_LEN];

uint8_t uid_enc_c[FINAL_UID_LEN];

init_rsa_keys(&r);

SetServerPrivateKey(&r, private_key);

hex2array(uid_enc, FINAL_UID_LEN * 2, uid_enc_c);

recover(&uid_enc_c[FINAL_UID_LEN - SN_LEN], UID_Recover, SN_LEN);

rsa_decrypt(&r, UID_Recover, plaintext, &plaintext_len);

/*printf("plaintext=\n");

for (size_t i = 0; i < UID_LEN; i++)

{

if (i > 0 && i % 16 == 0) {

printf("\n");

}

printf("%02x,", plaintext[i]);

}

printf("\n");*/

ret = (*env)->NewByteArray(env, UID_LEN);

(*env)->SetByteArrayRegion(env, ret, 0, UID_LEN, (jbyte*)plaintext);

(*env)->ReleaseByteArrayElements(env, privateKey, private_key, 0);

(*env)->ReleaseStringUTFChars(env, uidEnc, uid_enc);

return ret;

}

到此C语言RSA加解密就介绍完毕了。

1dc53c917a05fe6ed8e9cba0ad6fc845.png

7443628b0808bf41c06574ee61e91166.png

张志翔

博客专家

发布了343 篇原创文章 · 获赞 376 · 访问量 36万+

他的留言板

关注

标签:ctr,..,BUFFER,mbedtls,RSA,rsa,Mbedtls,C语言,SIZE

来源: https://blog.csdn.net/qq_19734597/article/details/104061384

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值