Is it possible to declare one's own [mini] namespace within an NSUUID? - swift

The Wikipedia page https://en.wikipedia.org/wiki/Universally_unique_identifier states that in version 3 (and therefore presumably 5) of the UUID spec: "Six bits are replaced by fixed values"
I am working on an iPhone app that utilises the NSUUID class. My client has asked for the ability to declare his own small fixed set of chars within the full UUID string. From what I have read thus far, I don't think this is possible - for just loads for understandable reasons - however I am obliged to ask whether there is a way, so that I can answer/deflect his questions with surety.
So is there or not, please?
Thanks in advance.

Is it possible? Of course; but unless your client's iPhone app lives in an alternate universe, perhaps your client's iPhone app would be better served by sticking to the versions described by the RFC 4122 variant.
It might be helpful to sit down with your client and explain the uuid layout. You might consider using Mahonri Moriancumer's UUID and GUID Generator and Forensics to demonstrate UUID options.
Update: In thinking this through a bit more, there is a way to add a signature to generated UUIDs...
Consider the version 1 UUID structure (RFC 4122 variant). For this type of UUID, the last 12 digits represent the MAC address of the computer's ethernet card that generated the UUID.
If you were to get the MAC address from a specific ethernet card (even an old, obsolete one), and then destroy the card, you could be assured that no other computer will ever generate a UUID (v1) using that ethernet card's MAC address ever again. Then you could use that MAC address as your "own small fixed set of chars within the full UUID string".
Then, just write your own UUID v1 generator that uses this mac address as the last 12 digits of the UUID. The rest of the UUID digits could comply with the v1 spec. The resulting generated UUIDs would be fully complient with the v1 spec, and could be identified (as a set) by the last 12 digits.

Related

Does Swift Foundation's UUID incorporate the time by default?

Does the Swift UUID type take into account the time it was created to help guarantee its uniqueness or is it purely random? If not, is there a version that does?
I quote the documentation:
Initializes a new UUID with RFC 4122 version 4 random bytes.
So it is entirely random. There is a post already describing how to create the time based UUID over here.

How can SystemInfo.deviceUniqueIdentifier be unique?

According to http://docs.unity3d.com/ScriptReference/SystemInfo-deviceUniqueIdentifier.html, SystemInfo.deviceUniqueIdentifier
It is guaranteed to be unique for every device (Read Only).
If you delete and reinstall your application, this value will change. How can it guarantee that there isn't another iPhone in the world that happened to generate the same identifier?
(I know that the identifier is pretty long so it is quite unlikely for this to happen - but I'd like to know why)
As the description says, it's typically some form of device ID, set by the vendor:
iOS: on pre-iOS7 devices it will return hash of MAC address. On iOS7
devices it will be UIDevice identifierForVendor or, if that fails for
any reason, ASIdentifierManager advertisingIdentifier.
Windows Store
Apps: uses AdvertisingManager::AdvertisingId for returning unique
device identifier, if option in 'PC Settings -> Privacy -> Let apps
use my advertising ID for experiences across apps (turning this off
will reset your ID)' is disabled, Unity will fallback to
HardwareIdentification::GetPackageSpecificToken().Id.
Even if these values were random, they come out in the same format as a GUID with 32 hexadecimal characters (128bits). The number of possibilities is rather large.
From Wikipedia:
The total number of unique such GUIDs is 2^122 (approximately 5.3×10^36). This number is so large that the probability of the same number being
generated randomly twice is negligible; however other GUID versions
have different uniqueness properties and probabilities, ranging from
guaranteed uniqueness to likely duplicates. Assuming uniform
probability for simplicity, the probability of one duplicate would be
about 50% if every person on earth as of 2014 owned 600 million GUIDs.

Using MD5 checksum to uniquely address a binary content in DB

I need to take binary (images and pdf's) from one environment to another .
These binaries are referenced in a main document mostly HTML Doc as Title and Version No: .
The problem is that we have a versioning ,So an HTML DOC might reead to img src=(Logo1 + Version 2) . The Title is good for me , but the Version is system generated for the host system's use .
I need take the HTML Doc to another system - I can ofcourse insert the Logo assosiated - I don't want to just insert the image(or pdf) , if it is already available in the destination system . Can I use a combination of Title + MD5 Checksum to check if the destination system already has the same content possibly with a different Version No:. I think the chances of a collision is bare minmal with this approach ? We have Md5's stored in our document manager system
The chances for collisions depend on the number of documents you have to store, but should be sufficiently low.
But this assumes nobody actually tries to create collisions. MD5 is considered broken, so if somebody could benefit from causing collisions on your end he/she might be able to pull that of.
Therefore I'd recommend a more secure hash function. It shouldn't make much of a difference for your effort which one you use.
See also this question and answer: What is the clash rate for md5?

major and minor device numbers

I am reading linux device driver book of rubini,corbet and hartmen.I have doubt regarding dynamic allocation of major and minor device numbers.They say
The disadvantage of dynamic assignment is that you can’t create the device nodes in
advance, because the major number assigned to your module will vary.For normal
use of the driver, this is hardly a problem, because once the number has been
assigned, you can read it from /proc/devices.
1)What does it mean by advance here?
2)Why major and minor numbers must be read from /proc/devices when function alloc_chrdev_region provides major and minor numbers in the argument sent to it.can that argument sent, not be used directly?
Thanks in advance
1) Dynamic assignment would mean that you cannot create device nodes before the driver is loaded, for example having them as a static part of the filesystem when the system boots. Instead you could only create them once you discover what their major/minor numbers are this time.
2) The driver may know what it's major and minor numbers are, but the device nodes should be created by something in userspace. They are suggesting that if this information cannot be given in advance in parallel to both the kernel driver and userspace, then userspace will have to discover it at runtime from something such as /proc/devices.
When we assign a major number dynamically to a device driver, we are not aware with the Major Number till the alloc_chrdev_region function finishes execution or let's say that you don't get to know the Major Number before you insert the module into the kernel (and for this we use insmod). And so you cannot create a node for your driver (for which we use mknod) unless you load a device driver, this is referred to as advanced by the author.
We read /proc/devices for Major and Minor Numbers of one device driver when a different device/program needs them.

Encrypting SQLite Database file in iPhone OS

Any SQLite database on the iPhone is simply a file bundled with the application. It is relatively simple for anyone to extract this file and query it.
What are your suggestions for encrypting either the file or the data stored within the database.
Edit: The App is a game that will be played against other users. Information about a users relative strengths and weaknesses will be stored in the DB. I don't want a user to be able to jail-break the phone up their reputation/power etc then win the tournament/league etc (NB: Trying to be vague as the idea is under NDA).
I don't need military encryption, I just don't want to store things in plain text.
Edit 2: A little more clarification, my main goals are
Make it non-trivial to hack sensitive data
Have a simple way to discover if data has been altered (some kind of checksum)
You cannot trust the client, period. If your standalone app can decrypt it, so will they. Either put the data on a server or don't bother, as the number of people who actually crack it to enhance stats will be minuscule, and they should probably be rewarded for the effort anyway!
Put a string in the database saying "please don't cheat".
There are at least two easier approaches here (both complimentary) that avoid encrypting values or in-memory databases:
#1 - ipa crack detection
Avoid the technical (and legal) hassle of encrypting the database and/or the contents and just determine if the app is pirated and disable the network/scoring/ranking aspects of the game. See the following for more details:
http://thwart-ipa-cracks.blogspot.com/2008/11/detection.html
#2 - data integrity verification
Alternatively store a HMAC/salted hash of the important columns in each row when saving your data (and in your initial sqlite db). When loading each row, verify the data against the HMAC/hash and if verification fails act accordingly.
Neither approach will force you to fill out the encryption export forms required by Apple/US government.
Score submission
Don't forget you'll need to do something similar for the actual score submissions to protect against values coming from something other than your app. You can see an implementation of this in the cocos2d-iphone and cocoslive frameworks at http://code.google.com/p/cocos2d-iphone/ and http://code.google.com/p/cocoslive/
Response to comments
There is no solution here that will 100% prevent data tampering. If that is a requirement, the client needs to be view only and all state and logic must be calculated on a trusted server. Depending on the application, extra anti-cheat mechanisms will be required on the client.
There are a number of books on developing massively-multiplayer games that discuss these issues.
Having a hash with a known secret in the code is likely a reasonable approach (at least, when considering the type of applications that generally exist on the App Store).
Like Kendall said, including the key on the device is basically asking to get cracked. However, there are folks who have their reasons for obfuscating data with a key on-device. If you're determined to do it, you might consider using SQLCipher for your implementation. It's a build of SQLite that provides transparent, page-level encryption of the entire DB. There's a tutorial over on Mobile Orchard for using it in iPhone apps.
How likely do you think it is that your normal user will be doing this? I assume you're going through the app store, which means that everything is signed/encrypted before getting on to the user's device. They would have to jailbreak their device to get access to your database.
What sort of data are you storing such that it needs encryption? If it contains passwords that the user entered, then you don't really need to encrypt them; the user will not need to find out their own password. If it's generic BLOB data that you only want the user to access through the application, it could be as simple as storing an encrypted blob using the security API.
If it's the whole database you want secured, then you'd still want to use the security api, but on the whole file instead, and decrypt the file as necessary before opening it. The issue here is that if the application closes without cleanup, you're left with a decrypted file.
You may want to take a look at memory-resident databases, or temporary databases which you can create either using a template db or a hard-coded schema in the program (take a look at the documentation for sqlite3_open). The data could be decrypted, inserted into the temporary database, then delete the decrypted database. Do it in the opposite direction when closing the connection.
Edit:
You can cook up your own encryption scheme I'm sure with just a very simple security system by XOR-ing the data with a value stored in the app, and store a hash somewhere else to make sure it doesn't change, or something.
SQLCipher:
Based on my experience SQLCipher is the best option to encrypt the data base.
Once the key("PRAGMA key") is set SQLCipher will automatically encrypt all data in the database! Note that if you don't set a key then SQLCipher will operate identically to a standard SQLite database.
The call to sqlite3_key or "PRAGMA key" should occur as the first operation after opening the database. In most cases SQLCipher uses PBKDF2, a salted and iterated key derivation function, to obtain the encryption key. Alternately, an application can tell SQLCipher to use a specific binary key in blob notation (note that SQLCipher requires exactly 256 bits of key material), i.e.
Reference:
http://sqlcipher.net/ios-tutorial
I hope someone would save time on exploring about this
Ignoring the philosophical and export issues, I'd suggest that you'd be better off encrypting the data in the table directly.
You need to obfuscate the decryption key(s) in your code. Typically, this means breaking them into pieces and encoding the strings in hex and using functions to assemble the pieces of the key together.
For the algorithm, I'd use a trusted implementation of AES for whatever language you're using.
Maybe this one for C#:
http://msdn.microsoft.com/en-us/magazine/cc164055.aspx
Finally, you need to be aware of the limitations of the approach. Namely, the decryption key is a weak link, it will be available in memory at run-time in clear text. (At a minimum) It has to be so that you can use it. The implementation of your encryption scheme is another weakness--any flaws there are flaws in your code too. As several other people have pointed out your client-server communications are suspect too.
You should remember that your executable can be examined in a hex editor where cleartext strings will leap out of the random junk that is your compiled code. And that many languages (like C# for example) can be reverse-compiled and all that will be missing are the comments.
All that said, encrypting your data will raise the bar for cheating a bit. How much depends on how careful you are; but even so a determined adversary will still break your encryption and cheat. Furthermore, they will probably write a tool to make it easy if your game is popular; leaving you with an arms-race scenario at that point.
Regarding a checksum value, you can compute a checksum based on the sum of the values in a row assuming that you have enough numeric values in your database to do so. Or, for an bunch of boolean values you can store them in a varbinary field and use the bitwise exclusive operator ^ to compare them--you should end up with 0s.
For example,
for numeric columns,
2|3|5|7| with a checksum column | 17 |
for booleans,
0|1|0|1| with a checksum column | 0101 |
If you do this, you can even add a summary row at the end that sums your checksums. Although this can be problematic if you are constantly adding new records. You can also convert strings to their ANSI/UNICODE components and sum these too.
Then when you want to check the checksum simple do a select like so:
Select *
FROM OrigTable
right outer join
(select pk, (col1 + col2 + col3) as OnTheFlyChecksum, PreComputedChecksum from OrigTable) OT on OrigTable.pk = OT.pk
where OT.OnTheFlyChecksum = OT.PreComputedChecksum
It appears to be simplest to sync all tournament results to all iPhones in the tournament. You can do it during every game: before a game, if the databases of two phones contradict each other, the warning is shown.
If the User A falsifies the result if his game with User B, this result will propagate until B eventually sees it with the warning that A's data don't match with his phone. He then can go and beat up explain to A that his behavior isn't right, just the way it is in real life if somebody cheats.
When you compute the final tournament results, show the warning, name names, and throw out all games with contradictory results. This takes away the incentive to cheat.
As said before, encryption won't solve the problem since you can't trust the client. Even if your average person can't use disassembler, all it takes is one motivated person and whatever encryption you have will be broken.
Yet, if on windows platform, you also can select SQLiteEncrypt to satisfy your needs.SQLiteEncrypt extends sqlite encryption support, but you can treat it as original sqlite3 c library.