Skip to content

Instantly share code, notes, and snippets.

@dafanasiev
Created April 24, 2015 09:18
Show Gist options
  • Save dafanasiev/5405a88a19a78f129b37 to your computer and use it in GitHub Desktop.
Save dafanasiev/5405a88a19a78f129b37 to your computer and use it in GitHub Desktop.
MobileVIP Auth
#include "assert.h"
#include <string>
#include <iomanip>
#include <iostream>
#include <vector>
#include <openssl/evp.h>
#include <openssl/ecdh.h>
#include <openssl/aes.h>
#include <openssl/sha.h>
void print_hex(unsigned char* p, size_t len){
for (size_t i = 0; i < len; ++i) { printf("%02x", p[i]); }
}
static void *KDF1_SHA256(const void *in, size_t inlen,
void *out, size_t *outlen)
{
if (*outlen < SHA256_DIGEST_LENGTH)
return NULL;
else
*outlen = SHA256_DIGEST_LENGTH;
return SHA256((unsigned char*)in, inlen, (unsigned char*)out);
}
int _tmain(int argc, _TCHAR* argv[])
{
int rv;
OpenSSL_add_all_algorithms();
EC_KEY* client_key_curve, *server_key_curve;
EC_POINT* client_publicKey, *server_publicKey;
EC_GROUP* client_key_group, *server_key_group;
auto bn_ctx = BN_CTX_new();
BN_CTX_start(bn_ctx);
auto client_publicK_x = BN_CTX_get(bn_ctx);
auto client_publicK_y = BN_CTX_get(bn_ctx);
auto client_privatKey = BN_CTX_get(bn_ctx);
auto server_publicK_x = BN_CTX_get(bn_ctx);
auto server_publicK_y = BN_CTX_get(bn_ctx);
//auto nid = EC_curve_nist2nid("P-521");
//auto client_key_curve_group = EC_GROUP_new_by_curve_name(nid);
//client_key_curve = EC_KEY_new();
//EC_KEY_set_group(client_key_curve, client_key_curve_group);
if ((client_key_curve = EC_KEY_new_by_curve_name(NID_secp521r1)) == NULL)
assert(0);
if ((client_key_group = (EC_GROUP *)EC_KEY_get0_group(client_key_curve)) == NULL)
assert(0);
if (EC_KEY_generate_key(client_key_curve) != 1)
assert(0);
if ((client_publicKey = (EC_POINT *)EC_KEY_get0_public_key(client_key_curve)) == NULL)
assert(0);
if (EC_KEY_check_key(client_key_curve) != 1)
assert(0);
client_privatKey = (BIGNUM *)EC_KEY_get0_private_key(client_key_curve);
char *client_public_key = EC_POINT_point2hex(client_key_group, client_publicKey, POINT_CONVERSION_UNCOMPRESSED, bn_ctx);
char *client_privat_key = BN_bn2hex(client_privatKey);
std::string _clientPublicKey = client_public_key;
_clientPublicKey = _clientPublicKey.substr(2);
std::cout << "My Public key:" << _clientPublicKey << std::endl;
std::string _serverPublicKey;
std::cout << "Server Public key ?>";
std::cin >> _serverPublicKey;
_serverPublicKey = "04" + _serverPublicKey;
if ((server_key_curve = EC_KEY_new_by_curve_name(NID_secp521r1)) == NULL)
assert(0);
if ((server_key_group = (EC_GROUP *)EC_KEY_get0_group(server_key_curve)) == NULL)
assert(0);
if ((server_publicKey = EC_POINT_new(server_key_group)) == NULL)
assert(0);
if (EC_POINT_hex2point(server_key_group, _serverPublicKey.c_str(), server_publicKey, bn_ctx) != server_publicKey)
assert(0);
unsigned char *key_agreement = NULL;
key_agreement = (unsigned char *)OPENSSL_malloc(SHA256_DIGEST_LENGTH);
if (ECDH_compute_key(key_agreement, SHA256_DIGEST_LENGTH, server_publicKey, client_key_curve, KDF1_SHA256) == 0)
assert(0);
std::cout << "Shared Secret Key:";
print_hex(key_agreement, SHA256_DIGEST_LENGTH);
std::cout << std::endl;
std::string clientPassword;
std::cout << "Password (string)?>";
std::cin >> clientPassword;
{
std::vector<unsigned char> encrypted;
size_t max_output_len = clientPassword.length() + 16 - (clientPassword.length() % 16);
encrypted.resize(max_output_len);
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
unsigned char iv[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// Enc is 1 to encrypt, 0 to decrypt, or - 1 (see documentation).
EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key_agreement, iv, 1);
int actual_size = 0;
EVP_CipherUpdate(&ctx,
&encrypted[0], &actual_size,
reinterpret_cast<unsigned char *>(&clientPassword[0]), clientPassword.length());
int final_size;
EVP_CipherFinal_ex(&ctx, &encrypted[actual_size], &final_size);
actual_size += final_size;
encrypted.resize(actual_size);
std::cout << "Encrypted password:";
for (size_t index = 0; index < encrypted.size(); ++index)
{
std::cout << std::hex << std::setw(2) << std::setfill('0') <<
static_cast<unsigned int>(encrypted[index]);
}
std::cout << "\n";
EVP_CIPHER_CTX_cleanup(&ctx);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment