I can't figure out why my keys aren't equal when doing this diffie hellman exchange example.
I'm using the openssl library in C (openssl/dh.h).
It seems pretty straightforward, but for some reason the keys aren't the same. What am I missing?
Any ideas? Thanks!
void hexprint(unsigned char *printBuf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%x ", printBuf[i]);
}
printf("\n");
}
int main(int argc, char *argv[])
{
srand(time(NULL));
DH *dh1;
DH *dh2;
unsigned char *dh_secret1;
unsigned char *dh_secret2;
dh1 = DH_generate_parameters(256, 2, NULL, NULL);
dh2 = DH_generate_parameters(256, 2, NULL, NULL);
DH_generate_key(dh1);
DH_generate_key(dh2);
dh_secret1 = malloc(DH_size(dh1));
memset(dh_secret1, 0, DH_size(dh1));
dh_secret2 = malloc(DH_size(dh2));
memset(dh_secret2, 0, DH_size(dh2));
DH_compute_key(dh_secret1, dh2->pub_key, dh1);
DH_compute_key(dh_secret2, dh1->pub_key, dh2);
printf("Secret Key 1: \n");
hexprint(dh_secret1, 32);
printf("Secret Key 2: \n");
hexprint(dh_secret2, 32);
free(dh_secret1);
free(dh_secret2);
DH_free(dh1);
DH_free(dh2);
}
Because in DH the users must share the same parameters.
Only perform DH_generate_parameters once, and share it between the users.
Related
So i was working on some ros based UAV simulation and it just struck me when I had to initialize separate publishers for each UAV. Is it possible to make an array of such publishers and then reference them by just using their index number? I know I should just do it and try it, but I guessed asking here would be a faster option:)
Yes this is possible by collecting multiple ros::Publishers in containers. Here is a small example using an array:
#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc, char *argv[])
{
ros::init(argc, argv, "test_node");
ros::NodeHandle nh;
ros::WallTimer timer;
//Create publishers
std::array<ros::Publisher, 3> publishers;
for (size_t i = 0; i < publishers.size(); i++)
{
std::stringstream topic_name;
topic_name << "topic" << i;
publishers[i] = nh.advertise<std_msgs::String>(topic_name.str(), 0);
}
//Publish
ros::Rate r(1);
std_msgs::String msg;
while (nh.ok())
{
std::stringstream message;
message << "Hello World " << ros::Time::now();
msg.data = message.str();
for (size_t i = 0; i < publishers.size(); i++)
{
publishers[i].publish(msg);
}
ros::spinOnce();
r.sleep();
}
return 0;
}
The node advertises the three topics
/topic0
/topic1
/topic2
and publishes a simple string like Hello World 1562571209.130936883 with a rate of 1 Hz.
I am reading a file with commands that are [a-zA-Z][a-zA-Z0-9], i.e., two chars. There is a total of 43 different commands, and I would like to transform the two chars to a number (1..43).
How would you proceed? I was thinking on creating an array of 43 unsigned shorts (two bytes) each corresponding to the two chars of each command, and then doing something like:
//char1: first char of cmd, char2: second char of cmd, lut: array of 43 shorts.
unsigned short tag;
tag = (char1 << 8) | char2;
for(int i=1;i<=43;i++) {
if(tag==lut[i-1]) return i;
}
return 0;
The thing is I'm not sure if this is the best way for doing what I want. I guess that with just 43 elements it won't matter, but that list might increase in the future.
Here is a method I used on an old project. One big drawback to this method is the lookup table and enum are dependent on each other and need to be kept synchronized. I got this method from an online article quite a few years ago, but don't remember where. This is a complete example:
#include <stdio.h>
#include <string.h>
#define CMDSIZE 2
const char* cmd_table[] = { "qu",
"qr",
"fi",
"he"};
enum { CMD_QUIT,
CMD_QUIT_RESTART,
CMD_FILE,
CMD_HELP,
CMD_NONE };
int lookup(char command[])
{
int i = 0;
int cmdlength = strlen(command);
for (i = 0; i < cmdlength; i++)
{
command[i] = tolower(command[i]);
}
const int valid_cmd = sizeof cmd_table / sizeof *cmd_table;
for (i = 0; i < valid_cmd; i++)
{
if (strcmp(command, cmd_table[i]) == 0)
return i;
}
return CMD_NONE;
}
int main()
{
char key_in[BUFSIZ];
char command[CMDSIZE+1];
// Wait for command
do
{
printf("Enter command: ");
fgets(key_in, BUFSIZ, stdin);
key_in[strlen(key_in)-1] = '\0';
strncpy(command, key_in, CMDSIZE);
command[CMDSIZE] = '\0';
switch (lookup(command))
{
case CMD_QUIT:
printf ("quit\n");
break;
case CMD_QUIT_RESTART:
printf ("quit & restart\n");
break;
case CMD_FILE:
printf ("file\n");
break;
case CMD_HELP:
printf("help\n");
break;
case CMD_NONE:
if(strcmp(key_in, ""))
printf("\"%s\" is not a valid command\n", key_in);
break;
}
} while (strcmp(command, "qu"));
return 0;
}
EDIT:
I found the article I mentioned:
https://www.daniweb.com/software-development/cpp/threads/65343/lookup-tables-how-to-perform-a-switch-using-a-string
I have the following program. It successfully obtains the raw 32 byte EC private key data and then creates a EC_KEY from it. But i2d_ECPrivateKey fails to give the size of the DER encoded private key, as it crashes. Does anyone know why and how to fix this?
#include "CBWIF.h"
#include <openssl/ssl.h>
int main(int argc, char * argv[]) {
CBWIF wif;
if (argc != 2)
return EXIT_FAILURE;
// Decode WIF string
CBByteArray str;
CBInitByteArrayFromString(&str, argv[1], false);
CBInitWIFFromString(&wif, &str, false);
CBDestroyByteArray(&str);
// Get key
uint8_t key[32];
CBWIFGetPrivateKey(&wif, key);
CBDestroyWIF(&wif);
// Create OpenSSL key
EC_KEY * eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
BIGNUM * bn = BN_bin2bn(key, CB_PRIVKEY_SIZE, NULL);
if (!EC_KEY_set_private_key(eckey, bn))
return EXIT_FAILURE;
// Convert key to DER format
int len = i2d_ECPrivateKey(eckey, NULL); // <-- CRASH HERE
unsigned char derkey[len];
i2d_ECPrivateKey(eckey, (unsigned char **)&derkey);
EC_KEY_free(eckey);
// Encode DER key as hex
char out[len*2+1];
CBBytesToString(derkey, 0, len, out, false);
// Print to stdout
puts(out);
return EXIT_SUCCESS;
}
CB_PRIVKEY_SIZE is 32. I verified that the key data from CBWIFGetPrivateKey is correct. The program crashes with the following stacktrace:
#0 0x00007ffff766cb03 in EC_POINT_point2oct () from /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#1 0x00007ffff7658124 in i2d_ECPrivateKey () from /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#2 0x0000000000400bf6 in main (argc=2, argv=0x7fffffffe038) at examples/WIF2DER.c:46
The reason is that you cannot run i2d_ECPrivateKey without setting a public key, probably due to a bug in OpenSSL. I generated the public key and solved a few other issues an now the program works:
#include "CBWIF.h"
#include <openssl/ssl.h>
int main(int argc, char * argv[]) {
CBWIF wif;
if (argc != 2)
return EXIT_FAILURE;
// Decode WIF string
CBByteArray str;
CBInitByteArrayFromString(&str, argv[1], false);
CBInitWIFFromString(&wif, &str, false);
CBDestroyByteArray(&str);
// Get key
uint8_t key[32];
CBWIFGetPrivateKey(&wif, key);
CBDestroyWIF(&wif);
// Create OpenSSL key
EC_KEY * eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
BIGNUM * bn = BN_bin2bn(key, CB_PRIVKEY_SIZE, NULL);
if (!EC_KEY_set_private_key(eckey, bn))
return EXIT_FAILURE;
// Create public key as OpenSSL cannot do this easily
EC_GROUP * group = EC_GROUP_new_by_curve_name(NID_secp256k1);
EC_POINT * point = EC_POINT_new(group);
BN_CTX * ctx = BN_CTX_new();
EC_POINT_mul(group, point, bn, NULL, NULL, ctx);
BN_CTX_free(ctx);
EC_GROUP_free(group);
BN_free(bn);
if (!EC_KEY_set_public_key(eckey, point))
return EXIT_FAILURE;
EC_POINT_free(point);
// Check the key
if (!EC_KEY_check_key(eckey))
return EXIT_FAILURE;
// Convert key to DER format
int len = i2d_ECPrivateKey(eckey, NULL);
unsigned char derkey[len];
unsigned char * derkeyPtr = derkey;
i2d_ECPrivateKey(eckey, &derkeyPtr);
// Freeing the EC_KEY here crashes for some reason???
// Encode DER key as hex
char out[len*2+1];
CBBytesToString(derkey, 0, len, out, false);
// Print to stdout
puts(out);
return EXIT_SUCCESS;
}
Here's how OpenSSL uses it in <openssl src/crypto/ec/ec_ameth.c. All the other similar uses in the library utilize i2d_ECPrivateKey_bio. Also, you might take a quick look at how the OPENSSL_EC_NAMED_CURVE flag is used with V_ASN1_OBJECT.
unsigned char *ep, *p;
int eplen, ptype;
unsigned int tmp_flags, old_flags;
...
old_flags = EC_KEY_get_enc_flags(ec_key);
tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
...
eplen = i2d_ECPrivateKey(ec_key, NULL);
if (!eplen)
{
EC_KEY_set_enc_flags(ec_key, old_flags);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
return 0;
}
ep = (unsigned char *) OPENSSL_malloc(eplen);
if (!ep)
{
EC_KEY_set_enc_flags(ec_key, old_flags);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
return 0;
}
p = ep;
if (!i2d_ECPrivateKey(ec_key, &p))
{
EC_KEY_set_enc_flags(ec_key, old_flags);
OPENSSL_free(ep);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
return 0;
}
...
Also take a look at Avoid a NULL dereference in i2d_ECPrivateKey() when an EC_KEY lacks the public key member from OpenBSD's LibReSSL project.
I'm working on decryption of encrypted MS Excel(RC4 encryption with SHA1),password is already known.In vs2010,I've could decrypt it correctly,however,my program hasto work under both Win and linux.And I have no idea to get the encryption key under linux right now,which is something like below under Win:
int getEncrypKey(HCRYPTKEY *hKey, int blocknum)
{
//------------------------H0 = H(salt, password)-----
BYTE *pbSaltandPwdHash = NULL;
DWORD dwSaltandPwdLen = 0;
pbSaltandPwdHash = SHA1_2(psalt, 16, ppwd, strlen(pwd)/2, &dwSaltandPwdLen);
printf("SHA1 of SaltandPwd:\n");
for(DWORD i = 0 ; i < dwSaltandPwdLen ; i++) {
printf("%2.2x ",pbSaltandPwdHash[i]);
}
printf("\n");
//------------------------H0 = H(salt, password)-----
//------------------------Hfinal = H(H0, block)-----
HCRYPTHASH hHash1 = 0;
CryptCreateHash( hCryptProv, CALG_SHA1, 0, 0, &hHash1) ;
CryptHashData( hHash1, pbSaltandPwdHash, dwSaltandPwdLen, 0) ;
CryptHashData( hHash1, (unsigned char*)&blocknum, sizeof(blocknum), 0) ;
//------------------------Hfinal = H(H0, block)-----
CryptDeriveKey(hCryptProv, CALG_RC4, hHash1, 0x00280000, hKey);
if(hHash1 != 0) CryptDestroyHash(hHash1);
if(pbSaltandPwdHash != NULL) free(pbSaltandPwdHash);
return 0;
}
I knew how to get H0 under linux,but I dont know how to get the hHash1 and hKey.
This post sounds like it does the same thing: Implement Windows CryptoAPI CryptDeriveKey Using OpenSSL APIs
A more general way of generating hashes in openssl is below:
Before you do anything:
#include <ssl/evp.h>
int main(int argc, char argv[]) // or in an "initialise" type function
{
OpenSSL_add_all_digests()
...
}
Then to generate the hash (error checking omitted):
const EVP_MD *digest;
EVP_MD_CTX context;
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hash_len;
digest = EVP_get_digestbyname("sha1"); /* choose the hash type here */
EVP_MD_CTX_init(&context);
EVP_DigestInit_ex(&contxt, digest, NULL);
EVP_DigestUpdate(&context, pbSaltandPwdHash, dwSaltandPwdLen);
EVP_DigestUpdate(&context, &blocknum, sizeof(blocknum));
EVP_DigestFinal_ex(&context, hash, &hash_len);
EVP_MD_CTX_cleanup(&context);
/* Now use hash and hash_len as required */
I have a definite set of strings and its corresponding numbers:
kill -> 1
live -> 2
half_kill -> 3
dont_live -> 4
List is of 30 such strings and their number mapping.
If user enters "kill", I need to return 1 and if he enters "dont_live" I need to return 4.
How should I achieve this in c program? I am looking for an efficient solution because this operation needs to be done 100s of times.
should I put them in #define in my .h file?
Thanks in advance.
Sort your table, and use the standard library function bsearch to perform a binary search.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct entry {
char *str;
int n;
};
/* sorted according to str */
struct entry dict[] = {
"dont_live", 4,
"half_kill", 3,
"kill", 1,
"live", 2,
};
int compare(const void *s1, const void *s2)
{
const struct entry *e1 = s1;
const struct entry *e2 = s2;
return strcmp(e1->str, e2->str);
}
int
main (int argc, char *argv[])
{
struct entry *result, key = {argv[1]};
result = bsearch(&key, dict, sizeof(dict)/sizeof(dict[0]),
sizeof dict[0], compare);
if (result)
printf("%d\n", result->n);
return 0;
}
Here's what you get when you run the program.
$ ./a.out kill
1
$ ./a.out half_kill
3
$ ./a.out foo
<no output>
PS: I reused portions of sidyll's program. My answer should now be CC BY-SA compliant :p
A possible solution:
#include <stdio.h>
#include <string.h>
struct entry {
char *str;
int n;
};
struct entry dict[] = {
"kill", 1,
"live", 2,
"half_kill", 3,
"dont_live", 4,
0,0
};
int
number_for_key(char *key)
{
int i = 0;
char *name = dict[i].str;
while (name) {
if (strcmp(name, key) == 0)
return dict[i].n;
name = dict[++i].str;
}
return 0;
}
int
main (int argc, char *argv[])
{
printf("enter your keyword: ");
char s[100]; scanf("%s", s);
printf("the number is: %d\n", number_for_key(s));
return 0;
}
Here's one approach:
int get_index(char *s)
{
static const char mapping[] = "\1.kill\2.live\3.half_kill\4.dont_live";
char buf[sizeof mapping];
const char *p;
snprintf(buf, sizeof buf, ".%s", s);
p = strstr(mapping, buf);
return p ? p[-1] : 0;
}
The . mess is to work around kill being a substring of half_kill. Without that issue you could simply search for the string directly.
If it is a very short list of strings then a simple block of ifs will be more than sufficient
if (0 == strcmp(value, "kill")) {
return 1;
}
if (0 == strcmp(value, "live")) {
return 2;
}
...
If the number approach 10 I would begin to profile my application though and consider a map style structure.
if you have a fixed set of strimgs, you have two options: generate a perfect hashing function (check gperf or cmph) or create a trie so that you never have to check charcters more than once.
Compilers usually use perfect hashes to recognize a language keyword, in your case I would probably go with the trie, it should be the fastest way (but nothing beats direct measurement!)
Is it really a bottleneck? You should worry about efficiency only if the simple solution proves to be too slow.
Having said that, possible speed improvements are checking the lengths first:
If it's 4 characters then it could be "kill" or "live"
If it's 9 characters then it could be "half_kill" or "dont_live"
or checking the first character in a switch statement:
switch (string[0]) {
case 'k':
if (strcmp(string, "kill") == 0)
return 1;
return 0;
case 'l':
...
default:
return 0;
}
Use hashmap/ hashtable i think this would be the best solution.
Can you use an Enumunerator?
int main(void) {
enum outcome { kill=1, live, half_kill, dont_live };
printf("%i\n", kill); //1
printf("%i\n", dont_live); //4
printf("%i\n", half_kill); //3
printf("%i\n", live); //2
return 0;
}
Create a list of const values:
const int kill = 1;
const int live = 2;
const int half_kill = 3;
etc