每一个可以努力的日子,都是一份厚礼。
DSA签名与验证——使用openssl编程
2011-01-04 15:27
和手写签名一样,数字签名可以为我们验证文档的作者、签名的时间,从而鉴明消息的内容是真实可靠的。它的目的和MAC类似,只是使用的是公钥加密体系。
和RSA加密解密过程相反,在DSA数字签名和认证中,发送者使用自己的私钥对文件或消息进行签名,接受者收到消息后使用发送者的公钥来验证签名的真实性。这个方法完全可以基于RSA来实现,但是在DSA中,我们会更有效率地做这件事情。
最直接的想法是,直接对消息m进行签名。假设发送者的公钥为K+,私钥为K-,即将K-(m)发送给消息接收者,在接收方执行验证 m = K+(K-(m))。然而我们知道,非对称密钥体系一个最大的缺点就是速度很慢,如果我们需要传送一个1G大小的文件,则加密解密签名验证都需要耗费大量的时间。于是,我们想到,可以使用一个哈希函数对消息进行摘要,对摘要进行签名和验证,就快多了。
DSS是美国国家标准局和国家安全局在90年代初期通过的一项标准,它使用了SHA哈希函数生成摘要。DSA只是一种算法,和RSA不同之处在于它不能用作加密和解密,也不能进行密钥交换,只用于签名。它比RSA要快很多。
下面是使用openssl进行DSA签名和验证的示例程序:
/*
* dsa.cc
* - Show the usage of DSA sign/verify
*/
#include
#include
#include
#include
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 \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> 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 也可以发表评论或引用到你的网站。除特殊说明外文章均为本人原创,并遵从署名-非商业性使用-相同方式共享创作协议,转载或使用请注明作者和来源,尊重知识分享。 |

批评不自由
则赞美无意义