用过OpenSSL的DSA的请帮助解惑

快乐鹦鹉 2011-03-03 09:08:57
DSA算法中的签名包括R和S两项数据,但OpenSSL的签名验证函数DSA_verify中,对于签名参数只包含一个指针参数和指针长度参数,那么,R和S两项数据如何作为指针参数传递呢???

int DSA_verify(int type,const unsigned char *dgst,int dgst_len,
const unsigned char *sigbuf, int siglen, DSA *dsa);
第一个参数是加密方式,应该是NID_SHA1
第二个参数是摘要,第三个是摘要的长度
第四个参数是签名,第五个参数是签名的长度
第六个参数是公钥

现在如何把R和S传递给第四个参数呢???

如能成功解决,本贴再加100分感谢。
...全文
456 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
t514901334 2013-06-06
  • 打赏
  • 举报
回复
引用 8 楼 happyparrot 的回复:
[Quote=引用 5 楼 jennyvenus 的回复:] 验签时传数据与签名结果进去,验签再算一个签名比较。 R与S是一样长的吧。 [/Quote] R和S都是20个字节长。 你说的第一句有点看不懂意思。
应该说r,s中都是32字节呢
shi5661 2013-03-26
  • 打赏
  • 举报
回复
一点也不懂。
愤豆 2013-03-05
  • 打赏
  • 举报
回复
DSA签名,验证(读取证书) 2012-01-03 09:47:27| 分类: OpenSSL | 标签: |字号大中小 订阅 . 网上的资料,真的是参差不齐阿,有的完全是在浪费你的时间!签名的输入都用到了md5哈希。 先用命令行生成整数,然后再进行DSA签名认证! openssl dsaparam -noout -out dsakey-pri.pem -genkey 1024 openssl dsa -in dsakey-pri.pem -pubout -out dsakey-pub.pem #include <string.h> #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/dsa.h> unsigned int sig_len; unsigned char* dsa_sign(unsigned char *input_string) { DSA *dsa; FILE *file; unsigned char* sign_string; if ((file = fopen("/home/zc/SSL/dsakey-pri.pem", "r")) == NULL) { perror("open pri key file error"); } //读取私钥 if ((dsa = PEM_read_DSAPrivateKey(file, NULL, NULL, NULL)) == NULL) { ERR_print_errors_fp(stdout); } //分配给签名的信息 sign_string = (unsigned char*) calloc(DSA_size(dsa), sizeof(unsigned char)); if (sign_string == NULL) { fprintf(stderr, "Unable to allocate memory for sign_string\n"); exit(-1); } // sign input_string if (DSA_sign(NID_md5, input_string, strlen((char*) input_string), sign_string, &sig_len, dsa) == 0) { printf("Sign Error.\n"); } return sign_string; } int dsa_verify(unsigned char* sign_string, unsigned char* input_string) { DSA *dsa; FILE *file; if ((file = fopen("/home/zc/SSL/dsakey-pub.pem", "r")) == NULL) { perror("open pub key file error"); } if ((dsa = PEM_read_DSA_PUBKEY(file, NULL, NULL, NULL)) == NULL) { ERR_print_errors_fp(stdout); return 0; } int is_valid_signature = DSA_verify(NID_md5, input_string, strlen( (char*) input_string), sign_string, sig_len, dsa); return is_valid_signature; } int DSA_func(unsigned char *input_str) { int i, ans; unsigned char* input_string; unsigned char* sign_string; //分配空间给哈希 input_string = (unsigned char*) calloc(128, sizeof(unsigned char)); if (input_string == NULL) { fprintf(stderr, "Unable to allocate memory for input_string\n"); exit(-1); } input_string = MD5_func(input_str); sign_string = dsa_sign(input_string); ans = dsa_verify(sign_string, input_string); printf("input string = %s\n", input_str); printf("signed string = "); for (i = 0; i < sig_len; ++i) { printf("%x%x", (sign_string[i] >> 4) & 0xf, sign_string[i] & 0xf); } printf("\n"); printf("is_valid_signature? = %d\n", ans); return ans; }
cnfitc 2012-12-14
  • 打赏
  • 举报
回复
int DSA_do_verify(const unsigned char *dgst,int dgst_len, DSA_SIG *sig,DSA *dsa); typedef struct DSA_SIG_st { BIGNUM *r; BIGNUM *s; } DSA_SIG;
快乐鹦鹉 2011-03-04
  • 打赏
  • 举报
回复
伊人何在
用户 昵称 2011-03-04
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 happyparrot 的回复:]
引用 5 楼 jennyvenus 的回复:
验签时传数据与签名结果进去,验签再算一个签名比较。

R与S是一样长的吧。

R和S都是20个字节长。
你说的第一句有点看不懂意思。
[/Quote]
DSA不懂,rsa和ecc知道一点,rsa验签跟签名的流程一样,最后就是一个memcmp,ecc的验签是传签名时生成的R和S,DSA平时没遇到过。
快乐鹦鹉 2011-03-03
  • 打赏
  • 举报
回复
这个例子对我没啥用啊。现在找到的例子总是这样:
DSA_sign(0, str1, 20, sig, &siglen, dsa);
if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
ret=1;

这没有意义啊,自己先签名,然后再验证,当然没有问题啊。这种样例根本没有参考价值。

实际情况都是有文件形式的证书,然后对证书进行验证,也就是不可能同时进行签名和验证,这两个过程分别由数据提供方和接收方进行,怎么可能一起使用呢。

现在的问题是,DSA_verify函数的参数sig怎么传递?实际得到的签名是在一个文本文件中,并且两个参数R和S是分别给出的,而这个函数的参数却只有一个指针,不知道怎么把两个字符串传递给这一个指针啊。
Chivalry 2011-03-03
  • 打赏
  • 举报
回复
曾经用它做过rsa,当时花了一些时间研究了一下,所以了解一点~
Chivalry 2011-03-03
  • 打赏
  • 举报
回复
上面是OpenSSL库下面的test目录下的dsatest.c的内容,看看对你有没有用,呵呵~
Chivalry 2011-03-03
  • 打赏
  • 举报
回复
/* crypto/dsa/dsatest.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/

/* Until the key-gen callbacks are modified to use newer prototypes, we allow
* deprecated functions for openssl-internal code */
#ifdef OPENSSL_NO_DEPRECATED
#undef OPENSSL_NO_DEPRECATED
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "../e_os.h"

#include <openssl/crypto.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/bn.h>

#ifdef OPENSSL_NO_DSA
int main(int argc, char *argv[])
{
printf("No DSA support\n");
return(0);
}
#else
#include <openssl/dsa.h>

#ifdef OPENSSL_SYS_WIN16
#define MS_CALLBACK _far _loadds
#else
#define MS_CALLBACK
#endif

static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg);

/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
* FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
static unsigned char seed[20]={
0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
};

static unsigned char out_p[]={
0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91,
};

static unsigned char out_q[]={
0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
0xda,0xce,0x91,0x5f,
};

static unsigned char out_g[]={
0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02,
};

static const unsigned char str1[]="12345678901234567890";

static const char rnd_seed[] = "string to make the random number generator think it has entropy";

static BIO *bio_err=NULL;

int main(int argc, char **argv)
{
BN_GENCB cb;
DSA *dsa=NULL;
int counter,ret=0,i,j;
unsigned char buf[256];
unsigned long h;
unsigned char sig[256];
unsigned int siglen;

if (bio_err == NULL)
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

CRYPTO_malloc_debug_init();
CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

ERR_load_crypto_strings();
RAND_seed(rnd_seed, sizeof rnd_seed);

BIO_printf(bio_err,"test generation of DSA parameters\n");

BN_GENCB_set(&cb, dsa_cb, bio_err);
if(((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512,
seed, 20, &counter, &h, &cb))
goto end;

BIO_printf(bio_err,"seed\n");
for (i=0; i<20; i+=4)
{
BIO_printf(bio_err,"%02X%02X%02X%02X ",
seed[i],seed[i+1],seed[i+2],seed[i+3]);
}
BIO_printf(bio_err,"\ncounter=%d h=%ld\n",counter,h);

if (dsa == NULL) goto end;
DSA_print(bio_err,dsa,0);
if (counter != 105)
{
BIO_printf(bio_err,"counter should be 105\n");
goto end;
}
if (h != 2)
{
BIO_printf(bio_err,"h should be 2\n");
goto end;
}

i=BN_bn2bin(dsa->q,buf);
j=sizeof(out_q);
if ((i != j) || (memcmp(buf,out_q,i) != 0))
{
BIO_printf(bio_err,"q value is wrong\n");
goto end;
}

i=BN_bn2bin(dsa->p,buf);
j=sizeof(out_p);
if ((i != j) || (memcmp(buf,out_p,i) != 0))
{
BIO_printf(bio_err,"p value is wrong\n");
goto end;
}

i=BN_bn2bin(dsa->g,buf);
j=sizeof(out_g);
if ((i != j) || (memcmp(buf,out_g,i) != 0))
{
BIO_printf(bio_err,"g value is wrong\n");
goto end;
}

dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME;
DSA_generate_key(dsa);
DSA_sign(0, str1, 20, sig, &siglen, dsa);
if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
ret=1;

dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME;
DSA_generate_key(dsa);
DSA_sign(0, str1, 20, sig, &siglen, dsa);
if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
ret=1;

end:
if (!ret)
ERR_print_errors(bio_err);
if (dsa != NULL) DSA_free(dsa);
CRYPTO_cleanup_all_ex_data();
ERR_remove_state(0);
ERR_free_strings();
CRYPTO_mem_leaks(bio_err);
if (bio_err != NULL)
{
BIO_free(bio_err);
bio_err = NULL;
}
#ifdef OPENSSL_SYS_NETWARE
if (!ret) printf("ERROR\n");
#endif
EXIT(!ret);
return(0);
}

static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg)
{
char c='*';
static int ok=0,num=0;

if (p == 0) { c='.'; num++; };
if (p == 1) c='+';
if (p == 2) { c='*'; ok++; }
if (p == 3) c='\n';
BIO_write(arg->arg,&c,1);
(void)BIO_flush(arg->arg);

if (!ok && (p == 0) && (num > 1))
{
BIO_printf((BIO *)arg,"error in dsatest\n");
return 0;
}
return 1;
}
#endif
xengine-qyt 2011-03-03
  • 打赏
  • 举报
回复
我只是拷贝过去的。没弄过!能帮就帮呗,别这么大意见 没弄过!
快乐鹦鹉 2011-03-03
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jennyvenus 的回复:]
验签时传数据与签名结果进去,验签再算一个签名比较。

R与S是一样长的吧。
[/Quote]
R和S都是20个字节长。
你说的第一句有点看不懂意思。
快乐鹦鹉 2011-03-03
  • 打赏
  • 举报
回复
楼上的,拜托看完贴再回好不好哦......
xengine-qyt 2011-03-03
  • 打赏
  • 举报
回复


#include <string.h>

#include <openssl/objects.h>

#include <openssl/dsa.h>



int main()

{

int ret;

DSA *d;

int i,bits=1024,signlen,datalen,alg,nid;

unsigned chardata[100],signret[200];



d=DSA_new();

ret=DSA_generate_parameters_ex(d,512,NULL,0,NULL,NULL,NULL);

if(ret!=1)

{

DSA_free(d);

return -1;

}

ret=DSA_generate_key(d);

if(ret!=1)

{

DSA_free(d);

return -1;

}

for(i=0;i<100;i++)

memset(&data[i],i+1,1);

printf("please select digest alg: \n");

printf("1.NID_md5\n");

printf("2.NID_sha\n");

printf("3.NID_sha1\n");

printf("4.NID_md5_sha1\n");

scanf("%d",&alg);

if(alg==1)

{

datalen=20;

nid=NID_md5;

}

else if(alg==2)

{

datalen=20;

nid=NID_sha;

}

else if(alg==3)

{

datalen=20;

nid=NID_sha1;

}

else if(alg==4)

{

datalen=20;

nid=NID_md5_sha1;

}

ret=DSA_sign(nid,data,datalen,signret,&signlen,d);

if(ret!=1)

{

printf("DSA_sign err!\n");

DSA_free(d);

return -1;

}

ret=DSA_verify(nid,data,datalen,signret,signlen,d);

if(ret!=1)

{

printf("DSA_verify err!\n");

DSA_free(d);

return -1;

}

DSA_free(d);

printf("test ok!\n");

return 0;

}



用户 昵称 2011-03-03
  • 打赏
  • 举报
回复
验签时传数据与签名结果进去,验签再算一个签名比较。

R与S是一样长的吧。

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧