i passing in following(the digest/hash sha1):
hash = hextobytes("9e712647173b435cf691537a76c2f1423e4a18ed"); signature = base64tobytes("aslq3wgusdkjcffwe3kvbfp7bdnjdajl2ezietr6dsiacfvasveaw9v6s3im0lnaqav2bte7ebcrmef/qb2/hw=="); pubkey16 = "04c2d0a868c35f475208b6c33a58d4ac275190f1a9d5804456ff07c42605716ef748fb4fd246163e851dbe9a942569741f54341a7c85f394b20777ab7fe526096a";//actual key lacks 04 @ front i'm guessing openssl needs this?
to function:
int misc::verify_signature(unsigned char* hash, std::vector<unsigned char> signature, char* cpubkey16) { printf("signature length: %d\n", signature.size()); int function_status = -1; ec_key *eckey = null; ec_point *pub_key; const ec_group *ecgroup; ssl_library_init(); ssl_load_error_strings(); std::string pubkeys(cpubkey16); std::vector<unsigned char> pubkeyvc = misc::hextobytes(pubkeys); const unsigned char* pubkeyvcp = pubkeyvc.data(); const unsigned char** pubkeyvcpp = &pubkeyvcp; //nid_secp256k1 not r1 .net uses eckey = ec_key_new_by_curve_name(nid_x9_62_prime256v1); //load our public key eckey = o2i_ecpublickey(&eckey, pubkeyvcpp, pubkeyvc.size()); if (!ec_key_check_key(eckey)) { printf("ec_key_check_key failed:\n"); printf("%s\n", err_error_string(err_get_error(), null)); } else { printf("public key verified ok\n"); } //create formatted signature ecdsa_sig* ec_sig = ecdsa_sig_new(); //split signature r , s value //set r if (null == bn_bin2bn(&signature[0], 32, (ec_sig->r))) { printf("failed set r value in ec signature\n"); function_status = -1; } printf("post r :%s\n", bn_bn2hex(ec_sig->r)); //set s if (null == bn_bin2bn(&signature[0] + 32, 32, (ec_sig->s))) { printf("failed set s value in ec signature\n"); function_status = -1; } printf("post s :%s\n", bn_bn2hex(ec_sig->s)); //encode signature int sig_size = i2d_ecdsa_sig(ec_sig, null); unsigned char *sig_bytes =(unsigned char *) malloc(sig_size); unsigned char *p; printf("orig sig size: %d\n", sig_size); p = sig_bytes; int new_sig_size = i2d_ecdsa_sig(ec_sig, &p); printf("new sig size: %d\n", new_sig_size); int verify_status = ecdsa_do_verify(hash, 20, ec_sig, eckey); printf("verify status: %d\n", verify_status); const int verify_success = 1; if (verify_success != verify_status) { if(verify_status==-1)handleerrors(); printf("failed verify ec signature\n"); function_status = -1; } else { printf("verifed ec signature\n"); function_status = 1; } //ec_group_free(ecgroup);//might fail ecgroup constant todo ec_key_free(eckey); return function_status; }
but cannot verify signature in openssl(verify_success 0), though exact same data verifies in c#.
any ideas why or doing wrong?
the public key in c# is:
4543533120000000c2d0a868c35f475208b6c33a58d4ac275190f1a9d5804456ff07c42605716ef748fb4fd246163e851dbe9a942569741f54341a7c85f394b20777ab7fe526096a
i'm assuming 4543533120000000 .net specific stuff pre-pended 04 rest of it.
here c# code used verify signature , successfully(sha1 of databytes identical across both programs)..
hashalgorithm hashman2 = new sha1managed(); byte[] databytes = hashman2.computehash(encoding.ascii.getbytes("h4siaaaaaaaeadpqmqbcqzbjdssm0xcmdtfuyypqajfnaisaaovfht3raaaa")); string sig = "aslq3wgusdkjcffwe3kvbfp7bdnjdajl2ezietr6dsiacfvasveaw9v6s3im0lnaqav2bte7ebcrmef/qb2/hw=="; byte[] readpublickey2 = convert.frombase64string("runtmsaaaadc0khow19hugi2wzpy1kwnuzdxqdwarfb/b8qmbxfu90j7t9jgfj6fhb6alcvpdb9unbp8hfousgd3q3/ljglq"); console.writeline("public key file read as:"); console.writeline(convert.tobase64string(readpublickey2)); using (ecdsacng ecsdkey = new ecdsacng(cngkey.import(readpublickey2, cngkeyblobformat.eccpublicblob))) { if (ecsdkey.verifydata(databytes, convert.frombase64string(sig))) { console.writeline("data , signature have been verified."); } else { console.writeline("data , signature not verified!"); } }
any appreciated.
i found issue, using .net function ecdsa.signdata, hashes data prior input(with ecdsacng.hashalgorithm), assuming taking hash input correct function ecdsa.signhash, i've switched signhash , new signature/message verifies correctly. (note may different depending on version of .net, sure check api version)
in case someone, here draft-working function(there extra/unneeded stuff in here may you):
int misc::verify_signature(std::vector<unsigned char> hash, std::vector<unsigned char> signature, char* cpubkey16) { printf("signature length: %d\n", signature.size()); int function_status = -1; ec_key *eckey = null; ec_point *pub_key; const ec_group *ecgroup; ssl_library_init(); ssl_load_error_strings(); std::string pubkeys(cpubkey16); std::vector<unsigned char> pubkeyvc = misc::hextobytes(pubkeys); printf("raw pubkey bytes: \n"); (unsigned char t : pubkeyvc) { printf("%d\n", t); } printf("raw pubkey length:%d \n", pubkeyvc.size()); const unsigned char* pubkeyvcp = pubkeyvc.data(); const unsigned char** pubkeyvcpp = &pubkeyvcp; //nid_secp256k1 not r1 .net uses eckey = ec_key_new_by_curve_name(nid_x9_62_prime256v1); ec_key_set_asn1_flag(eckey, openssl_ec_named_curve); eckey = o2i_ecpublickey(&eckey, pubkeyvcpp, pubkeyvc.size()); if (!ec_key_check_key(eckey)) { printf("ec_key_check_key failed:\n"); printf("%s\n", err_error_string(err_get_error(), null)); } else { printf("public key verified ok\n"); } //create formatted signature ecdsa_sig* ec_sig = ecdsa_sig_new(); //split signature r , s value //set r if (null == bn_bin2bn(&signature[0], 32, (ec_sig->r))) { printf("failed set r value in ec signature\n"); function_status = -1; } printf("post r :%s\n", bn_bn2hex(ec_sig->r)); ////try pad s //std::vector<unsigned char> spadded = std::vector<unsigned char>(&signature[32], &signature[32] + 32); //spadded.insert(spadded.begin(), '0'); //spadded.insert(spadded.begin(), '0'); //set s if (null == bn_bin2bn(&signature[32], 32, (ec_sig->s))) { printf("failed set s value in ec signature\n"); function_status = -1; } printf("post s :%s\n", bn_bn2hex(ec_sig->s)); //encode signature std::vector<unsigned char> rvalue = std::vector<unsigned char>(&signature[0], &signature[0] + 32); std::vector<unsigned char> svalue = std::vector<unsigned char>(&signature[32], &signature[32] + 32); std::vector<unsigned char> derencoded = std::vector<unsigned char>(); derencoded.push_back(0x30); //push payload length position later //seperator derencoded.push_back(0x02); //length of rvalue if (rvalue.at(0) >= 0x80) { derencoded.push_back(rvalue.size() + 1); } else { derencoded.push_back(rvalue.size()); } //push rvalue bytes in int c = 0; (unsigned char b : rvalue) { if (b >= 0x80 && c == 0) { derencoded.push_back(0); } derencoded.push_back(b); c++; } //seperator derencoded.push_back(0x02); //length of svalue if (svalue.at(0) >= 0x80) { derencoded.push_back(svalue.size() + 1); } else { derencoded.push_back(svalue.size()); } //push svalue bytes in c = 0; (unsigned char b : svalue) { if (b >= 0x80 && c == 0) { derencoded.push_back(0); } derencoded.push_back(b); c++; } //insert payload length in int len = derencoded.size() - 1; derencoded.insert(derencoded.begin() + 1, len); printf("encoded sig len: %d\n", derencoded.size()); printf("encoded sig64: %s\n", misc::base64_encode_d(&derencoded).c_str()); //unsigned char *p = (unsigned char*)malloc(ecdsa_size(eckey)); //int new_sig_size = i2d_ecdsa_sig(ec_sig, &p); //printf("new sig size: %d\n", new_sig_size); //for (int x = 0; x < new_sig_size; x++) { // printf("%d\n", p[x]); //} //dump der encoded sig //printf("der encoded signature\n"); //const unsigned char* pp = (unsigned char*) malloc(new_sig_size); //d2i_ecdsa_sig(&ec_sig, &pp, new_sig_size); //std::vector<unsigned char> ppvc = std::vector<unsigned char>(pp, pp+new_sig_size); //printf("base64: %s\n", misc::base64_encode_d(&ppvc).c_str()); //ecdsa_sig *signature = ecdsa_do_sign(hash, 20, eckey); //ecdsa_size(eckey); int verify_status = ecdsa_verify(0, hash.data(), hash.size(), derencoded.data(), derencoded.size(), eckey);//ecdsa_do_verify(hash.data(), hash.size(), ec_sig, eckey); printf("verify status: %d\n", verify_status); const int verify_success = 1; if (verify_success != verify_status) { if (verify_status == -1) { handleerrors(); } printf("failed verify ec signature\n"); function_status = -1; } else { printf("verifed ec signature\n"); function_status = 1; } //ec_group_free(ecgroup);//might fail ecgroup constant todo ec_key_free(eckey); return function_status; }
Comments
Post a Comment