Decrypting message hashed with SHA256 - c#

I was given a 16 byte key(used to encrypt message in RC4). First 8 bytes are unknown for me. I know that key was created by hashing a message using SHA256(secret) and getting first 16 characters from string obtained from this hashing function. Unfortunately i don't see a way to get the first 8 bytes of this key. As i know SHA256 is one way hashing function(we cant decrypt it). So how i can use half of the key to get a whole? I would be grateful for giving me some advice.

You answered your own question. The point of a hash is that it's very hard to get the original value, and that the hash changes completely when even a single bit is different.
The 8 bytes you're looking for could be anything, dependent solely on the original value that was being hashed. If you don't know the original value, there is no way to determine what the first 8 bytes of the hash are.

Related

AES Key length not matching

I'm sending some encrypted data to a client through a web service.
The client had requested that I encrypt the data using a given key and IV. I know you should ideally use a different random IV each time, and I've already raised that with them.
The IV they have provided is a string of length 25. This really doesn't seem right to me.
As far as I was aware the IV length should match the block size, so either 128, 192 or 256 bytes (String lengths 16, 24 or 32). Am I right, or am I missing something here...?
Please note that the IV was provided to me, and therefore I am not trying to pick it.
The provided IV was of the form "ghPNHfg544JUdfjdR5BGVbj67", which I not believe is correct. (The provided key was a string 16 characters long)

Create a 5 chars unique identifier from a 40 characters string

I have a list of 10 to max 300 string codes (40 word characters capitalized) that need to be stored inside an oauth2 Access Token (Claims based authorization);
I have to keep the token small as much as I can (header size problem) so I'm searching a way to create a small unique identifier representing the original string inside the token.
I would then create a lookup table where I will put the uid and the original string.
When the Token will be sent by the client, through the uid and the lookup table I will get the original string back.
I've read that it is possible to truncate the first bytes of a hash (MD5, SHA1) and I would like to know if I can follow this path safely.
Is it possible to safely (collision wise) create a list of hashes (unique) of these strings where each hash would be 4/5 bytes max?
Edit:
I can't pre-generate a random string as a index (or just a list index for example) because this list could change and increase in size (when the server application is deployed for example and new codes are added to this list) so I have to be sure that when I get the token back from the client, the uid will be bound to the correct code.
Yes, any of those hash algorithms give a uniform hash code where each bit isn't supposed to carry more information than any other. You can just take any 4-5 bytes of it (as long as you take the same bytes from each code) and use as a smaller hash code.
Naturally the collision risk gets higher the shorter the hash code is, but you will still get the lowest possible collision risk for that hash code length.
Edit:
As the question changed; No, you can't create unique identifiers using a hash code. With a long enough hash code you can make collisions rare enough that the hash code can be used as a unique identifer for almost any practical application, but a 32 bit hash code doesn't do that, a 128 bit hash code would do that.

Implement a binary hash like http://www.fileformat.info/tool/hash.htm

I have been struggling for 4 days trying to implement a hash algorithm in c# which works like the FIPS 198 standards document. I have reached a point where I have a value of
06070405020300010e0f0c0d0a0b080976777475363636363636363636363636363636363636363636363636363636363636363636363636363636363636363653616d706c65202332
I took this value and inserted it into the binary hash tool on http://www.fileformat.info/tool/hash.htm and the SHA-1 value is what I am expecting, but I can't replicate this in c#.
Expected value:
SHA-1: 74766e5f6913e8cb6f7f108a11298b15010c353a
When I use the SHA1 class in c# I get the value a969fdc725114c8418ca5c23946bd09977054ff6, which is the same as me entering my value above in the String Hash tool.
Could someone please point me in the right direction to generate what I require.
You will need to convert your hex-string data into a byte array. There are plenty of examples online of how to do this. One example posted to SO already is here (use the StringToByteArray function). Once you have a byte array, pass this through the SHA-1 hash and you should get the output you require.

Encryption/Encoding Algorithm

I have an unencrypted/unencoded string - "565040574". I also have the encrypted/encoded string for this string - "BSubW2AUWrSCL7dk9ucoiA==".
It looks like this string has been Base64ed after encryption, but I don't know which encryption algorithm has been used. If I convert "BSubW2AUWrSCL7dk9ucoiA==" string to bytes using Convert.FromBase64String("BSubW2AUWrSCL7dk9ucoiA=="), I get 16 bytes.
Is there anything using which I can know what type of encryption has been used to encrypt the "565040574" to "BSubW2AUWrSCL7dk9ucoiA=="?
No, there is nothing to tell you how it was encrypted. If you don't have the key to decrypt it then you will be out of luck anyway.
If the plan was to save this to a file or send it in email then it would be base-64 encoded, so that was a good guess.
You may be able to narrow down what it is not by looking at the fact that you have 7 bytes of padding perhaps, but whether it was IDEA or Blowfish or AES, there is no way to know.
Looking at it, from the top of my head I would say AES and more specifically Rijndael.
EDIT:
Just to add, as I said in my comment, without the key you will never know what this is. I am taking it on a best guess scenario, also based on implementations that could be termed "more common", which could also be a complete oversight from me.
Remember that if you can ever outright say what algorithm a ciphertext is in, never, ever use that algorithm.
What can you tell from the data you have? Well, the most concrete bit of information you have is that 9 bytes of cleartext encrypts to 16 bytes of ciphertext. Since it is unlikely that a data compression algorithm is being used on such a small chunk of data, this means we can make an educated guess that:
It is encrypted with a block cipher, with a block size <= 128 bits.
The encryption mode is ECB, since there is no room for an IV.

AES output, is it smaller than input?

I want to encrypt a string and embed it in a URL, so I want to make sure the encrypted output isn't bigger than the input.
Is AES the way to go?
It's impossible to create any algorithm which will always create a smaller output than the input, but can reverse any output back to the input. If you allow "no bigger than the input" then basically you're just talking isomorphic algorithms where they're always the same size as the input. This is due to the pigeonhole principle.
Added to that, encryption usually has a little bit of padding (e.g. "to the nearest 8 bytes, rounded up" - in AES, that's 16 bytes). Oh, and on top of that you're got the issue of converting between text and binary. Encryption algorithms usually work in binary, but URLs are in text. Even if you assume ASCII, you could end up with an encrypted binary value which isn't ASCII. The simplest way of representing arbitrary binary data in text is to use base64. There are other alternatives which would be highly fiddly, but the general "convert text to binary, encrypt, convert binary to text" pattern is the simplest one.
Simple answer is no.
Any symmetric encryption algorithm ( AES included ) will produce an output of at minimum the same but often slightly larger. As Jon Skeet points out, usually because of padding or alignment.
Of course you could compress your string using zlib and encrypt but you'd need to decompress after decrypting.
Disclaimer - compressing the string with zlib will not guarantee it comes out smaller though
What matters is not really the cipher that you use, but the encryption mode that you use. For example the CTR mode has no length expansion, but every encryption needs a new distinct starting point for the counter. Other modes like OFB, CFB (or CBC with ciphertext stealing) also don't need to be padded to a multiple of the block length of the cipher, but they need an IV. It is unclear from your question if there is some information available from which an IV could be derived pseudorandomly an if any of these modes would be appropriate. It is also unclear if you need authentication, or if you need semantic security> i.e. is it a problem if you encrypt the same string twice and you get the same ciphertext twice?
If we are talking about symetric encription to obtain the original encrypted string from a cyphered one it is not possible. I think that unless you use hashes (SHA1, SHA256...) you will never obtain a cyphered string smaller than the original text. The problem with hashes is that they are not the solution for retrieving the original string because they are one way encryption algorithms.
When using AES, the output data will be rounded up to have a specific length (e.g a length divisible trough 16).
If you want to transfer secret data to another website, a HTTP post may do better than embedding the data into the URL.
Also just another thing to clarify:
Not only is it true that symmetric encryption algorithms produce an output that is at least as large as the input, the same is true of asymmetric encryption.
"Asymmetric encryption" and "cryptographic hashes" are two different things.
Asymmetric encryption (e.g. RSA) means that given the output (i.e. the ciphertext), you can get the input (i.e. the plaintext) back if you have the right key, it's just that decrypting requires a different key than the key used for encrypting. For asymmetric encryption, the same "pigeonhole principle" argument applies.
Cryptographic hashes (e.g. SHA-1) mean that given the output (i.e. the hash) you can't get the input back, and you can't even find a different input that hashes to the same value (assuming the hash is secure). For cryptographic hashes, the hash can be shorter than the input. (In fact the hash is the same size regardless of the length of the input.
And also one more thing: In any secure encryption system the ciphertext will be longer than the plaintext. This is because there are multiple possible ciphertexts that any given plaintext could encrypt to (e.g. using different IVs.) If this were not the case then the cipher would leak information because if two identical plaintexts were encrypted, they would encrypt to identical ciphertexts, and an adversary would then know that the plaintexts were the same.

Categories