(C++) Decrypting a custom Polybius square - c++

I'm working on a project related to a cryptography systems, and I need some help. Here's the related code: Link
This is just a main part related to encryption. My goal is to make encryption and decryption. But I'm stuck with the decryption.
My only idea was to decrypt it through the switch-case construction, but it's kinda stupid, right?
So, do you have any ideas what do I need to add to make it decryptable without much CPU and RAM usage?
Thanks in advance!
P.S. This is my first question here, so if I've made something wrong - sorry)

The hardcoded way, using a dictionary (map) or hash table (unordered_map) works. In cryptography it is not uncommon to hardcode tables of data.
You already hardcoded an array for encryption. If you use a hash table or dictionary, that can work both for encryption and decryption, requiring a single one.

Related

Encrypting text file with AES-256 CBC

I've been trying to pick up C++ and computer security in my own free time and I've been attempting some CTF challenges.
The challenge was about finding out the number of words (N) in a text file (x.txt), and using N as a key to encrypt the text file (x.txt) using AES-256 CBC and outputting a new text file (y.txt) with the encrypted contents.
I have no problems getting the number of words from the text file, but I was just wondering if anyone knows how to perform the encryption stated?
I've been reading up on OpenSSL for this but I can't proceed further. I assume the IV would be zero in this case?
Thanks in advance.
I assume the IV would be zero in this case?
An IV or Initialization Vector, is the "seed" for encryption. It is needed so that plaintexts that are similar don't look similar when encrypted. It is meant to never repeat between different encryption runs and is not secret. A zero IV (or any other fixed IV) would thus defeat the purpose.
A typical approach with AES-CBC is during encryption to generate a random IV and store it together with the ciphertext. Then during decryption read it in and use it to initialize the decryptor.
To know more about the OpenSSL API's to use, refer to OpenSSL Wiki - Symmetric Encryption.
I'm currently learning about AES too. Here are some resources I found useful:
How to perform AES encryption:
It boils down to 4 steps per round:
Substitute bytes (using the S-box)
Shifting the rows
Mixing the columns
Adding the round key
There's a really good video about how to perform each AES round by Professor Paar. Here is a link to his AES video. His whole channel is really a gold mine with regards to learning crypto. Note: You will need to hard code the S-box or include it somehow.
One thing Prof. Paar doesn't explain in the video is key expansion (aka how to get each round key). You can find a java implementation of key expansion on Professor Wagner's page here. It should be relatively straight forward to refactor into C++. Just remember to include the round constant table.

Best way to efficiently store (and be able to filter by) hashes in Django

I'm trying to create a Django app where I can look up the hash of a file (md5, sha1, or sha256) in order to get back attributes of that file. Currently, I'm struggling with making a decision on how to efficiently store those values in the database.
I've seen Django's BinaryField, but unfortunately, that appears geared towards purely storage of a password (hash), and the documentation explicitly mentions that you cannot filter on that field when dealing with a QuerySet. This however, is of critical importance for my application. I've seen another post on SA regarding storing MD5 hashes specifically, where it is called out (with good performance numbers) that Django's UUIDField is a perfect fit. However, a UUIDField doesn't support more than 16 bytes, and so doesn't work for SHA1 or SHA256 hashes.
I've looked online to see if someone has come up with a Custom Field implementation for this but came up dry. Does anyone have a good idea on how to proceed? I'm specifically trying to avoid storing the hash as (say) base64 or the hexstring equivalent (using a CharField); I want to just store the bytes of the hash. It seems strange to me that I can't simply store 20 or 32 raw bytes into the database and be able to filter on that.
Thanks in advance! Let me know if there is any more information I can provide.
EDIT: I am using Postgresql as the backend, and python3.

Easy way to encrypt a text file

I'm working on a text based adventure game in C++ and I would like to store quests in a text file,but I don't want the player to read it.
Is there an easy way to encrypt it?
Another way to "hide" content of your file to player is to encrypt the file.
You can use openssl for instance.
In this thread you can have an idea on the usage.
Velthune's OpenSSL suggestion is fine but it is arguably overkill. I would try something simple like XOR encryption instead.
Of course XOR encryption is not secure, but neither is the OpenSSL approach, since your program must store the encryption key somewhere in the executable file in order to be able to do the decryption.
There is no way to truly secure the file's contents against a determined user and still have it be accessible to a program that runs on the user's machine.
So, I'd suggest XOR encryption as a simple form of obfuscation that will deter someone from changing the file casually, yet won't make your program dependent on an external library.

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.

How to prevent a file from being tampered with

I want to store confidential data in a digitally signed file, so that I know when its contents have been tampered with.
My initial thought is that the data will be stored in NVPs (name value pairs), with some kind of CRC or other checksum to verify the contents.
I am thinking of implementing the creating (i.e. writing) and verification (reading) of such a file, using ANSI C++.
Assuming this is the data I want to store:
//Unencrypted, raw data to be stored in file
struct PrivateInfo {
double age; weight;
FitnessScale fitness;
Location loc;
OtherStuff stuff;
};
//128-bit Encrypted Data (Payload to be stored in file)
struct EncryptedData {
// unknown fields/format ??
};
[After I have read a few responses to this question]
Judging by the comments I have received so far, I fear people are getting side tracked by the word "licensing" which seems to be a red flag to most people. I suspected that may be the case, but in todays atmosphere of heightened security and general nervousness, I thought I'd better detail what I needed to be "hiding" lest someone thought I was thinking of passing on the "Nuke password" to some terrorists or something. I will now remove the word "license" from my question.
View it more as a technical question. Imagine I am a student (which I am), and that I am trying to find out about recommended (or best practices) for encoding information that needs to be secure.
Mindful of the above, I will reformat my questions thus:
Given a struct of different data type fields, what is the "recommended" algorithm to give it a "reasonable secure" encryption (I still prefer to use 128 bit - but thats just me)
What is a recommended way of providing a ROBUST check on the encrypted data, so I can use that check value to know if the contents of the file (the Payload of encrypted data) differs from the original.?
First, note that "signing" data (to notice when it has been tampered with) is a completely separate and independent operation from "encrypting" data (to prevent other people from reading it).
That said, the OpenPGP standard does both. GnuPG is a popular implementation: http://www.gnupg.org/gph/en/manual.html
Basically you need to:
Generate a keypair, but don't bother publishing the public part.
Sign and encrypt your data (this is a single operation in gpg)
... storage ...
Decrypt and check the signature (this is also a single operation).
But, beware that this is only any use if you can store your private key more securely than you store the rest of the data. If you can't guarantee the security of the key, then GPG can't help you against a malicious attempt to read or tamper with your data. And neither can any other encryption/signing scheme.
Forgetting encryption, you might think that you can sign the data on some secure server using the private key, then validate it on some user's machine using the public key. This is fine as far as it goes, but if the user is malicious and clever, then they can invent new data, sign it using their own private key, and modify your code to replace your public key with theirs. Their data will then validate. So you still need the storage of the public key to be tamper-proof, according to your threat-model.
You can implement an equivalent yourself, something along the lines of:
Choose a longish string of random characters. This is your key.
Concatenate your data with the key. Hash this with a secure hash function (SHA-256). Then concatenate the resulting hash with your data, and encrypt it using the key and a secure symmetric cipher (AES).
... storage ...
Decrypt the data, chop off the hash value, put back the key, hash it, and compare the result to the hash value to verify that it has not been modified.
This will likely be faster and use less code in total than gpg: for starters, PGP is public key cryptography, and that's more than you require here. But rolling your own means you have to do some work, and write some of the code, and check that the protocol I've just described doesn't have some stupid error in it. For example, it has potential weaknesses if the data is not of fixed length, which HMAC solves.
Good security avoids doing work that some other, smarter person has done for you. This is the virtuous kind of laziness.
Err, why not use a well known encryption system like GPG?
The answers to the edited question depend on the specific scenario.
For q1 (encryption): if you encrypt and decrypt at your servers you can use a symmetric key algorithm. Otherwise you may want to use public key cryptography.
For q2, if you simply want to check if a file has changed you can use any cryptographic hash such as SHA-1 -- assuming that you can make sure that the hash itself wasn't change.
If the data generator and the verifier are both secure you can use MAC algorithm such as HMAC to to verify that the data and the MAC match. But this works only if the secret key remains secret.
Otherwise, you may be able to use digital signatures.
I'm going to change the phrasing of the question and see if it makes people happier (or I get downvoted). There are really two types of questions being asked:
You are making some computer game and you want to know if someone has been messing with your save files. (data signing)
You are writing a messaging program and want to keep people's message logs private. (data encryption)
I will deal with the second one (data encryption). It's a massively difficult topic and you should be looking for pre-built programs (such as PGP/GPG) even then it's going to take you a lot of time to understand and use properly. Think about encryption like this: it will be broken; your job is to make it not worth the effort. In other words make the effort required to break it greater than the value of the information.
As for the first one, again it can be broken. But a checksum is a good idea. see Amnon's answer for some links on that.
Hope this points you in the right direction. I'm not an expert on either topics but I hope this gives you a starting point. (you might want to re-phrase the question and see if you get some better answers)