How to create a safe offline single sign on - c++

I am currently writing a firmware for an embedded device which acts as an human-machine-interface in an (aftermarket) automobile environment.
The device has got a service menu which shall only be accessible to specific personnel, which is secured by a device specific pin-code, which is generated randomly in production, burned on the device and stored in a database for the personnel to retrieve. Within the service menu, the user is e.g. able to manually change states and also overwrite limits for regulation functions etc.
However it might be necessary for any user to get to that menu in an error case, e.g. if they get stuck in a remote place and have a faulty sensor or whatever. Therefore I would like to create a kind of single-sign-in for the devices. My idea is, that the device creates a code and displays it to the user. The user then calls the service team which can create a pin valid for this device in this current state (the code displayed).
I don't want it to be too easy to figure out, so that anybody will be able to crack the algorithm of code generation. I cannot use any online functionality, as the users - as mentioned - may be in a remote place.
I was thinking about creating a table of random numbers and implementing it in the firmware (like 1-10k of pins and the device displays an index and the service teams just looks up the pin for that index) But I feel like there is a better solution to that problem.
My question:
What is a safe algorithm to compute a 4 digit (1000 - 9999) pin-code based on a random number (~6 digits hexadecimal) and (optionally) a 6 byte large serialnumber?

Related

How do I find the UUID of a virtual machine? [duplicate]

I need to write a function that generates an id that is unique for a given machine running a Windows OS.
Currently, I'm using WMI to query various hardware parameters and concatenate them together and hash them to derive the unique id. My question is, what are the suggested parameters I should use?
Currently, I'm using a combination of bios\cpu\disk data to generate the unique id. And am using the first result if multiple results are there for each metric.
However, I ran into an issue where a machine that dual boots into 2 different Windows OS generates different site codes on each OS, which should ideally not happen.
For reference, these are the metrics I'm currently using:
Win32_Processor:UniqueID,ProcessorID,Name,Manufacturer,MaxClockSpeed
Win32_BIOS:Manufacturer
Win32_BIOS:SMBIOSBIOSVersion,IdentificationCode,SerialNumber,ReleaseDate,Version
Win32_DiskDrive:Model, Manufacturer, Signature, TotalHeads
Win32_BaseBoard:Model, Manufacturer, Name, SerialNumber
Win32_VideoController:DriverVersion, Name
I had the same problem and after a little research I decided the best would be to read MachineGuid in registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography, as #Agnus suggested. It is generated during OS installation and won't change unless you make another fresh OS install. Depending on the OS version it may contain the network adapter MAC address embedded (plus some other numbers, including random), or a pseudorandom number, the later for newer OS versions (after XP SP2, I believe, but not sure). If it's a pseudorandom theoretically it can be forged - if two machines have the same initial state, including real time clock. In practice, this will be rare, but be aware if you expect it to be a base for security that can be attacked by hardcore hackers.
Of course a registry entry can also be easily changed by anyone to forge a machine GUID, but what I found is that this would disrupt normal operation of so many components of Windows that in most cases no regular user would do it (again, watch out for hardcore hackers).
With our licensing tool we consider the following components
MAC Address
CPU (Not the serial number, but the actual CPU profile like stepping and model)
System Drive Serial Number (Not Volume Label)
Memory
CD-ROM model & vendor
Video Card model & vendor
IDE Controller
SCSI Controller
However, rather than just hashing the components and creating a pass/fail system, we create a comparable fingerprint that can be used to determine how different two machine profiles are. If the difference rating is above a specified tolerance then ask the user to activate again.
We've found over the last 8 years in use with hundreds of thousands of end-user installs that this combination works well to provide a reliably unique machine id - even for virtual machines and cloned OS installs.
Parse the SMBIOS yourself and hash it to an arbitrary length. See the PDF specification for all SMBIOS structures available.
To query the SMBIOS info from Windows you could use EnumSystemFirmwareEntries, EnumSystemFirmwareTables and GetSystemFirmwareTable.
IIRC, the "unique id" from the CPUID instruction is deprecated from P3 and newer.
What about just using the UniqueID of the processor?
I hate to be the guy who says, "you're just doing it wrong" (I always hate that guy ;) but...
Does it have to be repeatably generated for the unique machine? Could you just assign the identifier or do a public/private key? Maybe if you could generate and store the value, you could access it from both OS installs on the same disk?
You've probably explored these options and they doesn't work for you, but if not, it's something to consider.
If it's not a matter of user trust, you could just use MAC addresses.
You should look into using the MAC address on the network card (if it exists). Those are usually unique but can be fabricated. I've used software that generates its license file based on your network adapter MAC address, so it's considered a fairly reliable way to distinguish between computers.
For one of my applications, I either use the computer name if it is non-domain computer, or the domain machine account SID for domain computers. Mark Russinovich talks about it in this blog post, Machine SID:
The final case where SID duplication would be an issue is if a distributed application used machine SIDs to uniquely identify computers. No Microsoft software does so and using the machine SID in that way doesn’t work just for the fact that all DC’s have the same machine SID. Software that relies on unique computer identities either uses computer names or computer Domain SIDs (the SID of the computer accounts in the Domain).
You can access the domain machine account SID via LDAP or System.DirectoryServices.
In my program I first check for Terminal Server and use the WTSClientHardwareId. Else the MAC address of the local PC should be adequate.
If you really want to use the list of properties you provided leave out things like Name and DriverVersion, Clockspeed, etc. since it's possibly OS dependent. Try outputting the same info on both operating systems and leave out that which differs between.
There is a library available for getting hardware specific informations: Hardware serial number extractor (CPU, RAM, HDD, BIOS)
Maybe cheating a little, but the MAC Address of a machines Ethernet adapter rarely changes without the motherboard changing these days.
Can you pull some kind of manufacturer serial number or service tag?
Our shop is a Dell shop, so we use the service tag which is unique to each machine to identify them. I know it can be queried from the BIOS, at least in Linux, but I don't know offhand how to do it in Windows.
I had an additional constraint, I was using .net express so I couldn't use the standard hardware query mechanism. So I decided to use power shell to do the query. The full code looks like this:
Private Function GetUUID() As String
Dim GetDiskUUID As String = "get-wmiobject Win32_ComputerSystemProduct | Select-Object -ExpandProperty UUID"
Dim X As String = ""
Dim oProcess As New Process()
Dim oStartInfo As New ProcessStartInfo("powershell.exe", GetDiskUUID)
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardInput = True
oStartInfo.RedirectStandardOutput = True
oStartInfo.CreateNoWindow = True
oProcess.StartInfo = oStartInfo
oProcess.Start()
oProcess.WaitForExit()
X = oProcess.StandardOutput.ReadToEnd
Return X.Trim()
End Function
Look up CPUID for one option. There might be some issues with multi-CPU systems.
Try this one, it gives a unique hard disk ID: Port of DiskId32 for Delphi 7-2010.

Disable application after expiry date for trial

I am writing a simple application for a semi-trusted client, and have no say on certain specifics. The client must be given a copy of a binary, myTestApp, which makes use of proprietary code in an external library, libsecrets. It is a Windows application that will run on a few separate Windows 7 laptops. I have been informed that after the application has served its purpose, it will be deleted. I know there is no perfect solution to this, but I would like to implement an expiry date in the program, and hinder efforts to potentially reverse engineer the code, or at least to prevent the contents of libsecrets from being exposed too easily.
So, my first step will be to statically link myTestApp against libsecrets so everything is contained in one binary, so only the needed pieces of libsecrets is included in the final binary, and its interfaces are no longer published.
Second, I want to implement some sort of getTime mechanism that is not naive. Is there anything in Windows that does a "secure" getTime call, so it can't be tricked by changing the time in the system tray or the BIOS?
Thirdly, if there is no "secure" getTime call, I could also modify myTestApp to use NTP to query a trusted time server, and fail if it can't get the time from it or the trial period has elapsed. But this could be fooled by messing with DNS on the gateway, unless there is some sort of certificates mechanism in place to verify the time server. I don't know much about this though, and would need some suggestions on how to implement it.
Next, is there some way to alter the binary so that it is impractical for individuals to attempt to reverse engineer it by viewing the assembly code? Maybe some sort of wrapper that encrypts the binary and requires a third-party authentication tool? Or maybe some sort of certificate I create that is required to run it and expires later?
Finally, is there any software out there (ie: packaging or publishing software) that can do this for me, either by repacking the final .exe or as some sort of plugin for Microsoft Visual Studio?
Thank you all in advance.
Edit: This is NOT meant to be a bullet proof system, and if it fails, that is acceptable. I just want to make it inconvenient for a non-technical person to attempt to crack. The people using it are technical Luddites, and the only way the software would be cracked is if they hired someone to do it. Since the names and company name are watermarked into the application, and only one person could benefit from its use, it's unlikely they would redistribute it.
You can't make things complete secure, but you can make it hard(er).
Packing with UPX adds some level of complexity to the hacker.
You can check at runtime if you're running under a debugger in several places or if you're running under a virtual machine.
You can encrypt a DLL you're using and load it manually (complicated).
You can write a loader that checks a hash of your application and your application can check the hash of the loader.
You can get the system time and compare it to a system time you already wrote to disk and see that it's monotonic.
All depends on the level of protection you want.
If you go to PirateBay or any other torrent site, you'll see that everything get's hacked if hackers are interested.
There is one way to make it really difficult for them to use it after expiry. The main theme of this trick is to make your expiration date independent of system time and make it depend on hours passed, irrespective of whatever the system time may be.
you will have to create a separate thread to perform this task.
Suppose you want the application to expire after they use it 70 hours.
Create a binary file called "record", and store any number in it, which should be hard to guess (I will tell you latter why you have to put this number in binary file).
When your application starts, it checks if that number is present there if yes, your application should get the current time, and store it in that file along with hour=1 (replacing the already present number), and the thread you created should keep on checking if hour in system time has changed or not, when it changes store current time in that file along with hour=2. A time will come when hour=70.
Add this code at two places inside that thread and on the start of your applicaiton
/*the purpose of storing current time is to find out later if hour has changed or not*/
/*read hour from file.*/
if(hour==70)
{
cout<<"Your trial period has expired"<<endl;
return EXIT_SUCESS;
}
now when ever hour=70 application will not work.
Earlier I told you to keep any number in your binary file, when ever they will run your application, binary file will be read and if that number is found there your application will replace it with current time and hour=1, now suppose they use your application for 5 hours and close it and run it after some time, now when your application will be run it will check that binary file if that number has been replaced with time stored previously and hour=5 it means now you will have to store current time along with hour=stored hour in file +1; . In this even if they change time or do anything else it will not effect your expiration period. Because now your expiration checking is not based on system time any more, it is now based on hours passed, irrespective whatever the time may be.
The absence of that number indicates file is not being accessed for first time and currently present hour in file should be incremented, and use binary file so that client can't see that number.
One last thing
Your binary file's format should be like this
current time, hour="any number", another_secret_number
another_secret_number will be placed so that even if they any how change your binary they will not be able to put that another_secret_number there because they don't know it. It means while reading your binary file you will have to make sure that, the end of any entry in your binary file contains "another_secret_number" at end.
For checking purposes both hidden numbers will also be hard coded in your code, which surely they can't see, and they can't read the binary also, so there is no way they can know them.
I hope it will help you.
Nothing stop the hackers!!!
Your question is like a a searching needle at the hay.
Assembly is large room for the responses.
You may thing only hrder, nothing, never stop 'bad' persons.
For UPX: Is well known, dont use it!!!

Mifare SMART Card Proper Identification Technique

Ok so i have developed an application which communicates with Mifare Classic smart cards (contactless).
The application is going to be used for member identification.
The current way is was just writing a 16 byte value to block 4 of the card. I left all the keys as the default (FF FF FF FF FF).
But what is the proper way to develope this kind of system so that it is more secure? Should we use the UID of the card instead of writing our own user id to data blocks?
Also can someone explain how the keys are used etc.
Thanks
If you want to identify someone you may want to keep record of an ID but also of personal data, such as the name of the person. Other data also may be interesting depending on the purpose of you application.
The bad thing about recording personal data is that this card may be lost exposing that information to person that are able to read the card data. That's why you should change the keys of the card to improve security. This way, a third subject who wants to check the content of your card would have to find out the key value first and this, besides possible, is not so trivial.
To protect the key value instead of having it hardcoded you could work with tables loaded in the reader device. Some readers have a memory region (a EEPROM, for instance) dedicated to store key values and all you will have to do is to pass the index of the desired key.
I don't think that using the UID of the card is a good option, thinking in the maintenance of your system. If someone has to change the card you would have to update you database. The advantage of your solution is that you don't need to do absolutely no set up to the card...
So, if you don't want to record any data on the card and wish to use its UID for identification, don't even bother to change the key.
Hope that helps!

Automatically selecting incomming telephone call with Java

I want to select incoming calls based on user input. E.g. by matching the telephone number to the user input number. To get user input number I used Java.
What are the best hardwares supporting to this requirement. I guess this hardware should allow us to call API and get current caller number. Then we can do the selection part using Java. After that we can another API method ans allow that call to proceed.
Let me know about the suitable hardware for this.
You have a number of options depending on how your incoming calls are presented - if you are lucky enough that they are coming in to a PABX which has some form of computer telephony interface (CTI) then you just need to interface your Java app to the PABX (many Cisco, Avaya etc pABX's will support some form of CTI).
If your calls come in on a standard line to a standard phone today, then you can either replace the phone with a simple commercial PABX (if you have the budget) or you can create your own PABX using one of the open source options and some line cards - see the answer to this question for a link to an example line card for the open source Asterix PABX:
https://stackoverflow.com/a/18220055/334402
If you have the option of a hosted VoIP 'telephone line' then it would be worth contacting your provider as they may provide hosted CTI options, saving you the need to get dedicated hardware.

Protect an executable / application for licensing

I was considering the various options that i have when i want to protect a generic chunk of data to apply this principles to the distribution of a generic application.
Encryption doesn't make sense, it's like giving something unusable for the user or i have to give both the encrypted file and the key do decrypt it which make even less sense.
Generating entropy does not make sense because this process will only re-arrange the data in other way without breaking the business logic of the application.
Wrapping my application in an executable that requires a password to the user, my real application and my wrapper are double-linked and if my wrapper does not gives a green light my application will not run.
Web based distribution like the popular "Steam" service with a customized compilation for every user based on some login/ID verification.
What are the other options? I know that this will not end up with a definitive solution but at least i want to avoid the user to just redistribute my application with a simple copy and paste and i want to have at least a small edge over the software distribution system.
The usual way of doing this is to encrypt the data using some piece of information that is already on the user's system as the key; the data is then keyed to that system. For instance, on Mac OS X you can get the system serial serial number with a library call. Sun systems have a gethostid() library call that makes this trivial. An alternative that works on dumb systems cough Winders cough is to use the MAC address of an ethernet interface, or something like that.
It can be tricky, you typically have to write a little program that will grovel around in the system and generate a key, and then have the customer email this key to you, or at least OK the program to email the key to you. You can then encrypt the protected data using the key information you got back, and have the customer download it. It is possible to add this entire transaction to your application installer, if the size of the data blob is reasonable.