char
*
base64_encode
(
const
char
*buffer,
int
length)
{
BIO *bmem =
NULL
;
BIO *b64 =
NULL
;
BUF_MEM *bptr;
char
*buff =
NULL
;
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, buffer, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
BIO_set_close(b64, BIO_NOCLOSE);
buff = (
char
*)
malloc
(bptr->length +
1
);
memcpy
(buff, bptr->data, bptr->length);
buff[bptr->length] =
0
;
BIO_free_all(b64);
return
buff;
char
*
base64_decode
(
char
*input,
int
length)
{
BIO *b64 =
NULL
;
BIO *bmem =
NULL
;
char
*buffer =
NULL
;
buffer = (
char
*)
malloc
(length);
memset
(buffer,
0
, length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return
buffer;
int
my_verify
(
const
char
*input,
int
input_len, ECDSA_SIG *signret,
const
char
*pub_key_fn)
EC_KEY *p_dsa =
NULL
;
FILE *file =
NULL
;
int
ret =
0
;
unsigned
char
digest[EVP_MAX_MD_SIZE];
unsigned
int
digest_len =
0
;
EVP_MD_CTX md_ctx;
if
((file = fopen(pub_key_fn,
"rb"
)) ==
NULL
) {
ret =
-1
;
return
ret;
if
((p_dsa = PEM_read_EC_PUBKEY(file,
NULL
,
NULL
,
NULL
)) ==
NULL
) {
ret =
-2
;
fclose(file);
return
ret;
fclose(file);
EVP_MD_CTX_init(&md_ctx);
if
(!EVP_DigestInit(&md_ctx, EVP_sha256())) {
printf
(
"EVP_digest fail \n"
);
return
-1
;
if
(!EVP_DigestUpdate(&md_ctx, (
const
void
*)input, input_len)) {
printf
(
"EVP_DigestUpdate fail \n"
);
return
-1
;
if
(!EVP_DigestFinal(&md_ctx, digest, &digest_len)) {
printf
(
"EVP_DigestFinal fail \n"
);
return
-1
;
printf
(
"verify digest: %s\n"
, digest);
ret = ECDSA_do_verify(digest, digest_len, signret, p_dsa);
if
(ret ==
-1
) {
ret =
-3
;
printf
(
"ECDSA_verify err!\n"
);
EC_KEY_free(p_dsa);
return
ret;
}
else
if
(ret ==
0
) {
ret =
-3
;
printf
(
"ECDSA_verify err incorrect signature!\n"
);
EC_KEY_free(p_dsa);
return
ret;
}
else
{
printf
(
"ECDSA_verify ok\n"
);
printf
(
"verify is ok!\n"
);
EC_KEY_free(p_dsa);
return
0
;
int
my_sign
(
const
char
*input,
int
input_len,
const
char
*pri_key_fn)
EC_KEY *p_dsa =
NULL
;
ECDSA_SIG *s;
FILE *file =
NULL
;
unsigned
char
*data[
2
];
int
nid;
int
signlen =
0
;
int
i =
0
;
int
ret =
0
;
unsigned
char
digest[EVP_MAX_MD_SIZE];
unsigned
int
digest_len =
0
;
EVP_MD_CTX md_ctx;
memset
(data,
0x00
,
sizeof
(data));
nid =
0
;
file = fopen(pri_key_fn,
"rb"
);
if
(!file)
ret =
-1
;
return
ret;
if
((p_dsa = PEM_read_ECPrivateKey(file,
NULL
,
NULL
,
NULL
)) ==
NULL
) {
ret =
-2
;
fclose(file);
return
ret;
fclose(file);
EVP_MD_CTX_init(&md_ctx);
if
(!EVP_DigestInit(&md_ctx, EVP_sha256())) {
printf
(
"EVP_digest fail \n"
);
return
-1
;
if
(!EVP_DigestUpdate(&md_ctx, (
const
void
*)input, input_len)) {
printf
(
"EVP_DigestUpdate fail \n"
);
return
-1
;
if
(!EVP_DigestFinal(&md_ctx, digest, &digest_len)) {
printf
(
"EVP_DigestFinal fail \n"
);
return
-1
;
printf
(
"sign digest: %s\n"
, digest);
s = ECDSA_do_sign(digest, digest_len, p_dsa);
if
(s ==
NULL
) {
ret =
-3
;
EC_KEY_free(p_dsa);
return
ret;
data[
0
] = BN_bn2hex(s->r);
data[
1
] = BN_bn2hex(s->s);
EC_KEY_free(p_dsa);
ECDSA_SIG_free(s);
printf
(
"%s\n"
, data[
0
]);
printf
(
"%s\n"
, data[
1
]);
free
(data[
0
]);
free
(data[
1
]);
return
0
;
int
main
(
int
argc,
char
**argv)
char
src[
512
+
1
];
char
dst_str[
2
][
512
+
1
];
int
src_len;
int
ret;
FILE *f;
memset
(src,
0x00
,
sizeof
(src));
memset
(dst_str,
0x00
,
sizeof
(dst_str));
if
(argv[
1
][
0
] ==
's'
) {
strcpy
(src,
"hello world"
);
src_len =
strlen
(src) ;
ret = my_sign(src, src_len, argv[
2
]);
if
(ret) {
fprintf
(
stderr
,
"Error\n"
);
else
{
ECDSA_SIG *s = (ECDSA_SIG *)
malloc
(
sizeof
(ECDSA_SIG));
strcpy
(src,
"hello world"
);
strncpy
(dst_str[
0
], argv[
2
],
512
);
strncpy
(dst_str[
1
], argv[
3
],
512
);
src_len =
strlen
(src);
s->r = BN_new();
s->s = BN_new();
BN_hex2bn(&(s->r), dst_str[
0
]);
BN_hex2bn(&(s->s), dst_str[
1
]);
ret = my_verify(src, src_len, s, argv[
1
]);
if
(ret) {
fprintf
(
stderr
,
"Error\n"
);
BN_free(s->r);
BN_free(s->s);
free
(s);
return
0
;
2.编译环境
openssl版本为1.0.2g,openssl version查看openssl的版本,其他版本自行验证
base的编解码代码也有,这里demo暂不使用
gcc ecdsa.c -o ecdsa -lssl -lcrypto
4.生成私钥和公钥
openssl ecparam -genkey -name prime256v1 -out eccpri256.key
openssl ec -in eccpri256.key -pubout -out eccpri256.pem
5.运行结果
root@ubuntu:/home/workspace/test/demo_sign# ./ecdsa s eccpri256.key
sign digest: ¹M'¹M¥.Rؚ}«尣zSΩ
E948080F0496BEAF2303A184BF9F67491AB95920BD3951DBABA36813768273DF
568224ECBA9A83161E1494DAB02884B123A376DE57A9A7BA4F018A5BB9E38404
root@ubuntu:/home/workspace/test/demo_sign# ./ecdsa eccpri256.pem E948080F0496BEAF2303A184BF9F67491AB95920BD3951DBABA36813768273DF 568224ECBA9A83161E1494DAB02884B123A376DE57A9A7BA4F018A5BB9E38404
verify digest: ¹M'¹M¥.Rؚ}«尣zSΩ3*fO@
ECDSA_verify ok
verify is ok!
复制代码