openssl engine引擎 实现RSA引擎 (4)
通过对openssl rsa_st结构体进行重新赋值并导入到引擎中,在使用openssl与rsa相关的算法中都会调用引擎中的rsa算法
rsa算法中主要包括
- public_encrypto //公钥加密
- public_decrypto //公钥解密
- private_encrypto //私钥加密
- private_decrypto //私钥解密
- sign //签名
- verify //验签
- gen_key //生成密钥
rangine.h
#ifndef __RANG_ENG_H__
#define __RANG_ENG_H__
#include <openssl/engine.h>
#include <stdio.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/ecdh.h>
#include <openssl/crypto.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
const char *eng_id="randeng";
const char *eng_name="rand engines for OpenSSL";
/*需要声明一下结构体*/
typedef volatile int CRYPTO_REF_COUNT;
struct rsa_st {
/*
* The first parameter is used to pickup errors where this is passed
* instead of an EVP_PKEY, it is set to 0
*/
int pad;
int32_t version;
const RSA_METHOD *meth;
/* functional reference if 'meth' is ENGINE-provided */
ENGINE *engine;
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
/* for multi-prime RSA, defined in RFC 8017 */
STACK_OF(RSA_PRIME_INFO) *prime_infos;
/* If a PSS only key this contains the parameter restrictions */
RSA_PSS_PARAMS *pss;
/* be careful using this if the RSA structure is shared */
CRYPTO_EX_DATA ex_data;
CRYPTO_REF_COUNT references;
int flags;
/* Used to cache montgomery values */
BN_MONT_CTX *_method_mod_n;
BN_MONT_CTX *_method_mod_p;
BN_MONT_CTX *_method_mod_q;
/*
* all BIGNUM values are actually in the following data, if it is not
* NULL
*/
char *bignum_data;
BN_BLINDING *blinding;
BN_BLINDING *mt_blinding;
CRYPTO_RWLOCK *lock;
};
struct rsa_meth_st {
char *name;
int (*rsa_pub_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int (*rsa_pub_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
/* Can be null */
int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
/* Can be null */
int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
/* called at new */
int (*init) (RSA *rsa);
/* called at free */
int (*finish) (RSA *rsa);
/* RSA_METHOD_FLAG_* things */
int flags;
/* may be needed! */
char *app_data;
/*
* New sign and verify functions: some libraries don't allow arbitrary
* data to be signed/verified: this allows them to be used. Note: for
* this to work the RSA_public_decrypt() and RSA_private_encrypt() should
* *NOT* be used RSA_sign(), RSA_verify() should be used instead.
*/
int (*rsa_sign) (int type,
const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen,
const RSA *rsa);
int (*rsa_verify) (int dtype, const unsigned char *m,
unsigned int m_length, const unsigned char *sigbuf,
unsigned int siglen, const RSA *rsa);
/*
* If this callback is NULL, the builtin software RSA key-gen will be
* used. This is for behavioural compatibility whilst the code gets
* rewired, but one day it would be nice to assume there are no such
* things as "builtin software" implementations.
*/
int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
int (*rsa_multi_prime_keygen) (RSA *rsa, int bits, int primes,
BIGNUM *e, BN_GENCB *cb);
};
#endif // DEBUG
rangine.c
#include "rangeng.h"
static int myrand_init(ENGINE *e)
{
printf("myrand_init\n");
return 1;
}
static int myrand_finish(ENGINE *e)
{
printf("myrand_finish\n");
return 1;
}
static int myrand_destroy(ENGINE *e)
{
printf("myrand_destroy\n");
return 1;
}
//自己写的一个加密算法 askii+10
static int my_rsa_pub_enc(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
printf("my_rsa_pub_enc\n");
for (int i = 0; i < flen; i++)
{
to[i]=from[i]+10;
}
return flen;
}
static int my_rsa_pub_dec(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
printf("my_rsa_pub_dec\n");
for (int i = 0; i < flen; i++)
{
to[i]=from[i]-10;
}
return flen;
}
static int my_rsa_priv_enc(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
printf("my_rsa_priv_enc\n");
return 1;
}
static int my_rsa_priv_dec(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
printf("my_rsa_priv_dec\n");
return 1;
}
static int my_rsa_sign (int type,const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen,const RSA *rsa)
{
printf("my_rsa_sign\n");
return 1;
}
static int my_rsa_verify (int type,const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen,const RSA *rsa)
{
printf("my_rsa_verify\n");
return 1;
}
static int my_rsa_init(RSA *rsa)
{
printf("my_rsa_init\n");
return 1;
}
static int my_rsa_finish(RSA *rsa)
{
printf("my_rsa_finish\n");
return 1;
}
//对照引擎rsa_st结构体一一对应,必须保持参数一致
const RSA_METHOD rsa_method = {
"rsa_engine_test",
my_rsa_pub_enc,
my_rsa_pub_dec,
NULL,
NULL,
NULL,
NULL,
my_rsa_init,
my_rsa_finish,
ENGINE_METHOD_RSA,
NULL,
my_rsa_sign,
my_rsa_verify,
NULL,
NULL
};
/*绑定函数*/
static int bind_pp(ENGINE *e)
{
if(!ENGINE_set_id(e,eng_id)||
!ENGINE_set_name(e,eng_name)||
!ENGINE_set_destroy_function(e,myrand_destroy)||
!ENGINE_set_init_function(e,myrand_init)||
!ENGINE_set_finish_function(e,myrand_finish)||
!ENGINE_set_RSA(e,&rsa_method))
return 0;
printf("ERR_load_rsa success\n");
return 1;
}
static ENGINE *enging_range(void)
{
ENGINE*e =ENGINE_new();
if(!e)
return NULL;
if(!bind_pp(e))
{
ENGINE_free(e);
return NULL;
}
return e;
}
void ENGINE_load_rand()
{
ENGINE* e=enging_range();
if(!e)
return ;
ENGINE_add(e);
ENGINE_free(e);
}
static void display_engine_list()
{
ENGINE *h;
int loop;
h = ENGINE_get_first();
loop = 0;
printf("start:\n");
while(h)
{
printf("engine %i, id = \"%s\", name = \"%s\"\n",
loop++, ENGINE_get_id(h), ENGINE_get_name(h));
h = ENGINE_get_next(h);
}
printf("end of list\n");
ENGINE_free(h);
}
int main()
{
// 初始化 OpenSSL 引擎系统
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
//加载引擎
ENGINE_load_rand();
display_engine_list();
ENGINE *e=NULL;
e=ENGINE_by_id(eng_id);
if(!e)
{
printf("err load engine failed\n");
return 0;
}
ENGINE_init(e);
printf("RSA-----BEGIN---END\n");
ENGINE_register_RSA(e); //
RSA *rsa = RSA_new();
BIGNUM *bn = BN_new();
BN_set_word(bn, RSA_F4);
RSA_generate_key_ex(rsa, 2048, bn, NULL);
printf("RSA Key Pair:\n");
RSA_print_fp(stdout, rsa, 0); //打印密钥
// 使用引擎进行 RSA 加密
unsigned char plaintext[] = "Hello, World!";
unsigned char ciphertext[256]={0}; // 注意,缓冲区大小可能需要根据您的密钥长度进行调整
unsigned char plaintext1[256]={0};
int len = RSA_public_encrypt(sizeof(plaintext), plaintext, ciphertext, rsa, RSA_PKCS1_PADDING);
len=RSA_public_decrypt(len, ciphertext, plaintext1, rsa, RSA_PKCS1_PADDING);
// 打印加密后的数据
printf("Encrypted data: ");
for (int i = 0; i < len; i++) {
printf("%02x ", ciphertext[i]);
}
printf("\n");
printf("ciphertext=%s\n",ciphertext);
// 打印加密后的数据
printf("decrypted data: ");
for (int i = 0; i < len; i++) {
printf("%02x ", plaintext1[i]);
}
printf("\n");
printf("ciphertext=%s\n",plaintext1);
// 清理引擎资源
ENGINE_finish(e);
ENGINE_free(e);
}
编译
gcc rangine.c -ldl -lpthread -lcrypto -lssl -o engINE