I need to send an encrypted data through a socket in C. So I make my payload like:
message_type|flags|message_1|message_2
I want to encrypt the message_x with AES.
For security concerns, I need to keep the message_x length for the ciphertext. That's why I am using the OpenSSL AES-CTR mode.
But there's the problem. The output is completely awful, like �3Y������ȳ�_�[��. And there are characters like [, _, etc. Every character could appear in the output. So the receiver won't be able to unserialize the payload because, perhaps, the delimiter (| in the example) has been generated by AES...
I saw base64 conversion could do the trick. But the conversion changes the length of the ciphertext (like explained in this article).
Does anyone have any ideas ?
Related
There is a problem parsing the subject in the mail header.
For example, the form of the subject is as follows.
subject: =?iso-2022-KR?B?DjlMOC4PIA....gyDzogT?=
My guess is that base64 decoding should include the escape character -SO, SI, ESC$)C-. However, decoding is not included.
How can I get a normal string?
I hope the results are as below.
Subject: like this, 안녕하세요.
Please give me a hint how to respond at the code level. in C
Update
sorry. I had a SO, SI, but I missed it. But there was no ESC$)C, The problem is resolved immediately and shared for others.
In the absence of a ESC$)C, the libiconv is a problem, but the gconv(in glibc) was not a problem. What I used was the libiconv. Changing to gconv has solved the problem.
thanks.
So in =?iso-2022-KR?B?DjlMOC4PIA....gyDzogT?= the Bsandwiched by question marks means base64 encoded. The iso-2022-KR is the character set. The DjlMOC4PIA....gyDzogT is the base64 encoded title.
You first base64 decode the title. It's easy to find a solution for this in C.
This will leave you with an array of binary bytes which is the title encoded in the ISO-2022-KR character set. Presumably you want to convert that to UTF-8 or some other character set your computer can handle. Your best bet for this part is to use a character set conversion utility. If you are on Linux or macOS, you can use the iconv library. See iconv_open, iconv and iconv_close.
Where is correct checking char* array is AES 128/192/256 crypt, or non crypt - is text?
not use OpenSSL, pls.
tldr: If you want a 100%-working solution, it´s completely impossible.
Long version:
First, stop thinking "binary vs text". That´s not how it works.
AES ciphertext surely is binary data in the computer, but "text" is too.
If you want do distinguish AES ciphertext from other non-AES data, it´s impossible because:
AES ciphertext can be some unreadable gargabe, but it can be a poem of Goethe too.
Every possible data thing can be ("is") a AES ciphertext for some plaintext with some key.
Non-AES data can be as much unreadable garbage as AES data. (Pseudo-) Random bytes as example: AES with proper input is an excellent random byte generator.
The other way round; if you want to distinguish proper and sane human-readable text from other things, it´s impossible because: There is no law or something what "text" is in your computer.
If you want to search for english letters, consider following points:
As said above, readable words can be AES ciphertext too.
English letters? What´s about German, Japanese, old Greek, Russian...?
How are letters mapped to bytes? ISO88591, UTF16LE with BOM, EBCDIC, own mappings...?
What´s about file formats like MS Word *.doc? In it, there´s text
too, yet it´s binary "garbage" data. Or compression algorithms: Gzip,
Rar etc. doesn´t make text less sane.
If you finally extracted proper letters, how do you know if it isn´t something like "miodsjoiusdJf"? Recognizing words and their meaning is a very big topic on it´s own, and nearly everything in it is guesswork.
I am trying to make a simple application, which is able to encrypt and decrypt some simple data. CryptEncrypt is working fine. The string to encrypt is: This is a sample string.. The encrypted data for this string is: ¼╩b╒áó√ $~ë▀i▐└╕ ]Φwµσ╨|V╜▐µáïÅ╚
So far so good.
After i have the encrypted text, i copy it to another string. This string will be used at the decryption. For some reason only the half of the string wil be copied in the new buffer,a nd therefore it can't be decrypted.
No matter how i try. I'm assumeing that in the encrypted string there are some special characters, and therefore it won't copied as expected. For example if i use sprintf(teststring,"%s",Encryptedstring); it will also copy only half of the string.
Is there a way to make CryptEncrypt encrypt the data in a hex form by default?
How should i copy my string correctly?
You are making a basic mistake:
You are handing a c-string (I cannot say whether with or without the terminator) to CryptEncrypt and somehow expect magically to get a valid c-string of the same length back.
Things just don't work that way, the output of any good encryption-function looks like a pseudo-random binary blob, maybe with embedded 0-bytes, maybe not, and unlikely to have a terminating 0-byte.
Case in point, the output you gave is considerably longer than the input (The last part is probably garbage picked up due to missing 0-terminator).
The solution: Properly handle arbitrary binary data as arbitrary binary data (memcpy for copying).
If you want, you can encode it into some textual representation to get a string, but that's an extra step needing more space and certainly not the task of CryptEncrypt.
My advice is that when you talk about encryption, do not talk in terms of strings. Your string is just a raw data block to an encryption function so deal with it accordingly. The problem with dealing the data as string is that string tends to terminate if a null character is found and there is every possibility that you will get null byte in encrypted block.
This is why string functions dont work with encrypted data. If you want to copy data from buffer to another buffer, use memcpy instead of sprintf or strcpy.
I guess that sprintf will stop the copy if it encounters a '\0' charcater. You should use memcpy
Good Afternoon all,
I am working over rsa encryption and decryption, for more security i am also using padding in cipher text, for different input (amit) , i am getting different length output like-
plain text- amit
cipher text-10001123A234A987A765A
My problem is- For big plain text ,my algo generate large size cipher text, and i thought,
it is wastage of resources to keep long string in database ,
Is there any way with the help of that i can compact cipher and convert real cipher when i will require?
In order for the algorithm to be encryption and not just hashing, it must be reversible. To be reversible, the output must contain as much information as the input, and so is unlikely to be significantly shorter.
You may compress the data before encryption. There's not a lot else you can do unless you're willing to give up the ability to recover your original text from the ciphertext.
There are a couple of possibilities:
Change your encryption scheme there are schemes where the size is same as the input size
Compress your data before you encrypt, this will be effective only if you have a large block of text to encrypt and then there's the additional overhead of decrypting too.
This doesn't apply to RSA specifically, but: any secure cipher will give output close to indistinguishable from a random bit pattern. A random bit pattern has, per definition, maximum information theoretic entropy, since for each bit, both 0 and 1 are equally likely.
Now, you want a lossless compression scheme, since you need to be able to decompress to the exact data you originally compressed. An optimal compression scheme will maximize the entropy of it's output. However, we know that the output of our cipher already has maximum entropy, so we can't possibly increase the entropy.
And thus, trying to compress encrypted data is useless.
Note: Depending on your encryption method, compression might be possible, for example, when using a block cipher in EBC mode. RSA is a completely different beast altogether though, and, well, compressing won't do anything (except quite possibly make your final output bigger).
[Edit] Also, the length of your RSA ciphertext will be in the order of log n. With n your public modulus. This is the reason that, especially for small plaintexts, public key crypto is extremely 'wasteful'. You normally employ RSA to setup a (smaller, e.g. 128-bit) symmetric key between two parties and then encrypt your data with a symmetric key algorithm such as AES. AES has a block size of 128 bits, so if you do straightforward encryption of your data, the maximum 'overhead' you incur will be length(message) mod 128 bits.
erm ... you wrote in a comment here that you apply RSA encryption to all single characters:
i am using rsa- it perform over
numbers to convert amit in cipher text
first i do a->97 m->109 i->105..and
then apply rsa over 97 ,109 ... then i
get different integers for 109, 105 or
... i joined that all as a string...
a good advice: don't do that since you will lose the security of RSA
if you use RSA in this way, your scheme becomes a substitution-cypher (with only one substitution alphabet) ... given a reasonably long cypher-text or a reasonable number of cypher-texts, this scheme can be broken by analyzing the frequency of cypher-text-chars
see RSAES-OAEP for a padding scheme to apply to your plaintext before encryption
How can I encrypt & decrypt binary files in C using OpenSSL?
I have a test program that encrypts and then decrypts the input it's given.
I executed my test program for text files, and the output is the same as the input, but when I execute my test program on a binary file the output is not the same as the input.
Just guessing: you are using Windows and missed O_BINARY flag in file operations?
Chances are you are using string functions like strlen() on the buffers you're reading. The OpenSSL functions work fine for binary files.
Without seeing your code we can only guess. But my first guess would be that your encryption or decryption routine is barfing on a \0 character or two within the binary file. The data must be treated as bytes not as character strings. (Same as the StrLen() problem mentioned elsewhere on this page.)
I'm not a C programmer(!) but the way I managed to get the encryption routines working within Delphi/Pascal was by downloading the OpenSSL source (in C) and stepping through the code for the openssl.exe application. Using the EVP_* functions became a whole lot easier once you work out how they do it themselves.