Getting iPhone unique id as long long value - iphone

I'm new to Iphone developing. I have next problem:
I need to get unique id for every iPhone that runs my application.
I found this great project on github:
https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5
These functions return string of 32 characters which represents some hexadecimal value.
Does someone have an idea how could I get unsigned long long value (64bit integer value) from this string?
Thanks

Please note that as for iOS 5, getting the device's UUID is deprecated by Apple and unless you're working on an in-house project, you should not do it. Apple apparently started rejecting apps doing it with no proper reason.
The best way to uniquely identify your users is by generating a GUID at startup. Please see this SO thread : UIDevice uniqueIdentifier Deprecated - What To Do Now?

You cannot fit 32 unicode characters (every one has 2 bytes, that is 64 bytes in total) into a long long which has only 8 bytes.

Luzal is right...getting the device's UDID is deprecated by Apple.
You also can use the OPEN UDID for uniquely identify your users..
downloads the classes from here-
https://github.com/ylechelle/OpenUDID
import the class -
#import "OpenUDID.h"
and use below code to get OPEN UDID
NSString * uniqueStr = [OpenUDID value];
NSLog(#"%#",uniqueStr);

Related

How to get Device Instance Path from Windows kernel driver?

Take a look at this example: a USB device in Windows 7 is reported to have Device instance path(DevinstPath) USB\VID_1EAB&PID_0501\7&25C389C1&0&1 and I know exactly that it corresponds to the so-called hardware-key(hwkey) in registry.
Now my question is: When my KMDF driver code has WDFDEVICE handle for that USB device, how can I know its DevinstPath?
I know I can
send a BusQueryDeviceID to achieve the so-called device-id USB\VID_1EAB&PID_0501;
send a BusQueryInstanceID to achieve the so-called instance-id 1 .
But I don't know how to get the so-called "instance-path". Could some kernel guru kindly tell me how I can get that?
MSDN doc seems really vague on this!
BTW: I also realize that user-layer function SetupDiGetDeviceInstanceId actually returns the DevinstPath -- although it is named "InstanceId".
Device instance path can be queried using DEVPKEY_Device_InstanceId, using either WdfDeviceAllocAndQueryPropertyEx or IoGetDevicePropertyData (passing the WDM physical device object)
Device Instance id is autoincrement sequence.
You can find HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum in registry;
Rules:NextPareneID.XXXXXXXX.N
XXXXXX use UUID Calculation crc32 values(test ok)
N is 1~9
Device Instance id format is N&PareneID&random's number&index
enter image description here

Globally unique random name for Images

I am trying to write code for generating globally unique name for images that are to be uploaded by users from iOS app to server. The names should be randomly generated and should be unique so that the images are not overwritten/replaced.
Here's my code for generating random and unique strings:
+ (NSString *)generateRandNameWithLength:(int)len
{
NSString *letters = [NSString stringWithFormat:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%#0123456789", [HJUtilities generateUniqueApId]];
NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
for (int i=0; i<len; i++) {
[randomString appendFormat: #"%C", [letters characterAtIndex: arc4random() % [letters length]]];
}
return randomString;
}
Where:
+ (NSString *)generateUniqueApId
{
NSString *appId = (__bridge NSString *) CFUUIDCreateString (NULL, CFUUIDCreate(NULL));
return appId;
}
returns a UUID.
Now I'm not sure whether this is the correct code for generating globally unique strings. I don't know how to verify this to be certain that no user will overwrite another user's image.
Note: I'm using Amazon Web services for storage. And one common bucket will be used for all the images of all users. So, its required that images names should be unique.
There is no need for the code you have. All you need is the CFUUIDCreateString function. This will be unique across all users on all devices.
From the docs for CFUUID:
UUIDs (Universally Unique Identifiers), also known as GUIDs (Globally Unique Identifiers) or IIDs (Interface Identifiers), are 128-bit values guaranteed to be unique. A UUID is made unique over both space and time by combining a value unique to the computer on which it was generated—usually the Ethernet hardware address—and a value representing the number of 100-nanosecond intervals since October 15, 1582 at 00:00:00.
The code you have now is definitely not guaranteed to be unique.
There is a new class added in iOS 6.0
#interface NSUUID : NSObject <NSCopying, NSSecureCoding>
To simplify the memory management you for sure can use it
You're overcomplicating it. Just get a UUID using CFUUIDCreateString and use that string. Adding extra layers of randomness isn't going to help. In fact, it's probably going to make things worse by increasing the chance of a name collision.
The only argument against using a UUID directly is that it may be possible to identify the source of the upload, since the UUID is (or can be) generated using device's MAC address, which is specific to the hardware. You won't be able to identify a user with nothing but a UUID, but you would be able to say "this collection of UUIDs came from the same device" or "this UUID came from this device". (See RFC 4122 for the various UUID formats and a discussion of this issue in section 4.5.)
If anonymity is a concern, running the UUID through a hash function, like SHA1 or MD5, would be good enough to make it unidentifiable.
Using a loop where you "add randomness" by mixing in random numbers is like shaking a dice for a few seconds versus an hour: the only difference is that you're rubbing sweat onto the dice.
As far as a locally unique string — which you could use as part of the file name — this is handy:
[[NSProcessInfo processInfo] globallyUniqueString]

openUDID using deprecated UDID

I'm looking at using openUDID inside my app for registration purposes.
However its still using the UDID number apple issues and so I was just reading though the .m file and came across this:
// One day, this may no longer be allowed in iOS. When that is, just comment this line out.
//
#if TARGET_OS_IPHONE
if([UIDevice instancesRespondToSelector:#selector(uniqueIdentifier)]){
_openUDID = [[UIDevice currentDevice] uniqueIdentifier];
}
#endif
// Take this opportunity to give the simulator a proper UDID (i.e. nullify UDID and create an OpenUDID)
//
#if TARGET_IPHONE_SIMULATOR
_openUDID = nil;
#endif
// Next we try to use an alternative method which uses the host name, process ID, and a time stamp
// We then hash it with md5 to get 32 bytes, and then add 4 extra random bytes
// Collision is possible of course, but unlikely and suitable for most industry needs (e.g.. aggregate tracking)
//
However I'm not sure exactly what line to comment out so that it used the alternative method which uses the host name, process ID, and a time stamp
You would comment out the 3 lines of code in the TARGET_OS_IPHONE block
You can "comment" out the line with uniqueIdentifier in it by prefixing that line using double slash comment.... or you can change the #if TARGET_OS_IPHONE line to #if 0, which means that block of code will never get called at all.
And then the alternative code will get used instead.
The way the code is currently written, it seems pretty safe to me to just leave it as is. Once Apple does completely do away with the uniqueIdentifier method, the instancesRespondToSelector call will properly fail and the alternative code will get used automatically.

iPhone 4 Unlocking. NCK-Bruteforce Research

Every iPhone has a NORID (8 bytes) & CHIPID (12 bytes) unique to each phone.
Where is this stored? NOR? seczone? Can it be dumped?
An iPhone requires a NCK to unlock. From what I understand the NCK is 15 characters.
Is it numeric, alpha or alphanumeric?
The security token for check if the NCK is valid is stored encrypted at +0x400 in the seczone.
Is this correct?
Based on what I've read from dogbert's blog, the security token is created using a method similar to the following pseudo code:
deviceKey = SHA1_hash(norID+chipID)
nckKey = custom_hash(norID, chipID, SHA1_hash(NCK), deviceKey)
rawSignature = generateSignature(SHA1_hash(norID+chipID), SHA1_hash(chipID))
Signature = RSA_encrypt(rawSignature, RSAkey)
security token = TEA_encrypt_cbc(Signature, nckKey)
Is the pseudocode correct? If it is then what is the custom hash that is being used? What is being used to generate the rawSignature? What is the RSAKey that is being used? Is it a public key that can be found in the phone?
If the above pseudocode is CORRECT. Then we would have to bruteforce all 15 character combinations to find the correct NCK key right? Because, even though we are able to recover the NORID and CHIPID, we will not be able to use that information to shorten the amount of characters which we need to find.
Correct?
New generations of iPhone OS contains a wildcardticket that is generated during activation process.
but this should be no problem generating once we have the NCK right? Correct?
The NOR ID is the hardware chip id burned into the baseband chip of the device. I don't know where you are getting the 8 bytes from but it is actually burned into the chip and the size is 64 bytes for iPhone 3G and 128 bytes for the iPhone 3GS.
The NCK is a 15 digit (base 10 so it is not alpha-numeric). ie. the max NCK would be 999999999999999
Your device key is wrong.
It should read:
deviceUniqueKey = SHA(NCK + CHIPID + NORID)
teaEncryptedData = &seczone[0x400]
rsaEncryptedData = TEA_DECRYPT(teaEncryptedData, deviceUniqueKey)
validRSAMessage = RSA_DECRYPT(rsaEncryptedData, rsaKey)
When your NCK produces a valid RSA message, you have found the correct NCK to unlock your device.
Here is the python script that can decrypt iPhone baseband memory so you will be able to get all NCK tokens like
CHIP ID
NOR ID
IMEI hushes
Tea hashes
But this script was used only for old basebands (S-Gold chipset) but you can always make your own.
Also here are some ways to dump iphone baseband into the file by using iPhone core dump function or by other script like NOR dumper. Hope this help

Is there any way to get the "Me" card from iPhone Address Book API?

So I'm stumped on this one.
In Mac OS X there is an easy way to get the "Me" card (the owner of the Mac/account) from the built-in address book API.
Has anyone found a way to find out which contact (if it exists) belongs to the owner of the iPhone?
You could use the undocumented user default:
[[NSUserDefaults standardUserDefaults] objectForKey:#"SBFormattedPhoneNumber"];
and then search the address book for the card with that phone number.
Keep in mind that since the User Default is undocumented, Apple could change at any time and you may have trouble getting into the App Store.
Another approach you could take, although it is much more fragile, is to look at the device name. If the user hasn't changed it from the default "User Name's iPhone" AND they are using their real name as an iPhone, you could grab the user name from that. Again, not the best solution by any means, but it does give you something else to try.
The generally accepted answer to this question is to file a Radar with Apple for this feature and to prompt users to choose their card.
Contacts container have a me identifier property on iOS that can be accessed using container.value(forKey: "meIdentifier")
if let containers = try? CNContactStore().containers(matching: nil) {
containers.forEach { container in
if let meIdentifier = container.value(forKey: "meIdentifier") as? String {
print("Contacts:", "meIdentifier", meIdentifier)
}
}
The identifier is a legacy identifier used in the old AddressBook framework. You can still access it in CNContact:
let iOSLegacyIdentifier = contact.value(forKey: "iOSLegacyIdentifier")
There is no such API in the iPhone SDK 2.2.1 and earlier. Please file a request for it at: http://bugreport.apple.com
Edit: [Obsolete answer]
There's no API for getting the "me" card because there is no "me" card. The iPhone's contacts app has no way of marking a card as being "me", and the API reflects this.
I came up with a partial solution to this
you can get the device name as follows
NSString *ownerName = [[UIDevice currentDevice] name];
in English a device is originally called, for example, 'Joe Blogg's iPhone'
the break out the name
NSRange t = [ownerName rangeOfString:#"’s"];
if (t.location != NSNotFound) {
ownerName = [ownerName substringToIndex:t.location];
}
you can then take that name and search the contacts
CNContactStore *contactStore = [CNContactStore new];
NSPredicate *usersNamePredicate = [CNContact predicateForContactsMatchingName:usersName];
NSArray * keysToFetch = #[[CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName],CNContactPhoneNumbersKey,CNContactEmailAddressesKey,CNContactSocialProfilesKey, ];
NSArray * matchingContacts = [contactStore unifiedContactsMatchingPredicate:usersNamePredicate keysToFetch:keysToFetch error:nil];
Of course other languages differ in the device name string e.g. 'iPhone Von Johann Schmidt' so more parsing needs to be done for other languages and it only works if the user hasn't changed the name of the device in iTunes to something like "Joes phone' but it gives you a starting point
well... it gives you an array of matching items :) So if there is more than one contact with that array you just have to use pot luck and go with the first one or work thru multiple cards and take what you need from each.
I did say its a partial solution and even though it won't work for all user cases you might find it works for many of your users and reduces a little friction