本帖最后由 happyparrot 于 2011-03-03 09:10:40 编辑

解决方案 »

  1.   

    /* crypto/dsa/dsatest.c */
    /* Copyright (C) 1995-1998 Eric Young ([email protected])
     * All rights reserved.
     *
     * This package is an SSL implementation written
     * by Eric Young ([email protected]).
     * 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 ([email protected]).
     * 
     * 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 ([email protected])"
     *    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 ([email protected])"
     * 
     * 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
    #endifstatic 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
      

  2.   

    上面是OpenSSL库下面的test目录下的dsatest.c的内容,看看对你有没有用,呵呵~
      

  3.   

    曾经用它做过rsa,当时花了一些时间研究了一下,所以了解一点~
      

  4.   

    这个例子对我没啥用啊。现在找到的例子总是这样:
    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是分别给出的,而这个函数的参数却只有一个指针,不知道怎么把两个字符串传递给这一个指针啊。
      

  5.   

     #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;       }
      

  6.   

    DSA不懂,rsa和ecc知道一点,rsa验签跟签名的流程一样,最后就是一个memcmp,ecc的验签是传签名时生成的R和S,DSA平时没遇到过。
      

  7.   

    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;
      

  8.   

    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;
    }
      

  9.   

    R和S都是20个字节长。
    你说的第一句有点看不懂意思。
    应该说r,s中都是32字节呢