What's the best method of Encryption whilst using ProtoBuf? - serialization

I've migrated my database on my mobile device away from VistaDB because it's just too slow. I'm now using ProtoBuf instead to create a series of flat files on a Storage Card, the only issue is there's obviously no encryption.
Which encryption method works best with ProtoBuf? I'm basically serializing a collection of data entities to a file, then deserializing from the File back into my collections. I figure the best place to put the encryption would be in the FileStream on the read/write.
The data will contain NI numbers, names and addresses, so this has to be secure. Any idea anyone?

I think you're on the right track. You should just be able to do something like:
ICryptoTransform encryptor = ...
Stream encStream = new CryptoStream(outputFileStream, encryptor, CryptoStreamMode.Write);
Serializer.Serialize(encStream, obj);
encStream.FlushFinalBlock()
encStream.Close();
ICryptoTransform decryptor = ...
Stream decStream = new CryptoStream(inputputFileStream, decryptor, CryptoStreamMode.Read);
Serializer.Deserialize<Type>(decStream);
decStream.FlushFinalBlock()
decStream.Close();
For the basics of .NET's encryption framework (including how to get the ICryptoTransform objects, see other questions like What’s the best way to encrypt short strings in .NET?.

Another option is to actually encrypt the entire folder where the data is stored by installing a system-wide file system filter. The advantages here are that:
Your app code is agnostic to the encryption and the encryption will be done in native code.
Since the encryption is done in native code, it's going to be faster
Since the encryption is not inside managed code, it's a lot harder to reverse engineer and figure out your keys, salts, etc.
Of course the disadvantage (for those who don't write C anyway) is that you can't write it in C#.

If you are concerned about key confidentiality. Have it be password based, And hash the manually entered password multiple times to generate a key.

Related

Google App Engine: Is there any security concern with giving away datastore urlsafe entity keys in an API?

I want to give out anonymous IDs to certain entities in a public token-based API.
Is there any reason I shouldn't be using the urlsafe string of entity keys for that, since they are already anonymized (at least in my case, where I’m not using my own data to construct the key?
Google App Engine and the Datastore are considered safe as long as I'm not handing anyone the key, which I'm not, right?
Thank you.
One of their documentations says ....The urlsafe keyword parameter uses a websafe-base64-encoded serialized reference but it's best to think of it as just an opaque unique string.... I think this is what you're referring to when you say it is anonymized
But a subsequent documentation says ....The string representation of a key looks cryptic, but is not encrypted! It can be converted back to the raw key data, both kind and identifier. If you don't want to expose this data to your users (and allow them to easily guess other entities' keys), then encrypt these strings or use something else....
You can decode the key yourself via base64 - usually there is no risk in giving it away.
The huge risk is in taking an urlsafe entity keys as parameters and using them to read from the datastore. An attacker can trick your application in reading arbitrary data from your datastore project. This is to my knowledge nowhere documented.
So basically, any variant of this is a no-go in a web server:
def get(params):
data = datastore.get(urlsavedeccode(params.key))
return data
Any key supplied from the outside should be never used with the datastore since you can not be shure you are reading the kind / path you are expecting. This is basically the same scope of risk as SQL injection.

Send RSA public key over socket them import it for encryption [VB .NET]

I'm writing that generates public and private key pair, then send the public key over the socket to another programs to be used to encrypt string data.
I'm using RSA in VB.NET and I was able to generate the required keys:
My public key v+u4Lt4nyLXincU+wbReOTU3nwiTZ7MlFkA7cytLOjuviHrAdnaVAV8+WoFhy9nADGtk1K0OLAE1ZwGzt/kgUw==
My question is: is the public key enough for encryption by other users? and if so, how can I import it to RSA parameters to encrypt data?
Edit:
I used the following code in an attempt to import the public key but it failed:
Dim Parameters As New RSAParameters
Parameters.Modulus = encoder.GetBytes(publicKey)
RSA.ImportParameters(Parameters)
My question is: is the public key enough for encryption by other
users?
The answer is as so often: It depends.
The way you describe your proposed protocol this would be widely open to man-in-the-middle-attacks. Eve could just intercept the message on the wire and replace the key by her own.
From a theoretical point of view, it is sufficient to encrypt data. However, to be useful in real world scenarios, you have to use symmetric encryption as well.
So here is my advice:
Don't do your own protocols if you have to ask such questions. Never. Not once. Use Well known, established technology like TLS!
I had a similar project in VB.net, you will not be able to send messages of a large length because if you are using 2048bit RSA, the maximum size of data you would be able to send would be 245 bytes. https://security.stackexchange.com/questions/33434/rsa-maximum-bytes-to-encrypt-comparison-to-aes-in-terms-of-security
I used the RSA public key so each client would use AES encryption and pass their own keys which are encrypted with RSA, the server would then decrypt the key and use that to resolve data. This uses both asymmetric(RSA) and symmetric encryption(AES). Here is a link with a useful video that explains this when I was doing this project. https://www.youtube.com/watch?v=6H_9l9N3IXU&t=271s
The way I imported the keys was using the .toXMLString and .fromXMLString in the RSA CryptoServiceProvider. Here is a great link explaining it, probably doing a better job that I could. https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsa.toxmlstring(v=vs.110).aspx
I found this page that was very useful for me here
Also I found that I was making the mistake of converting the encrypted byte array to string after encryption then back to byte array just before decryption. The last byte array didn't have the same size as the original.

Sending a file from a java client to a server using wcf method?

I want to build a wcf web service so that the client and the server would be able to transfer files between each other. Do you know how I can achieve this? I think I should turn it into a byte array but I have no idea how to do that. The file is also quite big so I must turn on streamed response.
It sounds like you're on the right track. A quick search of the interwebz yielded this link: http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP
Your question indicates that you want to send a file from a java client to a WCFd endpoint, but the contents of your question indicate that this should be a bidirectional capability. If this is the case, then you'll need to implement a service endpoint on your client as well. As far as that is concerned, I cannot be of much help, but there are resources out there like this SO question: In-process SOAP service server for Java
As far as practical implementation, I would think that using these two links you should be able to produce some code for your server and client.
As far as reading all bytes of a file, in C# you can use: File.ReadAllBytes It should work as in the following code:
//Read The contents of the file indicated
string fileName = "/path/to/some/file";
//store the binary in a byte array
byte[] buffer = File.ReadAllBytes(fileName);
//do something with those bytes!
Be sure to use the search function in the future:

Commutative cipher recognizing proper decryption?

In theory, let's say I'm using a commutative symmetrical cipher to create my own kind of encrypted file. I know that an encrypted rar/zip would do what I'm thinking of, but I'm looking to understand the under the hood details. If I just encrypt the file with no meta data, then how can I know when I decrypt it that it's properly decrypted?
One approach I thought of was to place the key used at the front of the file and then encrypt the key along with the file. When I decrypt, I can compare the decryption key with the beginning of the file and know if it worked, but I'm uncomfortable with actually placing the key inside the file.
Another idea would be placing a static section of data at the beginning of the file, but that can be used as an indicator when trying to brute force the file to when a collision in keys (or the actual key) is discovered if anybody knows the static section of data and I don't like security through obscurity.
My last thought is to include the hash of the initial unencrypted file, but for large files that can slow down the process. With this approach, I have to hash and encrypt the file and that seems inefficient. I'm hoping there's a better technique.
What would be the best approach to verify that an file that was encrypted with a commutative symmetrical cipher was decrypted successfully (without having the original file to compare to)?
Use a header with a well defined, but random format. One standard way to do this is with random data and cryptographic hashes (pseudo-code follows):
byte[] header = new byte[64];
header[0..31] = RandomBytes(32); // 32 cryptographically random bytes
header[32..63] = SHA256(header[0..31]); //Hash of your random data
This gives 64 bytes of high entropy data. There is no way this can be used crib for brute-forcing the encryption. To validate you have the proper key, just decrypt the header and check to make sure that the second 32 bytes are a valid SHA256 hash of the first.
I would still recommend storing a hash or checksum. If you put it at the end of the encrypted data, you can generate the checksum as you read the file during the encryption, so it doesn't require any extra passes through the file. (There will be CPU overhead for the checksum, but that'll be minimal. You don't need to use something as expensive as SHA for this purpose; CRC32 will do.)
The checksum will help detect errors in transit. If a single bit in the encrypted data is altered, the decrypted data past that point will probably be garbage. A magic header won't detect that, but a checksum will.
There are cipher modes like CCM that provide integrity. I'm not sure how they would fit with your requirement for commutativity.

Encryption for Executable

Can anyone recommend what's a good way to encrypt an executable? I was trying to use AxCrypt but I don't like the usage, i.e. you specify a passcode and the person who launches the exe needs to specify the passcode. Is there someway to encrypt it once and users just run the exe without specifying any passwords?
It's basically pointless. If it's a .NET or Java program, obfuscators can improve performance and decrease the executable size and make it difficult to reverse engineer. Packers can decrease executable size. Signing can provide assurance to your users that you built the program. But encryption of the executable for the purpose of hiding it's executable code is rather pointless.
A program which knows how to decrypt itself will contain all the information a hacker needs to compromise the program. You are handing out the lock with the key. However, lets assume you want to put up a small barrier to entry to your program. Maybe you have cheat codes in your game and you don't want someone to be able to just run 'strings' over your program and view them.
What I suggest is packing your program with an a program like UPX. This can further obfuscate your program on disk. Your basic interrogation techniques will only see the tiny decompressor. However, a determined hacker will quickly recognize the compressor program and decompress it. In either case, once a program is running in memory, one can take a core dump of the process, or attach a debugger to it. There isn't much you can do to prevent this on most hardware.
You guy's don't understand the question, it's normal for a programmer to think that way. But as a ethical hacker it is clear that he wants to bypass the antivirus not hide the code, anyway you may use Visual Basic.
for encryption use this code
Public Function TripleDES_Encrypt(ByVal input As String, ByVal pass As String) As String
Dim TripleDES As New System.Security.Cryptography.TripleDESCryptoServiceProvider
Dim Hash_TripleDES As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim encrypted As String = ""
Try
Dim hash(23) As Byte
Dim temp As Byte() = Hash_TripleDES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
Array.Copy(temp, 0, hash, 0, 16)
Array.Copy(temp, 0, hash, 15, 8)
TripleDES.Key = hash
TripleDES.Mode = Security.Cryptography.CipherMode.ECB
Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = TripleDES.CreateEncryptor
Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(input)
encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Return encrypted
Catch ex As Exception
End Try
End Function
for decryption
Public Function TripleDES_Decrypt(ByVal input As String, ByVal pass As String) As String
Dim TripleDES As New System.Security.Cryptography.TripleDESCryptoServiceProvider
Dim Hash_TripleDES As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim decrypted As String = ""
Try
Dim hash(23) As Byte
Dim temp As Byte() = Hash_TripleDES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
Array.Copy(temp, 0, hash, 0, 16)
Array.Copy(temp, 0, hash, 15, 8)
TripleDES.Key = hash
TripleDES.Mode = Security.Cryptography.CipherMode.ECB
Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = TripleDES.CreateDecryptor
Dim Buffer As Byte() = Convert.FromBase64String(input)
decrypted = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Return decrypted
Catch ex As Exception
End Try
End Function
If you only want specific users to run the exe then, you can define policies under windows that would allow you to run it for only specific users.
but if you want to hide code then:
since you have not mentioned which language you used to make the exe. If its c/c++ its already encrypted enough, it requires some work to get the code from it. If its java or csharp there are obfuscators that you can use. it would somewhat make it difficult to get the code from exe.
To answer the OP, I am not aware of a product that does this. It seems to me that it should be possible.
I'm guessing you are trying to protect your intellectual property by encrypting your executable and not to bypass antivirus programs as others have suggested.
First, a password probably does little to protect your IP by itself. But if that is all you want, then you should be able to save the password to a credential manager.
The problem I see offhand with just a password is that customers could easily share it.
Additional issues with any system: Did you decrypt the executable to storage media? If so, the unencrypted executable can be found and copied. Will the executable run strictly from memory, and if so, how do you keep it from being read from memory using a VM or debugger? If you have another trick, will it work correctly if parts of your program are swapped to disk in a low memory situation?
If decryption is just an algorithm, the algorithm will be on the machine and can be found and reversed engineered.
If the method uses asymmetric (public/private) keys, and the necessary key is available on the machine, the key can be found.
The decryption key will need to be somewhere. If an online broker provides it, you rely on the broker to protect the key that does the decrypting. If you act as the online broker for your customers, you will have more control over the process and you also get to do all the heavy lifting.
A scenario could be that you have a separate public/private set of keys to talk to the key broker. Collect information from the customer machine, encrypt that information into a packet with one of the keys and send that to your key broker system. The key broker has the other key to decode that packet, validates the customer machine is authorized to use the program, and sends the separate decryption key to decrypt the program.
My general answer is that it should be possible to protect your IP without needing to type a password in each time, but it won't be easy and I don't know of any implementations. As others have mentioned, obfuscation is what most people use.