More secure unique ID generation and encryption

Closed #150
Closed #151
This commit is contained in:
Alex Zolotarev 2011-03-23 14:05:36 +00:00 committed by Alex Zolotarev
parent 639a20fd3d
commit 00e3a285f8
2 changed files with 53 additions and 17 deletions

View file

@ -11,6 +11,8 @@
#include <net/if_dl.h>
#include <net/if.h>
#import <UIKit/UIDevice.h>
#if !defined(IFT_ETHER)
#define IFT_ETHER 0x6 /* Ethernet CSMACD */
#endif
@ -18,8 +20,15 @@
#define TIMEOUT_IN_SECONDS 15.0
#define MAX_AUTOMATIC_RETRIES 3
NSString * GetEncryptedMac()
string GetDeviceUid()
{
NSString * uid = [[UIDevice currentDevice] uniqueIdentifier];
return [uid UTF8String];
}
string GetMacAddress()
{
string result;
// get wifi mac addr
ifaddrs * addresses = NULL;
if (getifaddrs(&addresses) == 0 && addresses != NULL)
@ -32,19 +41,29 @@ NSString * GetEncryptedMac()
{
const struct sockaddr_dl * dlAddr = (const struct sockaddr_dl *) currentAddr->ifa_addr;
const char * base = &dlAddr->sdl_data[dlAddr->sdl_nlen];
// generate sha2 hash for mac address
string const hash = sha2::digest224(base, dlAddr->sdl_alen, false);
// and use base64 encoding
return [NSString stringWithUTF8String: base64::encode(hash).c_str()];
result.assign(base, dlAddr->sdl_alen);
break;
}
currentAddr = currentAddr->ifa_next;
}
while (currentAddr->ifa_next);
freeifaddrs(addresses);
}
return nil;
return result;
}
string GetUniqueHashedId()
{
// generate sha2 hash for mac address
string const hash = sha2::digest256(GetMacAddress() + GetDeviceUid(), false);
// xor it
size_t const offset = hash.size() / 4;
string xoredHash;
for (size_t i = 0; i < offset; ++i)
xoredHash.push_back(hash[i] ^ hash[i + offset] ^ hash[i + offset * 2] ^ hash[i + offset * 3]);
// and use base64 encoding
return base64::encode(xoredHash);
}
@implementation IPhoneDownload
@ -93,9 +112,9 @@ NSString * GetEncryptedMac()
[val release];
}
NSString * macStr = GetEncryptedMac();
if (macStr)
[request addValue:macStr forHTTPHeaderField:@"User-Agent"];
// send unique id in HTTP user agent header
static string const uid = GetUniqueHashedId();
[request addValue:[NSString stringWithUTF8String: uid.c_str()] forHTTPHeaderField:@"User-Agent"];
return request;
}

View file

@ -16,8 +16,21 @@
// How many times we try to automatically reconnect in the case of network errors
#define MAX_AUTOMATIC_RETRIES 2
/// @return mac address of active interface without colons or empty string if not found
/// @note mac is converted to decimal from hex and slightly crypted
#ifdef OMIM_OS_WINDOWS
#define LOGIN_VAR "USERNAME"
#else
#define LOGIN_VAR "USER"
#endif
/// @return login name for active user and local machine hostname
static QString UserLoginAndHostname()
{
char const * login = getenv(LOGIN_VAR);
QString result(login ? login : "");
result += QHostInfo::localHostName();
return result;
}
/// @return mac address of active interface or empty string if not found
static QString MacAddress()
{
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
@ -27,11 +40,8 @@ static QString MacAddress()
QString hwAddr = iface.hardwareAddress();
if (!iface.addressEntries().empty()
&& (iface.flags() & (QNetworkInterface::IsUp | QNetworkInterface::IsRunning
| QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast))
== iface.flags()
&& hwAddr.size() == 17) // mac length with semicolons
| QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast)) == iface.flags())
{
hwAddr.remove(':');
return hwAddr;
}
}
@ -62,10 +72,17 @@ static QString UniqueClientId()
if (result.size() == 0)
result = QString("------------");
}
// add salt - login user name and local hostname
result += UserLoginAndHostname();
// calculate one-way hash
QByteArray const original = QByteArray::fromHex(result.toLocal8Bit());
string const hash = sha2::digest224(original.constData(), original.size(), false);
return base64::encode(hash).c_str();
string const hash = sha2::digest256(original.constData(), original.size(), false);
// xor hash
size_t const offset = hash.size() / 4;
string xoredHash;
for (size_t i = 0; i < offset; ++i)
xoredHash.push_back(hash[i] ^ hash[i + offset] ^ hash[i + offset * 2] ^ hash[i + offset * 3]);
return base64::encode(xoredHash).c_str();
}
static QString UserAgent()