Bluetooth GATT service uuid overview - bluetooth

I'm thinking about to implement a couple of GATT services for a custom app, but I'm stuck right now in the research. I know that the service uuids are not random, some parts are well defined, others are still confusing me.
E.g. The Device Information Service seems to be advertised as 0000180a-xxx the "180a" I can find in https://www.bluetooth.com/specifications/gatt/services/, but e.g. the subfield "Model Number String" has the id 00002a24-xxx, a total different prefix which is also not defined in the same list, but instead here: https://www.bluetooth.com/specifications/gatt/characteristics/. How can I get a list of all those prefixes?
Is that part I marked with xxx seems to be equal for a random device my mobile found. Is there somewhere a overview how the uuid should be build and which "safe" prefixes I can use for my own GATT services?

In Bluetooth, attributes types, GATT service types, characteristic types and descriptor types, and other constants are identified through UUIDs.
UUIDs are no more than identifiers, 128-bit identifiers. One given 128-bit value designates one given thing. Using 128-bit random values gives minimal chances of collisions for two parties generating identifiers on their own, without the need for a central registry.
UUIDs in Bluetooth
Bluetooth standard-defined UUIDs receive special treatment as they are commonly used throughout the various protocols of the Specification. They are grouped around the Bluetooth Base UUID (xxxxxxxx-0000-1000-8000-00805F9B34FB) and share 96 common bits. (See core specification, 3.B.2.5.1)
In various protocol parts, standard UUIDs can be transmitted in a short form, skipping the common bits, thus only using 16 or 32 bits on the air. This is an implementation detail, specific to some protocols in the whole stack. Because of this, standard-defined UUIDs are often referred as Short UUIDs.
Apart from standard UUIDs, any implementor is free to generate its own UUIDs from 128 bits of random and use them anywhere needed. Custom UUIDs must not use the Bluetooth Base UUID (and cannot be encoded in a short form, but you should not care about this).
Implications for custom services
Use Standard UUID when implementing standard services and characteristics.
Never use Bluetooth Base-UUID based UUIDs for custom purposes.
When developing your custom service and attributes, reusing existing UUIDs (or part of UUIDs) from code you may find in example code, vendor SDKs, or anywhere else is not a good idea. You should really regenerate yours.
Side notes
Specification does not define any grouping scheme (what you call prefixes) for custom UUIDs, but some vendors do incitate to group custom UUIDs, in a way they generate one 96-bit custom base UUID, and issue incrementing values from this, as Bluetooth did. This is not standard and brings no protocol optimization.

Related

DDD correct the identity of an Entity

In DDD, Entities have a value that uniquely identify them i.e. the identity. Sometimes this identity is generated by the server, sometimes is obtained from another BC, sometimes is provided by the user, and so on. Let's assume we are working in the scenario where the user provides the identity.
Let's pretend that there is a business process exclusively done on paper and not-to-be-migrated-to-computer-soon where the Process Owner decides the new name for a thing called a Resource. The name is always following a fixed schema like PROD-<today's date>-<short random string> and is always validated between Very Important Team Members. The chosen and validated name is PROD-2021-01-04-KAH14564YUDO, the last character being an " O " (the letter) and not a " 0 " (the number).
Let's say that an operator registers this new Resource in the system, providing the given identity but mistakingly spelling the last character as a zero, perhaps because of bad handwriting. The Entity is inserted, some other Entities are linked to it via its identity, and then someone detects the error in the identity. What should happen now?
We know that the identity of an Entity should be unique and immutable, but here it seems we need to correct (and so change) it. Introducing a surrogate identity to avoid this bad insert problem is not correct since the identity provided by the PO and validated by the Very Important Team Members is actually unique and is not to be changed, it was only inserted with an error in the management system; moreover there is no concept in the business of this surrogate identity related to the Resource.
Where is the error in this scenario?
Interesting situation. I'm assuming that you cannot add validation to the Identity as it's just a random string entered by the user.
Let's start with the question Where is the error in this scenario?. It's an error prone mechanism or workflow in the Domain that you are in. When you build a system for a specific domain you will have to deal with nasty stuff from that domain. You just have to catch these nasty rules or mechanisms as early as possible and design the system in a way to handle them.
Let's see how you can handle this scenario.
One thing you can do is to use another ID (an auto-generated GUID for example) used by the system and hidden from the users. You can use it to link other entities to this one. This way if an error is detected to the Identity entered by the user you won't have to update the whole system as the Identity will not be used anywhere else. If you need it from another part of the system you should just make a query contains the GUID to get the Identity back. This will unsure that the ID is indeed immutable. Depending on the system it may be a good solution or it may complicate some parts of it and it's not always a viable solution.
If using another ID only for system use is not an option, then you just have to design it in a way to handle these situations. You will have to include updating the Identity from the user as a use-case. Add handling of Identity updates from every part of the system that uses this Identity. In some cases these errors will have nasty consequences. One example is if this Identity is send to another system or a person by e-mail and is already used somewhere else that your system doesn't have control of. In this case it's not the systems fault, it's in the Domain and the people who use it. The only way to fix this is to change the rules and mechanisms in the Domain. This isn't possible most of the time, but sometimes you can raise this issue and a more robust mechanism can be implemented. It's a nasty situation to be in but that's life.
Example for using natural keys / identity instead of GUID.
If you have a network of systems that operate with natural keys and their generation is robust you can use them. For example, banking systems use the International Bank Account Number (IBAN). These numbers are generated by a special schema that is robust. They are not just some random string entered by a user. In this case, the Domain has a robust mechanism that ensures that these natural keys are valid. In this case, it's almost impossible to send a GUID to another banking system to exchange for an IBAN.
When sending money to a bank account, this IBAN is validated, so errors are easily detected. This way a person cannot send money to a non-existing bank account thus losing them just for making a typo.
If you cannot fix the database, then fix the paper and make sure it never happens again e.g. use hex characters only.

Looking for a network-accessible hash table

I have a data acquisition application broken into a client and a server.
The server is reponsible for grabbing data from the hardware, running some realtime analysis, and recording the data to disk when it's asked.
The client is a GUI that the operator can use to look at some pretty graphs (generated by the server), set some parameters, and turn recording on and off. It's usually run on the same machine as the server, but can be run from any other machine on the network.
Both are written in Qt (C++). Both are used on Linux.
The communication between the two is currently done with a homegrown library (in C++, but not Qt) that is essentially a hash table. The server has a list of parameters, like analysis.graph.width, and those parameters can be set and get by both the server and client(s).
The system is being redesigned to support new hardware, and now is a good time to replace this library if something better exists. Here are some requirements:
Ideally would play well with Qt (using QVariant to store values, using signals/slots)
Must allow values to be many different types (integers, strings, doubles, bools, lists of those)
Keys will be strings
Must be fast, allowing set/get operations up to 30 times per second
Must allow multiple clients to set/get parameters simultaneously
I found this list: http://en.wikipedia.org/wiki/Structured_storage, but the libraries listed there seem too complex (distributed, mirrored) or not cabable enough (values can only be strings).
Is anyone aware of libraries that would fit some or all of the requirements?
Well Dave I have had used redis for the same problem. It doesn't meet all your requirements but meets
Must allow values to be many
different types (integers, strings,
doubles, bools, lists of those)
Keys will be strings
Must be fast, allowing set/get
operations up to 30 times per second
Must allow multiple clients to
set/get parameters simultaneously
You can use the c/c++ api to communicate with redis. How to use Redis within a C++ program? ... yes you will have to convert datatypes from one to another say char* to QString etc.

How are software license keys generated?

License keys are the defacto-standard as an anti-piracy measure. To be honest, this strikes me as (in)Security Through Obscurity, although I really have no idea how license keys are generated. What is a good (secure) example of license key generation? What cryptographic primitive (if any) are they using? Is it a message digest? If so, what data would they be hashing? What methods do developers employ to make it difficult for crackers to build their own key generators? How are key generators made?
For old-school CD keys, it was just a matter of making up an algorithm for which CD keys (which could be any string) are easy to generate and easy to verify, but the ratio of valid-CD-keys to invalid-CD-keys is so small that randomly guessing CD keys is unlikely to get you a valid one.
INCORRECT WAY TO DO IT:
Starcraft and Half-life both used the same checksum, where the 13th digit verified the first 12. Thus, you could enter anything for the first 12 digits, and guess the 13th (there's only 10 possibilities), leading to the infamous 1234-56789-1234
The algorithm for verifying is public, and looks something like this:
x = 3;
for(int i = 0; i < 12; i++)
{
x += (2 * x) ^ digit[i];
}
lastDigit = x % 10;
CORRECT WAY TO DO IT
Windows XP takes quite a bit of information, encrypts it, and puts the letter/number encoding on a sticker. This allowed MS to both verify your key and obtain the product-type (Home, Professional, etc.) at the same time. Additionally, it requires online activation.
The full algorithm is rather complex, but outlined nicely in this (completely legal!) paper, published in Germany.
Of course, no matter what you do, unless you are offering an online service (like World of Warcraft), any type of copy protection is just a stall: unfortunately, if it's any game worth value, someone will break (or at least circumvent) the CD-key algorithm, and all other copyright protections.
REAL CORRECT WAY TO DO IT:
For online-services, life is a bit simpler, since even with the binary file you need to authenticate with their servers to make any use of it (eg. have a WoW account). The CD-key algorithm for World of Warcraft - used, for instance, when buying playtime cards - probably looks something like this:
Generate a very large cryptographically-secure random number.
Store it in our database and print it on the card.
Then, when someone enters a playtime-card number, check if it's in the database, and if it is, associate that number with the current user so it can never be used again.
For online services, there is no reason not to use the above scheme; using anything else can lead to problems.
When I originally wrote this answer it was under an assumption that the question was regarding 'offline' validation of licence keys. Most of the other answers address online verification, which is significantly easier to handle (most of the logic can be done server side).
With offline verification the most difficult thing is ensuring that you can generate a huge number of unique licence keys, and still maintain a strong algorithm that isnt easily compromised (such as a simple check digit)
I'm not very well versed in mathematics, but it struck me that one way to do this is to use a mathematical function that plots a graph
The plotted line can have (if you use a fine enough frequency) thousands of unique points, so you can generate keys by picking random points on that graph and encoding the values in some way
As an example, we'll plot this graph, pick four points and encode into a string as "0,-500;100,-300;200,-100;100,600"
We'll encrypt the string with a known and fixed key (horribly weak, but it serves a purpose), then convert the resulting bytes through Base32 to generate the final key
The application can then reverse this process (base32 to real number, decrypt, decode the points) and then check each of those points is on our secret graph.
Its a fairly small amount of code which would allow for a huge number of unique and valid keys to be generated
It is however very much security by obscurity. Anyone taking the time to disassemble the code would be able to find the graphing function and encryption keys, then mock up a key generator, but its probably quite useful for slowing down casual piracy.
Check tis article on Partial Key Verification which covers the following requirements:
License keys must be easy enough to type in.
We must be able to blacklist (revoke) a license key in the case of chargebacks or purchases with stolen credit cards.
No “phoning home” to test keys. Although this practice is becoming more and more prevalent, I still do not appreciate it as a user, so will not ask my users to put up with it.
It should not be possible for a cracker to disassemble our released application and produce a working “keygen” from it. This means that our application will not fully test a key for verification. Only some of the key is to be tested. Further, each release of the application should test a different portion of the key, so that a phony key based on an earlier release will not work on a later release of our software.
Important: it should not be possible for a legitimate user to accidentally type in an invalid key that will appear to work but fail on a future version due to a typographical error.
I've not got any experience with what people actually do to generate CD keys, but (assuming you're not wanting to go down the road of online activation) here are a few ways one could make a key:
Require that the number be divisible by (say) 17. Trivial to guess, if you have access to many keys, but the majority of potential strings will be invalid. Similar would be requiring that the checksum of the key match a known value.
Require that the first half of the key, when concatenated with a known value, hashes down to the second half of the key. Better, but the program still contains all the information needed to generate keys as well as to validate them.
Generate keys by encrypting (with a private key) a known value + nonce. This can be verified by decrypting using the corresponding public key and verifying the known value. The program now has enough information to verify the key without being able to generate keys.
These are still all open to attack: the program is still there and can be patched to bypass the check. Cleverer might be to encrypt part of the program using the known value from my third method, rather than storing the value in the program. That way you'd have to find a copy of the key before you could decrypt the program, but it's still vulnerable to being copied once decrypted and to having one person take their legit copy and use it to enable everyone else to access the software.
CD-Keys aren't much of a security for any non-networked stuff, so technically they don't need to be securely generated. If you're on .net, you can almost go with Guid.NewGuid().
Their main use nowadays is for the Multiplayer component, where a server can verify the CD Key. For that, it's unimportant how securely it was generated as it boils down to "Lookup whatever is passed in and check if someone else is already using it".
That being said, you may want to use an algorhithm to achieve two goals:
Have a checksum of some sort. That allows your Installer to display "Key doesn't seem valid" message, solely to detect typos (Adding such a check in the installer actually means that writing a Key Generator is trivial as the hacker has all the code he needs. Not having the check and solely relying on server-side validation disables that check, at the risk of annoying your legal customers who don't understand why the server doesn't accept their CD Key as they aren't aware of the typo)
Work with a limited subset of characters. Trying to type in a CD Key and guessing "Is this an 8 or a B? a 1 or an I? a Q or an O or a 0?" - by using a subset of non-ambigous chars/digits you eliminate that confusion.
That being said, you still want a large distribution and some randomness to avoid a pirate simply guessing a valid key (that's valid in your database but still in a box on a store shelf) and screwing over a legitimate customer who happens to buy that box.
The key system must have several properties:
very few keys must be valid
valid keys must not be derivable even given everything the user has.
a valid key on one system is not a valid key on another.
others
One solution that should give you these would be to use a public key signing scheme. Start with a "system hash" (say grab the macs on any NICs, sorted, and the CPU-ID info, plus some other stuff, concatenate it all together and take an MD5 of the result (you really don't want to be handling personally identifiable information if you don't have to)) append the CD's serial number and refuse to boot unless some registry key (or some datafile) has a valid signature for the blob. The user activates the program by shipping the blob to you and you ship back the signature.
Potential issues include that you are offering to sign practically anything so you need to assume someone will run a chosen plain text and/or chosen ciphertext attacks. That can be mitigated by checking the serial number provided and refusing to handle request from invalid ones as well as refusing to handle more than a given number of queries from a given s/n in an interval (say 2 per year)
I should point out a few things: First, a skilled and determined attacker will be able to bypass any and all security in the parts that they have unrestricted access to (i.e. everything on the CD), the best you can do on that account is make it harder to get illegitimate access than it is to get legitimate access. Second, I'm no expert so there could be serious flaws in this proposed scheme.
If you aren't particularly concerned with the length of the key, a pretty tried and true method is the use of public and private key encryption.
Essentially have some kind of nonce and a fixed signature.
For example:
0001-123456789
Where 0001 is your nonce and 123456789 is your fixed signature.
Then encrypt this using your private key to get your CD key which is something like:
ABCDEF9876543210
Then distribute the public key with your application. The public key can be used to decrypt the CD key "ABCDEF9876543210", which you then verify the fixed signature portion of.
This then prevents someone from guessing what the CD key is for the nonce 0002 because they don't have the private key.
The only major down side is that your CD keys will be quite long when using private / public keys 1024-bit in size. You also need to choose a nonce long enough so you aren't encrypting a trivial amount of information.
The up side is that this method will work without "activation" and you can use things like an email address or licensee name as the nonce.
I realize that this answer is about 10 years late to the party.
A good software license key/serial number generator consists of more than just a string of random characters or a value from some curve generator. Using a limited alphanumeric alphabet, data can be embedded into a short string (e.g. XXXX-XXXX-XXXX-XXXX) that includes all kinds of useful information such as:
Date created or the date the license expires
Product ID, product classification, major and minor version numbers
Custom bits like a hardware hash
Per-user hash checksum bits (e.g. the user enters their email address along with the license key and both pieces of information are used to calculate/verify the hash).
The license key data is then encrypted and then encoded using the limited alphanumeric alphabet. For online validation, the license server holds the secrets for decrypting the information. For offline validation, the decryption secret(s) are included with the software itself along with the decryption/validation code. Obviously, offline validation means the software isn't secure against someone making a keygen.
Probably the hardest part about creating a license key is figuring out how to cram as much data as possible into as few bytes as possible. Remember that users will be entering in their license keys by hand, so every bit counts and users don't want to type extremely long, complex strings in. 16 to 25 character license keys are the most common and balance how much data can be placed into a key vs. user tolerance for entering the key to unlock the software. Slicing up bytes into chunks of bits allows for more information to be included but does increase code complexity of both the generator and validator.
Encryption is a complex topic. In general, standard encryption algorithms like AES have block sizes that don't align with the goal of keeping license key lengths short. Therefore, most developers making their own license keys end up writing their own encryption algorithms (an activity which is frequently discouraged) or don't encrypt keys at all, which guarantees that someone will write a keygen. Suffice it to say that good encryption is hard to do right and a decent understanding of how Feistel networks and existing ciphers work are prerequisites.
Verifying a key is a matter of decoding and decrypting the string, verifying the hash/checksum, checking the product ID and major and minor version numbers in the data, verifying that the license hasn't expired, and doing whatever other checks need to be performed.
Writing a keygen is a matter of knowing what a license key consists of and then producing the same output that the original key generator produces. If the algorithm for license key verification is included in and used by the software, then it is just a matter of creating software that does the reverse of the verification process.
To see what the entire process looks like, here is a blog post I recently wrote that goes over choosing the license key length, the data layout, the encryption algorithm, and the final encoding scheme:
https://cubicspot.blogspot.com/2020/03/adventuring-deeply-into-software-serial.html
A practical, real-world implementation of the key generator and key verifier from the blog post can be seen here:
https://github.com/cubiclesoft/php-misc/blob/master/support/serial_number.php
Documentation for the above class:
https://github.com/cubiclesoft/php-misc/blob/master/docs/serial_number.md
A production-ready open source license server that generates and manages license keys using the above serial number code can be found here:
https://github.com/cubiclesoft/php-license-server
The above license server supports both online and offline validation modes. A software product might start its existence with online only validation. When the software product is ready to retire and no longer supported, it can easily move to offline validation where all existing keys continue to work once the user upgrades to the very last version of the software that switches over to offline validation.
A live demo of how the above license server can be integrated into a website to sell software licenses plus an installable demo application can be found here (both the website and demo app are open source too):
https://license-server-demo.cubiclesoft.com/
Full disclosure: I'm the author of both the license server and the demo site software.
There are also DRM behaviors that incorporate multiple steps to the process. One of the most well known examples is one of Adobe's methods for verifying an installation of their Creative Suite. The traditional CD Key method discussed here is used, then Adobe's support line is called. The CD key is given to the Adobe representative and they give back an activation number to be used by the user.
However, despite being broken up into steps, this falls prey to the same methods of cracking used for the normal process. The process used to create an activation key that is checked against the original CD key was quickly discovered, and generators that incorporate both of the keys were made.
However, this method still exists as a way for users with no internet connection to verify the product. Going forward, it's easy to see how these methods would be eliminated as internet access becomes ubiquitous.
All of the CD only copy protection algorithms inconvience honest users while providing no protection against piracy whatsoever.
The "pirate" only need to have access to one legitimate cd and its access code, he can then make n copies and distribute them.
It does not matter how cryptographically secure you make the code, you need to supply this with the CD in plain text or an legitimate user cannot activite the software.
Most secure schemes involve either the user providing the software supplier with some details of the machine which will run the software (cpu serial numbers, mac addresses, Ip address etc.), or, require online access to register the software on the suppliers website and in return receive an activitation token. The first option requires a lot of manual administration and is only worth it for very high value software, the, second option can be spoofed and is absolutly infuriating if you have limited network access or you are stuck behind a firewall.
On the whole its much easier to establish a trust relationship with your customers!
You can use and implement Secure Licensing API from very easily in your Software Projects using it,(you need to download the desktop application for creating secure license from https://www.systemsoulsoftwares.com/)
Creates unique UID for client software based on System Hardware(CPU,Motherboard,Hard-drive)
(UID acts as Private Key for that unique system)
Allows to send Encrypted license string very easily to client system, It verifies license string and works on only that particular system
This method allows software developers or company to store more information about software/developer/distributor services/features/client
It gives control for locking and unlocked the client software features, saving time of developers for making more version for same software with changing features
It take cares about trial version too for any number of days
It secures the License timeline by Checking DateTime online during registration
It unlocks all hardware information to developers
It has all pre-build and custom function that developer can access at every process of licensing for making more complex secure code

UUIDs in CouchDB

I am wondering about the format UUIDs are by default represented in CouchDB. While the RFC 4122 describes UUIDs like 550e8400-e29b-11d4-a716-446655440000, CouchDB uses continuously chars like 3069197232055d39bc5bc39348a36417. I've searched some time in both their wiki and their documentation what this actually is, however without any result.
Do you know whether this is either a non RFC-conform format omitting all - or is this a completely different representation of the 128 bits.
The background is that I'm using Java UUIDs which are formatted as noted in the RFC. I see the advantage that the CouchDB-style is probably more handy for building internal trees, but I want to be sure to use a consistent implementation.
Technically we don't use the rfc standard for uuids as you've noticed. Version four uuids reserve something like four bits to specify the version of uuid. We also don't format them with the hyphens that are generally seen in other implementations.
CouchDB uuids are 16 random bytes formatted as hex. Roughly speaking that's a v4 uuid but not rfc compliant.
Regardless of the specifics, there's really not much of an issue in practice. You generally shouldn't try to interpret a uuid unless you're trying to do some sort out-of-band analysis. CouchDB will never interpret uuids, we only rely on the properties of randomness involved therein.
Bottom line would be to not worry about it and just treat them as strings after generation.
K I can provide some 2019 reference from the doc site: "it's in any case preferable to provide one's own uuids" -- https://docs.couchdb.org/en/latest/best-practices/documents.html?highlight=uuid
I ran slap bang into this because the (hobby) db I'm attempting as a first programming anything, deals with an application that does generate and use 4122 -compliant uuids and I was chewing my nails worrying about stripping the "-" bits out and putting them back on retrieval.
Before it hit me that the uuid that couchdb uses as the doc _id is a string not a number... doh. So I use the app's uuid generated when it creates an object to _id the document. No random duplicated uuids.

How to implement/use a secure 'read-once' local file access system?

does anybody know of a secure 'read-once' local file access system? Or how one might create one? I realise that if data is to be used on a system, then it must be capable of being read, but I think it may be possible to severely limit how data is made available and reduce the possibility of it being copied and used elsewhere.
These are my requirements:
I want to store a 'secure/encrypted' data-file on a USB stick (could be read-only CD/DVD, but better if read/write USB or even a floppy) and have this file capable of being read once (and mainly only once), on a decoded block-by-block basis, once a password has been entered. The file content is probably basic text/xml (or text-encoded data) and is to be read mainly as a sequential stream. The data (ideally) can be read by normal windows file-access methods, ie: a std file, FSO objects (stream and text file), all BASIC PC (VB6/VB.NET) file handling methods, even Excel text (import). yes, I know this probably defeats the object (as such a file can then be opened/saved), but I would still want this possibility. Finally, once the 'access' criteria had been met, the device would prevent further access.
Access to the data would be on a local PC system only. No LAN, no device sharing supported. Data on the device should not be copyable by normal means. Data would be written to the device using normal methods if possible or a special application if necessary.
To keep things simple, just one password, one file, one use, and one user would be great, but other possible enhancements include: (as icing on the cake)...
allowing 'n' opens
having multiple passwords 2 or more users, acting individually
silo-passwords, having 2 more users sign together to get access (or even
having at least n from m more users sign together to get access)
Password prompt should be given on first block-access, independent of
application calling the first block
Password could be embedded/automatic
tie the access to a nominated machine/mac/ip/disk serial number (or
other machine-code)
tie the access to a nominated program /application
if possible, delete and securely overwrite the data file
My first guess at doing this suggests that it would need a 'psuedo-device' driver that would appear as an extention to (or replacement of) the std removable-device driver. The driver would handle each file block, sector by sector, and refuse to server further decoded blocks if not authorised. The device should not give normal directory listings, but some some form of content summary may be given to a user (optional).
Unlike a DRM system, I don't want any form of on-line acces/authentication (but would consider it), I would prefer a self-contained system.
I have looked long and hard for a such a device/system, and haven't found one yet. Most devices and system tools (eg: Iomega/ironkey) appear to unlock access to files, but without limit, ie: read-many, once unlocked.
Performance is not an issue. Slow floppy read-rate would be okay. Encyption method is agnostic, anything reasonably strong 40bit+ (128bit) would be fine. I can't tell you what the data is or whats its for, I just need a way to give data to somebody and limit its use as far as possible and what they can do with it. Its a real requirement to protect confidential data and not meant for DRM or MP3s/Videos or similar.
I am an 'office' developer and not really familiar with device-drivers or DRM - Now where would I start with such a project? Is there anything out-there available to joe-public already?
Thanks - Tim.
PS: Update
I should point out that I just wish to pass data between ourselves and a single specific nominated service-provider. I don't want them to copy the data we provide. It will be used once to support a 'singular' one-off process and then be done-with. As the data is 'streamed/read' it should be 'consumed'. if the process fails, we will re-issue the data to the service-provider. the data remains our property, it is not being sold/licensed.
I do realise that no solution will be foolproof, but the risk/reward ratio should dissuade casual attempts to break the system. The data has no explicit commercial value.
PPS: Its a real requirement... What would you do?
Judging by the upvotes on #eriksons thoughtful answer, you guys are saying 'not possible / don't bother' - but apart from personally supervising that the data is used according to our wishes, what would you do?
Executive summary: this isn't a realistic solution. Re-think the process so that "read-once" isn't necessary.
A few companies (Disappearing Inc. comes to mind, and they had at least one competitor) tried to make "self-destructing" email on general-purpose hardware in the late 90s. They spent millions of dot.com dollars to develop systems that didn't really work.
The only potential solution I know of is the use of a Trusted Platform Module. These are fairly common, as they are required in all computers bought by the US government. However, their capabilities vary. You'd need one that supported something called remote attestation, which allows software to perform integrity checks on itself. With this capability, you could write software that would enforce your data destruction policy. However, I don't think this feature is widely used. My laptop has a TPM, but it doesn't support this.
You should also be aware that there is a lot of hostility against "trusted computing," because it can be used to limit the functionality of a machine. This violates the right to do as you please with your property. TPMs might make sense for corporate or government machines, but not for personal computers.
Other aspects of your problem, such as granting multiple users access to the data, requiring multiple users to gain access to the data are easier.
Encrypting data for multiple users is typically achieved by generating a key, encrypting the data with that "content encryption key", then encrypting the key (which is relatively small) with a "key encryption key" (which could be a password) belonging to each intended recipient.
Requiring some number of users to enter a password can be done securely with Shamir Secret Sharing, as I learned here on SO.
Based on the comments on the question, especially the "mailing label printing service" analogy, I'm afraid my initial answer isn't really relevant.
In a case like that, I can only see a legal solution. Disallow storage of your data in the contract. If it's worth suing them for violating the contract, do so.
Cryptographically speaking, the best thing I could think of would be to "watermark" such a "mailing list" with information that would help me prove that a copy of the list was disclosed by a particular vendor. Knowing that a watermark exists might deter any deliberate disclosures, and could help leverage a fast settlement in the case of accidental disclosure. This could use steganographic techniques within records as well as fake records in the collection.
Algorithms for doing this might already exist, but I'm not familiar with the field. Researching "digital watermarks" might be useful. Even if it only turns up algorithms for protected video and audio, perhaps these could be adapted to work with other media.
There are several problems with your approach.
If you can read the data from any application, you can safe the data anywhere. I would think this would defeat the purpose of any 'only-one-access' policy.
To get a device driver to handle your scenario, you would need deep knowledge of file-system-programming, which at least under windows is no easy undertaking. Even then, it would be hard to enforce the one time access prerequisite.
Programs have different file-access strategies, which might break your assumptions. E.g. an application may open a file once to get its size, then close and reopen it, to load its data. How should this be enforced? Do you want to limit 'OpenFile' calls? do you want to limit 'read byte' calls? Do you want to limit ... jumping around in the file?
When your medium gets copied, by whatever means, you have no way of knowing that. The games industry tries to bind the game to the original CD for years, but failed miserably for years.
I think, what would be feasible, would be a container format, with a encoder/decoder, or something like that. (See Bitlocker in Windows7) That would guarantee, that you can only decode the data once to a local disc and would then delete the container on your medium (beware, check first if the medium is writable, and bind the container to an serial-number or name of the medium so that the container cannot be copied).
Another possibility would be a separate USB device, which you can only use once to extract the data from it. Then you would only need to write a driver once in user mode with WinUSB. Encrypted USB-Sticks use this approach.
But I really think this is a bad idea, because you can very easily get around any counter measurement, when the receiving person can read all data from the medium and safe it anywhere else.

Resources