数字签名及加密C语言总代码实现
时间: 2023-08-26 13:03:34 浏览: 197
数字签名及加密是一种非常重要的信息安全技术,能够保证数据的完整性、可靠性和保密性。下面是一个基于 OpenSSL 库的数字签名及加密 C 语言代码实现示例。
首先需要安装 OpenSSL 库,可以使用以下命令在 Ubuntu 系统中安装:
```
sudo apt-get install libssl-dev
```
接下来是示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/md5.h>
// RSA 公钥加密
int rsa_public_encrypt(unsigned char *in, int inlen, RSA *rsa, unsigned char *out)
{
int ret = RSA_public_encrypt(inlen, in, out, rsa, RSA_PKCS1_PADDING);
if (ret == -1) {
printf("RSA_public_encrypt error: %s\n", ERR_error_string(ERR_get_error(), NULL));
}
return ret;
}
// RSA 私钥解密
int rsa_private_decrypt(unsigned char *in, int inlen, RSA *rsa, unsigned char *out)
{
int ret = RSA_private_decrypt(inlen, in, out, rsa, RSA_PKCS1_PADDING);
if (ret == -1) {
printf("RSA_private_decrypt error: %s\n", ERR_error_string(ERR_get_error(), NULL));
}
return ret;
}
// 生成 RSA 密钥对
int generate_rsa_keypair(RSA **rsa, int bits)
{
int ret = 0;
if ((*rsa = RSA_new()) == NULL) {
printf("RSA_new error: %s\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
BIGNUM *bne = BN_new();
if (BN_set_word(bne, RSA_F4) != 1) {
printf("BN_set_word error: %s\n", ERR_error_string(ERR_get_error(), NULL));
RSA_free(*rsa);
return -1;
}
ret = RSA_generate_key_ex(*rsa, bits, bne, NULL);
if (ret != 1) {
printf("RSA_generate_key_ex error: %s\n", ERR_error_string(ERR_get_error(), NULL));
RSA_free(*rsa);
return -1;
}
BN_free(bne);
return 0;
}
// 计算 MD5 摘要值
int md5_digest(unsigned char *in, int inlen, unsigned char *out)
{
MD5_CTX md5_ctx;
if (!MD5_Init(&md5_ctx)) {
printf("MD5_Init error\n");
return -1;
}
if (!MD5_Update(&md5_ctx, in, inlen)) {
printf("MD5_Update error\n");
return -1;
}
if (!MD5_Final(out, &md5_ctx)) {
printf("MD5_Final error\n");
return -1;
}
return 0;
}
int main()
{
RSA *rsa = NULL;
unsigned char md5[16];
unsigned char cipher[1024], plain[1024];
int cipher_len, plain_len, md5_len;
// 生成 RSA 密钥对
if (generate_rsa_keypair(&rsa, 1024) != 0) {
printf("generate_rsa_keypair error\n");
return -1;
}
// 加密明文
strcpy(plain, "Hello, world!");
plain_len = strlen(plain);
cipher_len = rsa_public_encrypt(plain, plain_len, rsa, cipher);
if (cipher_len < 0) {
printf("rsa_public_encrypt error\n");
RSA_free(rsa);
return -1;
}
// 解密密文
plain_len = rsa_private_decrypt(cipher, cipher_len, rsa, plain);
if (plain_len < 0) {
printf("rsa_private_decrypt error\n");
RSA_free(rsa);
return -1;
}
printf("Plain text: %s\n", plain);
// 计算明文的 MD5 摘要值
md5_len = md5_digest(plain, plain_len, md5);
if (md5_len < 0) {
printf("md5_digest error\n");
RSA_free(rsa);
return -1;
}
// 对 MD5 摘要值进行签名
unsigned char *sig;
sig = (unsigned char *)malloc(RSA_size(rsa));
int siglen;
if ((siglen = RSA_sign(NID_md5, md5, MD5_DIGEST_LENGTH, sig, &cipher_len, rsa)) != 1) {
printf("RSA_sign error: %s\n", ERR_error_string(ERR_get_error(), NULL));
RSA_free(rsa);
return -1;
}
// 验证签名
if (RSA_verify(NID_md5, md5, MD5_DIGEST_LENGTH, sig, siglen, rsa) != 1) {
printf("RSA_verify error: %s\n", ERR_error_string(ERR_get_error(), NULL));
RSA_free(rsa);
return -1;
}
printf("Signature verified successfully!\n");
// 释放资源
RSA_free(rsa);
free(sig);
return 0;
}
```
这段代码实现了 RSA 公钥加密、私钥解密、MD5 摘要值计算、数字签名和验证签名的功能。需要注意的是,此代码仅为示例,实际使用时还需要根据实际需求进行修改和完善。
阅读全文