每一個可以努力的日子,都是一份厚禮。
DSA簽名與驗證——使用openssl編程
和手寫簽名一樣,數字簽名可以為我們驗證文檔的作者、簽名的時間,從而鑒明消息的內容是真實可靠的。它的目的和MAC類似,只是使用的是公鑰加密體系。
和RSA加密解密過程相反,在DSA數字簽名和認證中,發送者使用自己的私鑰對文件或消息進行簽名,接受者收到消息後使用發送者的公鑰來驗證簽名的真實性。這個方法完全可以基於RSA來實現,但是在DSA中,我們會更有效率地做這件事情。
最直接的想法是,直接對消息m進行簽名。假設發送者的公鑰為K+,私鑰為K-,即將K-(m)發送給消息接收者,在接收方執行驗證 m = K+(K-(m))。然而我們知道,非對稱密鑰體系一個最大的缺點就是速度很慢,如果我們需要傳送一個1G大小的文件,則加密解密簽名驗證都需要耗費大量的時間。於是,我們想到,可以使用一個哈希函數對消息進行摘要,對摘要進行簽名和驗證,就快多了。
DSS是美國國家標準局和國家安全局在90年代初期通過的一項標準,它使用了SHA哈希函數生成摘要。DSA只是一種算法,和RSA不同之處在於它不能用作加密和解密,也不能進行密鑰交換,只用於簽名。它比RSA要快很多。
下面是使用openssl進行DSA簽名和驗證的示例程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* * dsa.cc * - Show the usage of DSA sign/verify */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <openssl/dsa.h> int main(int argc, char** argv) { DSA* dsa; unsigned char* input_string; unsigned char* sign_string; unsigned int sig_len; unsigned int i; // check usage if (argc != 2) { fprintf(stderr, "%s <plain text>\n", argv[0]); exit(-1); } // set the input string input_string = (unsigned char*)calloc(strlen(argv[1]) + 1, sizeof(unsigned char)); if (input_string == NULL) { fprintf(stderr, "Unable to allocate memory for input_string\n"); exit(-1); } strncpy((char*)input_string, argv[1], strlen(argv[1])); // Generate random DSA parameters with 1024 bits dsa = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, NULL, NULL); // Generate DSA keys DSA_generate_key(dsa); // alloc sign_string 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(0, input_string, strlen((char*)input_string), sign_string, &sig_len, dsa) == 0) { fprintf(stderr, "Sign Error.\n"); exit(-1); } // verify signature and input_string int is_valid_signature = DSA_verify(0, input_string, strlen((char*)input_string), sign_string, sig_len, dsa); // print DSAparams_print_fp(stdout, dsa); printf("input_string = %s\n", input_string); 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", is_valid_signature); return 0; } |
編譯Makefile:
CC=g++ CFLAGS=-Wall -g -O2 LIBS=-lcrypto all: dsa dsa: dsa.cc $(CC) $(CFLAGS) dsa.cc -o $@ $(LIBS) clean: @rm -f dsa |
這篇文章由lovelucy於2011-01-04 15:27發表在信息安全。你可以訂閱RSS 2.0 也可以發表評論或引用到你的網站。除特殊說明外文章均為本人原創,並遵從署名-非商業性使用-相同方式共享創作協議,轉載或使用請註明作者和來源,尊重知識分享。 |
批評不自由
則讚美無意義