Questions about creating a key generator for a license system - c++

I am new at this domain and I have to built a fairly safe license mechanism, but I have some questions about how public key system works.
Imagine an implementation of a key generator that uses a private key to generate a string with the MAC and the expiration date. This string will be decrypted by the software and the MAC will be checked to see if it can execute. MY question is: if someone decrypt my message and saw the MAC then it would be fairly easy to create key, wouldn't it? I say that because I know that there is some mathematics behind the fact that you can encrypt with one private key and decrypt with a public one, therefore with the encrypted message, the real message and the public key I guess that someone can find the private key.
I am a bit lost in the discussion about if it is necessary to hash some message before the encryption or not. And also the usage of elliptic curves for compression. I would appreciate if someone can give me some info about the topic.
P.S. I am using C++, but any comment in any other language is welcome.

create an DSA or ECDSA or <insert favourite sigining algo here> keypair ... YOU keep the private key safe ... the public key is embedded into your binary
create a datastructure holding your relevant licensing information
compress it
sign it
upon license checking:
verify license signature
uncompress structure
make whatever checks are needed based on license data
common well known asymetric ciphers are not prone against known plaintext attacks
to my knowledge elliptic curves are not used in the context of compression
elliptic curves ARE used in the context of cryptography (read encryption and digital signatures)
train your google-fu with: RSA, DSA, ECC (elliptic curve cryptography), ECDSA

Related

nettle curve25519 key exchange

I'm trying to understand how to implement key exchange using nettle's curve25519 functions.
I'm writing an software that establishes encrypted TCP connection with public key based authentication. The client and server programs share the same code base.
This is an hobby project to learn network and crypto programming. :-)
I have working toy app using nettle's rsa_encrypt function, but there is no equivalent to curve25519 from what I see. How do I do key exchange using nettle's curve25519 functions?
And to be clear, I know I could and probably should simply use any production quality TLS library like openssl, but I want to learn how to do encrypted TCP connection from scratch. Using TLS library would defeat that purpose.
I compared many crypto libraries and found nettle as most easily approachable since it is low level.
Elliptic curves, generally, are used for key 'agreement' rather than key 'exchange'.
I don't know how much you know about this so I'll briefly explain:
RSA - we generate a random symmetric key, encrypt it with the public key of the recipient, who themselves later decrypts and uses it.
ECC (Elliptic curve crypto) - we use a process called Elliptic Curve Diffie-Hellman, due to the commutative nature of the multiplication of curve points, we can establish the same point on the curve by multiplying theirPublicKeyPoint * ourPrivateKeyPoint * G, where G is the curves base point.
So, in summary:
I greatly encourage you to use ECDH instead of RSA.
You need to find a function to perform ECDH over curve25519, also known as x25519, nettle's function is this.
After the process of ECDH, we end up with another point on the curve. :) - which we hash the x co-ordinate of to generate the symmetric key. Though this is usually done by the lib.

Asymmetric authenticated encryption

I want to protect my data from being changed or read by unauthorized people. Searching around I found that Authenticated Encryption(AE) is a solution.
I know I can do AE in Crypto++ using any of CCM, GCM, or EAX. But I noticed they're using the same key to encrypt and decrypt data. I don't want that, I'd rather use asymmetric keys to encrypt and decrypt my data.
If I sign data using an asymmetric algorithm and then encrypt it using a symmetric algorithm, I will achieve what I want (Which should be safe since it's AtE method, right?).
But before I do that, are there any crypto libraries that do what I want already?
I know I can do Authenticated Encryption ... using ... CCM, GCM, or EAX. But I noticed they're using the same key to encrypt and decrypt data. I don't want that, I'd rather use asymmetric keys to encrypt and decrypt my data.
All the schemes I am aware will use a symmetric cipher for the bulk data encryption. The symmetric cipher can be a block cipher or a stream cipher.
I've also seen a few incorrect applications of RSA, where RSA is operated in ECB mode. That is, the data is "chunked" or "blocked", and then RSA is applied to each block. The Handbook of Applied Cryptography specifically warns against this.
The best you are probably going to do is Elliptic Curve Integrated Encryption Scheme (ECIES) or Discrete Log Integrated Encryption System (DLIES). Both are available in Crypto++. Both use public key (asymmetric) cryptography.
ECIES and DLIES combine a Key Encapsulation Mechanism (KEM) with a Data Encapsulation Mechanism (DEM). The system independently derives a symmetric cipher key and a MAC key from a common secret. Data is first encrypted under a symmetric cipher, and then the cipher text is MAC'd under an authentication scheme. Finally, the common secret is encrypted under the public part of a public/private key pair. The output of the encryption function is the tuple {K,C,T}, where K is the encrypted common secret, C is the ciphertext, and T is the authentication tag.
There is some hand waiving around the "common secret" since its actually the result of applying a Key Agreement function and later digested with a KDF. It uses the static public key and an ephemeral key pair. The person performing the decrypt uses their public key to perform the other half of the key exchange to arrive at the "common secret".
The KEM and the DEM avoid padding, so padding oracles are not a concern. That's why a KDF is used to digest the large "common secret" under the KEM. Omitting padding vastly simplifies the security proofs of the system. Because of the security proofs, ECIES and DLIES are IND-CCA2, which is one of the strongest you can achieve.
If I sign data using an asymmetric algorithm and then encrypt it using a symmetric algorithm...
Here's some related reading... First is Hugo Krawczyk's The Order of Encryption and Authentication for Protecting Communications. Second is Don Davis' Defective Sign & Encrypt in S/MIME, PKCS#7, MOSS, PEM, PGP, and XML.
The relevance here is: Krawczyk's paper deals with symmetric key cryptography and the Encrypt-then-Authenticate style of authenticated encryption (and how to perform authenticated encryption). Davis' paper deals with asymmetric cryptography and the disconnect between signing and encryption (and how to repair it).
But before I do that, are there any crypto libraries that do what I want already?
Yes (but it depends on what you want to do). Crypto++ is the only one I am aware that provides ECIES, DLIES, and a collection of PSSRs.
Bouncy Castle is a close second because it provides ECIES, but not DLIES. I'm not sure how many PSSRs it provides.
Crypto++, Bouncy Castle, OpenSSL (and others) provide the PSSR. You should not have any trouble finding a lib with PSSR.
You could possibly consider an OpenPGP-based solution. This would provide you with the functionality you desire and would scale to support arbitrary data sizes, unlike a solution based purely on asymmetric encryption (with no transport key).
There are a few open source implementations out there. BouncyCastle offer one, but I'm not sure they have a C++ implementation.
GPGME (GnuPG Made Easy). It's a high level encryption library in C and is LGPL licensed.

What method/algorithm/library can securely encrypt then decrypt

The following project is done in C++ with WinAPI, for encryption/encoding I am using CryptoC++ but I am open to better libraries. I need to encrypt/encode email data, transmit it, then decrypt it at the other end so privileged users can read the email.
My original idea was just to encrypt the email text using SHA256 using my key(eg "MYKEY"). But I think I don't fully understand what hashing is. I understand that a string encrypted with SHA256 or MD5 or AES is impossible to decrypt, BUT I thought that if I encrypt the string with my special key("MYKEY") that I could then decrypt it aslong as I know the special key. Is that correct?
If not can you suggest a library, algorithm or method I can use to achieve my task of encrypting/encoding email text & ONLY being able to decrypt it if I have a key or some shared secret that will allow me to decrypt the data?
As said by Captain Giraffe, a hash algorithm is not an encryption algorithm (though they are both counted in the area of symmetric cryptography). A good hash function has no way to recover a message which fits to the produced hash (other than trying all possible messages to see if they give the same hash). (And also, a hash function has fixed size output, but has a variable size input, which means that there are many messages giving the same hash. It still should be difficult finding even one pair of messages giving the same hash, or a message for a given hash.)
You need an encryption algorithm. Most probably asymmetric encryption (using public keys to encrypt, private keys to decrypt) is a good idea.
Don't invent new cryptographic data formats or protocols. You will make mistakes, which make your product insecure.
For email encryption, use either OpenPGP (RFC 4880) or S/MIME (RFC 3851), or some subsets of one of these.
You can then use any library which supports the necessary algorithms, or some library which supports specifically these file formats.
SHA256 and MD5 are One way functions. i.e. There is no decryption. See Hashing http://en.wikipedia.org/wiki/Cryptographic_hash_function.
But you really need to read up on encryption procedures before attempting to create a secure communication.
That being said wikipedia has an article dedicated to implementations http://en.wikipedia.org/wiki/AES_implementations

Password protecting embedded firmware download

I need to protect against the users of our product from downloading firmware that is incompatible with the revision of the hardware that they're trying to download to. I'll describe what exists right now and what I'm looking for.
We have an alpha-numeric hardware part number and revision stored in EEPROM that is only factory programmable. When a customer attempts to download a firmware file he will have to enter a password that is distributed with the firmware release. The existing firmware needs to be able to use this password to verify that the new firmware is compatible with the current hardware revision. Keep in mind that more than one hardware revisions may be compatible with a single released version of firmware.
Is there some form of public key cryptography that can be used to validate multiple hardware revision numbers to a key that is generated during the firmware build process? The hardware revision number(s) would act as the private key while the password entered by the customer to unlock the download mechanism would be the public key.
The embedded firmware is written in C and it would be great if the encryption algorithm were the same. It can be C++ as long as it has an interface that lends itself to being called from C functions.
There are a couple of hardware revisions out in the wild, but we can ignore those exist for now. Let's say a brand new product is going to be released that includes this feature, so it will be revision 0.
The password will be transferred from the client's computer to the embedded hardware without any modifications. So the decryption and password matching needs to happen in the embedded firmware, which will then report success / failure back to the client. The reason for this is that it may not always be a laptop being used to download the firmware. It'll more likely be a handheld download tool so options for executing custom software are limited.
Forget the passwords.
The simplest way to do this is to include in the firmware file, at a known location, a list of compatible hardware IDs. This could be stored as a length-prefixed array. When a new firmware is to be loaded into a device, the device looks for its own hardware ID in the list, and rejects the firmware if it is not present.
Such a system is robust, easy to understand and easy to debug. If space is a concern then you can store the list as a bitset, with each hardware revision allocated a bit.
If you wish to prevent active tampering, you can further sign the entire firmware file, including the list of compatible hardware IDs, with a normal public key signature algorithm like DSA or RSA.
So we assume this is a fresh design:
I am not really how much security you want/need and how processing power your device has...
I would make the firmware package consist of two parts - a header and the "real thing".
Both should be encrypted differently and then signed independently plus together (this is the public key cryptography part).
first check the outer signature
then check the signature of header (which must be calculated based on the header, header length plus the password)
The header is encrypted with the password you distribute and contains a list of hashes of the compatible hardware revisions (these hashes are calculated from the hardware revision + password).
The device decrypts the header, hashes its own revision from the EEPROM accordingly (again revision + password) and tries to find a match in the list.
IF it finds a match then it takes the hash of the list in the header.
with the hash of the list it check the signature of the the "real thing" (calculated on the encrypted content plus length plus password plus hash of the list)
if the signature is valid it proceeds decrypting the "real thing" (key would be password + hash of list)
For the signature part you create a cert, sign that cert with your root cert... the derived cert would be embedded into the devices... so you create the signatures with the private key of that cert and check them in the device with the public key.
The above is NOT 100% secure but provides several aspects:
tampering with package would be always detectable (as long as you don't loose your private key that is)
it won't be installable on any incompatible hardware revision
figuring out the scheme wouldn't allow for installation on incompatble hardware revisions (except if your customer somehow modifies your hardware)
IF that is two much calculations etc. you could always simplify the scheme... at the bare minimum I would keep the outer signature and the password...
EDIT - after some discussion (see comments):
The base algorithms to create the "password" I suggest consists of 2 parts - a hashing algorithm and an encryption algorithm:
hashing algorithm
The respective firmware should be hashed ("good" algorithms are SHA-512, SHA-384, SHA-256, MD5 - "VERY WEAK" algorithm would be CRC32)
encryption algorithm
The password would be encrypted using either an asymetric algorithm (like RSA, EC etc.) or a symetric algorithm ("strong" ones are AES, Blowfisch etc. - "weak" ones are for example DES - "VERY WEAK" is for example XOR)
The scheme consists of the following steps:
hash the firmware with any of the above hashing algorithms
build a string consisting of part number/ revision number + firmware hash
encrypt the string with any of the above mentioned encryption algorithms (asymetric means you use the private key, symetric means you use the same key for encryption/decryption)
The device need to contain a secret key (which is either the public key if asymetric encryption is used or the key in case of symetric encryption) and the part number/revision number.
Checking the firmware against the password means decrypting the password, hashing the firmware and comparing the part number/revision number and firmware hash...
Security aspects versus processing requirements:
asymetric encryption means handling big number (1024 bit or bigger)
IF the device is not capable of handling that you should perhaps take a symetric encryption.
symetric encryption means that IF your customer reads out the key from your hardware he would be able to create "valid passwords" himself while in the asymetric case this won't be possible
you could stick with hashing only (hash the firmware plus part numerb/revision number) and provide the result as a password but this leaves you open to a customer figuring the algorithm used out and then they can create themselves "valid passwords"
Some relevant links:
http://www.cryptosys.net/
http://www.openssl.org/
http://www.cryptopp.com/
http://en.wikipedia.org/wiki/Public-key_cryptography
http://en.wikipedia.org/wiki/Symmetric-key_algorithm

Advice about the Encryption Method I should Use

Ok, so I need some advice on which encryption method I should use for my current project. All the questions about this subject on here are to do with networking and passing encrypted data from one machine to another.
A brief summary of how the system works is:
I have some data that is held in tables that are in text format. I then use a tool to parse this data and serialize it to a dat file. This works fine but I need to encrypt this data as it will be stored with the application in a public place. The data wont be sent anywhere it is simply read by the application. I just need it to be encrypted so that if it were to fall into the wrong hands, it would not be possible to read the data.
I am using the crypto++ library for my encryption and I have read that it can perform most types of encryption algorithms. I have noticed however that most algorithms use a public and private key to encrypt/decrypt the data. This would mean I would have to store the private key with the data which seems counter intuitive to me. Are there any ways that I can perform the encryption without storing a private key with the data?
I see no reason to use asymmetric crypto in your case. I see two decent solutions depending on the availability of internet access:
Store the key on a server. Only if the user of the program logs in to the server he gets back the key to his local storage.
Use a Key-Derivation-Function such as PBKDF2 to derive the key from a password.
Of course all of this fails if the attacker is patient and installs a keylogger and waits until you access the files the next time. There is no way to secure your data once your machine has been compromised.
Short answer: don't bother.
Long answer: If you store your .DAT file with the application, you'll have to store the key somewhere too. Most probably in the same place (maybe hidden in the code). So if a malicious user wants to break your encryption all he has to do is to look for that key, and that's it. It doesn't really matter which method or algorithm you use. Even if you don't store the decryption key with the application, it will get there eventually, and the malicious user can catch it with the debugger at run time (unless you're using a dedicated secured memory chip and running on a device that has the necessary protections)
That said, many times the mere fact that the data is encrypted is enough protection because the data is just not worth the trouble. If this is your case - then you can just embed the key in the code and use any symmetric algorithm available (AES would be the best pick).
Common way to solve your issue is:
use symetric key algorithm to cipher your data, common algorithm are AES, twofish. most probably, you want to use CBC chaining.
use a digest (sha-256) and sign it with an asymetric algorithm (RSA), using your private key : this way you embed a signature and a public key to check it, making sure that if your scrambling key is compromised, other persons won't be able to forge your personal data. Of course, if you need to update these data, then you can't use this private key mechanism.
In any case, you should check
symetric cipher vs asymetric ones
signature vs ciphering
mode of operation, meaning how you chain one block to the next one for block ciphers, like AES, 3DES (CBC vs ECB)
As previously said, if your data is read andwritten by same application, in any way, it will be very hard to prevent malicious users to steal these data. There are ways to hide keys in the code (you can search for Whitebox cryptography), but it will be definitely fairly complex (and obviously not relying on a simple external crypto library which can be easily templated to steal the key).
If your application can read the data and people have access to that application, someone with enough motivation and time will eventually figure out (by disassembling your application) how to read the data.
In other words, all the information that is needed to decipher the encrypted data is already in the hand of the attacker. You have the consumer=attacker problem in all DRM-related designs and this is why people can easily decrypt DVDs, BluRays, M4As, encrypted eBooks, etc etc etc...
That is called an asymmetric encryption when you use public/private key pairs.
You could use a symmetric encryption algorithm, that way you would only require one key.
That key will still need to be stored somewhere (it could be in the executable). But if the user has access to the .dat, he probably also has access to the exe. Meaning he could still extract that information. But if he has access to the pc (and the needed rights) he could read all the information from memory anyways.
You could ask the user for a passphrase (aka password) and use that to encrypt symmetrically. This way you don't need to store the passphrase anywhere.