Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用openssl库验证摘要?_C_Openssl_Key_Sha256_Digest - Fatal编程技术网

C 如何使用openssl库验证摘要?

C 如何使用openssl库验证摘要?,c,openssl,key,sha256,digest,C,Openssl,Key,Sha256,Digest,我正在用以下方法建立一个许可证系统。我生成了一个匹配的公钥和私钥: 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 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;
    }
}
#包括
#包括
#包括
#包括
#包括
//用于文件读取操作的缓冲区。缓冲区必须能够容纳
//整个RSA签名(例如,4096位RSA密钥生成512字节签名)
#定义缓冲区大小512
静态无符号字符缓冲区[缓冲区大小];
int main(int argc,char*argv[])
{
如果(argc!=4)
{
fprintf(标准规范,“用法:%s数据文件签名\u文件公钥,\n”,argv[0]);
返回-1;
}
const char*filename=argv[1];
常量char*sigfile=argv[2];
const char*pubkeyfile=argv[3];
无符号字节=0;
//计算数据文件的SHA256摘要
FILE*datafile=fopen(文件名,“rb”);
//用于保存计算摘要的缓冲区
无符号字符摘要[SHA256_摘要_长度];
SHA256_CTX CTX;
SHA256_Init(&ctx);
//分块读取数据并将其馈送到OpenSSL SHA256
而((字节=fread(缓冲区,1,缓冲区大小,数据文件)))
{
SHA256_更新(&ctx、缓冲区、字节);
}
SHA256_最终版(摘要和ctx);
fclose(数据文件);
//从文件中读取签名
文件*sign=fopen(sigfile,“r”);
字节=fread(缓冲区,1,缓冲区大小,符号);
fclose(标志);
//验证计算的摘要和签名是否匹配
文件*pubkey=fopen(pubkeyfile,“r”);
//从文件中读取公钥
RSA*RSA\u pubkey=PEM\u read\u RSA\u pubkey(pubkey,NULL,NULL);
//解密签名(在缓冲区中)并验证其匹配
//使用从数据文件计算的摘要。
int result=RSA\u验证(NID\u sha256,摘要,sha256\u摘要长度,
缓冲区、字节、rsa_公钥);
RSA_-free(RSA_-pubkey);
fclose(pubkey);
如果(结果==1)
{
printf(“签名有效\n”);
返回0;
}
其他的
{
printf(“签名无效\n”);
返回1;
}
}
此外,您也可以使用
xxd-i pub-key.pem
生成一个漂亮的C样式的密钥头,以代替
pubkeyfile
,轻松地将公钥作为文件参数传入


示例代码来自:

命令
openssl dgst-sha256-signature license.secret-verify pub-key.pem license
将执行您正在查找的操作。查看
apps/dgst.c
中的
openssl
源代码,在您自己的代码中重新创建它,特别是查找
EVP_Digest
调用。但是,您还需要验证公钥(
pub key.pem
)是否真实(可能有人篡改了它),这并不容易。看到了吗?我可以在我的C程序中将公钥存储为数组吗?是的,可以。这将使修改它变得更加困难,但并非不可能。