我正在用以下方式建立一个许可证系统。我生成了一个匹配的公钥和私钥,现在我得到了一个包含用户和许可证详细信息的独特信息的许可证信息。
openssl genrsa -out mykey.pem 1024
openssl rsa -in mykey.pem -des3 -out prv-key.pem
openssl rsa -in mykey.pem -pubout -out pub-key.pem
现在我得到了一个包含用户和许可证细节的独特信息的许可证信息 我的产品读取这个信息,验证信息,如果一切都按计划进行,它就会读取许可证政策并相应地运行。
所以我把这个许可证文件用我的私钥进行了签名消化
openssl dgst -sha256 -sign prv-key.pem -out license.secret license
现在我把许可证和签名的许可证文件都发给了客户。
我的问题是:我怎样才能在C程序中使用客户方的公钥(pub-key.pem)来验证摘要。我找过libssl和openssl库,但找不到一个好的例子来验证摘要。
你会想使用 libopenssl-dev
或相当于Windows的程序来建立一个类似的C程序。
#include <stdio.h>
#include <stdlib.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
// Buffer for file read operations. The buffer must be able to accomodate
// the RSA signature in whole (e.g. 4096-bit RSA key produces 512 byte signature)
#define BUFFER_SIZE 512
static unsigned char buffer[BUFFER_SIZE];
int main(int argc, char *argv[])
{
if(argc != 4)
{
fprintf(stderr, "Usage: %s datafile signature_file public_key\n", argv[0]);
return -1;
}
const char* filename = argv[1];
const char* sigfile = argv[2];
const char* pubkeyfile = argv[3];
unsigned bytes = 0;
// Calculate SHA256 digest for datafile
FILE* datafile = fopen(filename , "rb");
// Buffer to hold the calculated digest
unsigned char digest[SHA256_DIGEST_LENGTH];
SHA256_CTX ctx;
SHA256_Init(&ctx);
// Read data in chunks and feed it to OpenSSL SHA256
while((bytes = fread(buffer, 1, BUFFER_SIZE, datafile)))
{
SHA256_Update(&ctx, buffer, bytes);
}
SHA256_Final(digest, &ctx);
fclose(datafile);
// Read signature from file
FILE* sign = fopen (sigfile , "r");
bytes = fread(buffer, 1, BUFFER_SIZE, sign);
fclose(sign);
// Verify that calculated digest and signature match
FILE* pubkey = fopen(pubkeyfile, "r");
// Read public key from file
RSA* rsa_pubkey = PEM_read_RSA_PUBKEY(pubkey, NULL, NULL, NULL);
// Decrypt signature (in buffer) and verify it matches
// with the digest calculated from data file.
int result = RSA_verify(NID_sha256, digest, SHA256_DIGEST_LENGTH,
buffer, bytes, rsa_pubkey);
RSA_free(rsa_pubkey);
fclose(pubkey);
if(result == 1)
{
printf("Signature is valid\n");
return 0;
}
else
{
printf("Signature is invalid\n");
return 1;
}
}
另外,你也可以不把公钥作为文件参数传入,而是通过使用 xxd -i pub-key.pem
来生成一个漂亮的C风格的密钥头,它可以被程序用来代替 pubkeyfile
.
示例代码来自。https:/pagefault.blog20190422 how-to-sign-and-verify-using-openssl