openssl EVP_DigestSignFinal EVP_DigestVerifyFinal完整代码示例
时间: 2024-01-21 16:19:38 浏览: 487
以下是 OpenSSL EVP_DigestSignFinal 和 EVP_DigestVerifyFinal 函数的完整代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#define BUFFER_SIZE 1024
int sign_data(const char *message, const char *private_key_path, unsigned char **signature, size_t *signature_length) {
EVP_PKEY *pkey = NULL;
EVP_MD_CTX *mdctx = NULL;
const EVP_MD *md = NULL;
int result = 0;
// Load private key
FILE *fp = fopen(private_key_path, "r");
if (!fp) {
printf("Error: Failed to open private key file.\n");
goto cleanup;
}
pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
fclose(fp);
if (!pkey) {
printf("Error: Failed to load private key.\n");
goto cleanup;
}
// Initialize message digest context
md = EVP_get_digestbyname("SHA256");
if (!md) {
printf("Error: Failed to get message digest.\n");
goto cleanup;
}
mdctx = EVP_MD_CTX_new();
if (!mdctx) {
printf("Error: Failed to create message digest context.\n");
goto cleanup;
}
if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
printf("Error: Failed to initialize message digest context.\n");
goto cleanup;
}
// Update message digest context with message
if (EVP_DigestUpdate(mdctx, message, strlen(message)) != 1) {
printf("Error: Failed to update message digest context.\n");
goto cleanup;
}
// Sign message digest
size_t siglen = EVP_PKEY_size(pkey);
*signature = (unsigned char*)malloc(siglen);
if (!*signature) {
printf("Error: Failed to allocate memory for signature.\n");
goto cleanup;
}
if (EVP_DigestSignFinal(mdctx, *signature, &siglen, pkey) != 1) {
printf("Error: Failed to sign message digest.\n");
goto cleanup;
}
*signature_length = siglen;
result = 1;
cleanup:
if (mdctx) {
EVP_MD_CTX_free(mdctx);
}
if (pkey) {
EVP_PKEY_free(pkey);
}
return result;
}
int verify_signature(const char *message, unsigned char *signature, size_t signature_length, const char *public_key_path) {
EVP_PKEY *pkey = NULL;
EVP_MD_CTX *mdctx = NULL;
const EVP_MD *md = NULL;
int result = 0;
// Load public key
FILE *fp = fopen(public_key_path, "r");
if (!fp) {
printf("Error: Failed to open public key file.\n");
goto cleanup;
}
pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
fclose(fp);
if (!pkey) {
printf("Error: Failed to load public key.\n");
goto cleanup;
}
// Initialize message digest context
md = EVP_get_digestbyname("SHA256");
if (!md) {
printf("Error: Failed to get message digest.\n");
goto cleanup;
}
mdctx = EVP_MD_CTX_new();
if (!mdctx) {
printf("Error: Failed to create message digest context.\n");
goto cleanup;
}
if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
printf("Error: Failed to initialize message digest context.\n");
goto cleanup;
}
// Update message digest context with message
if (EVP_DigestUpdate(mdctx, message, strlen(message)) != 1) {
printf("Error: Failed to update message digest context.\n");
goto cleanup;
}
// Verify signature
if (EVP_DigestVerifyFinal(mdctx, signature, signature_length, pkey) != 1) {
printf("Error: Failed to verify signature.\n");
goto cleanup;
}
result = 1;
cleanup:
if (mdctx) {
EVP_MD_CTX_free(mdctx);
}
if (pkey) {
EVP_PKEY_free(pkey);
}
return result;
}
int main() {
const char *message = "Hello, world!";
const char *private_key_path = "private_key.pem";
const char *public_key_path = "public_key.pem";
unsigned char *signature = NULL;
size_t signature_length = 0;
// Sign data
if (!sign_data(message, private_key_path, &signature, &signature_length)) {
printf("Error: Failed to sign data.\n");
goto cleanup;
}
// Verify signature
if (!verify_signature(message, signature, signature_length, public_key_path)) {
printf("Error: Failed to verify signature.\n");
goto cleanup;
}
printf("Signature verified successfully.\n");
cleanup:
if (signature) {
free(signature);
}
return 0;
}
```
该示例使用 SHA256 哈希算法对消息进行哈希,并使用 RSA 私钥对哈希进行签名。然后,使用 RSA 公钥验证签名是否正确。在实际使用中,需要将示例代码中的私钥和公钥路径替换为实际路径。
阅读全文