当前位置: 首页 > 知识库问答 >
问题:

不同消息的OpenSSL签名长度不同

朱丰
2023-03-14

我一直在努力解决RSA_verify的一个奇怪问题。我正在尝试使用C进行RSA签名,并使用C进行RSA验证。我已经使用OpenSSL命令生成了私钥和证书。

message = "1.2.0:08:00:27:2c:88:77"

当我使用上面的消息,生成一个散列并使用RSA\u-sign对摘要进行签名时,我得到长度为256的签名(strlen(signature)),并且RSA\u-sign返回的长度为256。我使用此长度进行验证,验证成功。

但是当我使用message=“1.2.0:08:00:27:2c:88:08”时,签名长度为60,RSA\u-sign返回256。当我使用这个长度60来验证它失败时。它也无法验证长度为256。对于某些消息(1.2.0:08:00:27:2c:88:12),生成的签名也是零。

我使用SHA256散列消息,NID_SHA256RSA_signRSA_verify这个摘要。我在使用OpenSSL命令生成密钥时使用了-sha256。

我通过解析一个XML文件,使用一些字符串操作读取一些标记,从而形成消息。

请建议。

下面是用于签名的代码。

int main(void)  
{  
    int     ret;  
    RSA    *prikey;  
    char *data ;  
    unsigned char* signature;  
    int slen = 0;  
    FILE * fp_priv = NULL;  
    char* privfilepath = "priv.pem";  
    unsigned char* sign = NULL; 

    ERR_load_crypto_strings();

    data = generate_hash();
    printf("Message after generate hash %s: %d\n", data, strlen(data));

    fp_priv = fopen(privfilepath, "r"); 
    if (fp_priv == NULL)
    {
        printf("Private key path not found..");
        return 1;
    }
    prikey = RSA_new();
    prikey = PEM_read_RSAPrivateKey(fp_priv, &prikey, NULL, NULL);
    if (prikey == NULL)
    {
        printf("Private key returned is NULL\n");
        return 1;
    }

    signature = (unsigned char*)malloc(RSA_size(prikey)); 

    if( signature == NULL )
        return 1;

    if(RSA_sign(NID_sha256, (unsigned char*)data, strlen(data), 
         signature, &slen, prikey) != 1) {
        ERR_print_errors_fp(stdout); 
        return 1;
    }
    printf("Signature length while signing... %d : %d : %d ",  
       strlen(signature), slen, strlen(data)); 

    FILE * sig_bin = fopen("sig_bin", "w");
    fprintf(sig_bin, "%s", signature);
    fclose(sig_bin);

    system("xxd -p -c256 sig_bin sig_hex"); 

    RSA_free(prikey);
    if(signature)
        free(signature);    
    return 0; 
} 

共有1个答案

隗高旻
2023-03-14

关于C,有一件非常非常重要的事情需要学习,那就是它有两个不同的类型,名字相同。

  • char*:这表示字符串的开头。你可以做像strstr或strlen这样的事情。
    • 你不应该是strstr或strlen,而是strnstr和strnlen,但那是一个不同的问题。

    RSA_sign使用后者。它返回“数据”,而不是“消息”。那么,在你的片段中

    printf("Signature length while signing... %d : %d : %d ",  
       strlen(signature), slen, strlen(data));
    
    FILE * sig_bin = fopen("sig_bin", "w");
    fprintf(sig_bin, "%s", signature);
    fclose(sig_bin);
    

    数据来自一个名为generate_hash()函数;它可能是非文本的,所以strlen不适用<代码>签名肯定是数据,所以strlen不适用。出于同样的原因,fprintf也不适用。这些函数通过第一次出现零字节(0x00、\0’等)来标识字符串的结尾。但是0x00在签名、散列或大量“数据”中是完全合法的。

    RSA_符号输出的长度写入传递到第5个参数的地址中。您通过了

    要以二进制形式编写签名,应该使用fwrite,例如fwrite(sig_-bin,sizeof(char),signature,slen) 。如果您希望将其作为文本,则应该对数据进行Base-64编码。

 类似资料:
  • 问题内容: 因此,我试图用Java生成ECDSAwithHA256签名,为此,我使用的是BouncyCastle提供程序。曲线是secp521r1。 要初始化我正在使用的签名者: 并签署我正在使用 现在唯一的问题是,当我运行代码时,我得到的签名长度在137到139字节之间。但我希望得到的字节数始终相同。有人知道我必须更改什么,即我的签名长度始终相同,但仍然是标准的签名格式吗? 问题答案: 通常,J

  • 所以我尝试用Java生成一个ECDSAwithHA256签名,为此,我使用了BouncyCastle提供程序。曲线是secp521r1。 要初始化我正在使用的签名者:: 为了签名,我使用 现在唯一的问题是,当我运行代码时,我得到的签名长度在137到139字节之间。但是我希望得到的字节数总是相同的。有人知道我必须改变什么吗,我总是有相同的签名长度,但仍然是标准化的签名格式?

  • 我正在尝试生成“原始”的未编码ECDSA签名,用于加密芯片。目标是在主机pc上签名,然后将其发送到芯片进行验证。然而,我遇到了一个小问题。我的理解是ECDSA签名应该是64字节(对于secp256v1)。而且,当我使用芯片生成签名时,它的长度确实是64字节。然而,当我使用openssl时,签名长度为71字节。签名的开头似乎是某种前缀,但我找不到关于它的任何数据。 以下是我尝试做每件事情的方式: 生

  • 问题内容: ECDSA算法中256位EC密钥的签名长度将是多少?我想验证签名长度是否相同。如果某个机构可以帮助我设置一个EC钥匙,那将是很棒的。 问题答案: 这取决于您如何对签名进行编码。这是OpenSSL的代码段,用于测量DER格式的ECDSA签名的长度。 以prime256曲线上的EC_KEY作为参数的上述函数的结果是 sig_len在哪里。 您需要使用位EC密钥的字节来进行DER编码的ECD

  • 我想用PHP实现一个XML数字签名。我正在这个验证器上测试签名的正确性。 我得到了错误的签名值,所以我要一步一步地解释我在做什么,请纠正我做错了什么。 我要签名的XML(无新行): 首先,我规范化XML,然后使用sha256对其进行散列,从而生成正确的摘要值。 第二,创建SignedInfo XML元素并规范化它(无新行): 最后,使用RSA-SHA256对SignedInfo元素进行签名。这是产

  • 问题内容: 我使用openssl命令对消息“ Test。”进行签名,使用hexdump输出 十六进制字符串是091bcee24b69 … 我的私钥 使用Golang生成签名 运行此代码,输出如下:52e1cce3810c1a89693cf6965d1035618820a9e3a7b95203d885c4153dc3f7424b98e3ba628a186f1074d672bb59a1c0788a9c