maximum size of string for encrypt in Openssl RSA - c

The function RSA_public_encrypt requires that the variable where encrypted text will be saved, should have a length of RSA_size(*rsa) bytes.
Now, I need to know how big could be the text to encrypt, because if I crypt a little string (for example "asdasd"), there's no problem, but if I try with a bigger string, just a portion of it it's crypt.

Assuming you're talking about RSA_public_encrypt(), the docs state it pretty clearly:
flen must be less than RSA_size(rsa) - 11 for the PKCS #1 v1.5 based padding modes, less than RSA_size(rsa) - 41 for RSA_PKCS1_OAEP_PADDING and exactly RSA_size(rsa) for RSA_NO_PADDING.
Remember that these are block cryptos, in the general case you need to split your input into blocks and feed the blocks one at a time to the encryption function.

Related

How to encrypt variable size of data by using AES (CBC) 128 Algorithm

I want encrypt 4 byte of data, but AES takes 16 byte of data as input and gives 16 bytes as output,
So How to overcome this problem, If some have source code please share
Thanks
To encrypt 4 byte of data we need to add 12 more bytes and make a block of 16 bytes, its take more data length to transfer via wireless, So How to send Encrypted data with Real data length
On encryption, append 12 bytes of random junk.
On decryption, ignore the last 12 bytes.
If length is not fixed, then
[1-bit junk][7-bit bit-length][n-bits of data][128-8-n junk bits to fill to 128]
Cipher block chaining (CBC mode) requires that the plaintext be a mulitple of the block size. If it is not, you'll need to pad it out to a multiple of the block size.
Cipher-feedback mode (CFB mode) exists primarily to avoid this -- as it uses the block cipher as a way of generating key bits to XOR with the the plaintext to encrypt it, it can be used with any bit length and padding is not needed. With CFB mode, however, it is critical to not reuse IVs, as that will directly leak the first block of the plaintext. In CBC mode, reusing IVs is still bad (will leak info about correlated inputs), but arguably not as bad.

Encryption algorithm for 14 byte data

I have an application, where I have to transfer an encrypted packet over BLE advertisement which is fixed 14 byte in length. AES algorithm restricts data to be minimum of 16 bytes long and DES requires it to be in multiples of 8 byte. I have a odd length of 14 byte which I cannot change. Is there any encryption algorithm which can be used to encrypt this 14 byte data. Also it would be good, if someone could point out any C based implementation of the algorithm?
Assuming you mean both plaintext and ciphertext are exactly 14 bytes in length:
Use AES in CTR mode. This yields the same 16 byte chunks of data on each side. You can use 14 of the 16 bytes as an XOR key and discard the last two.
Initialization of the IV is done with 14 bytes of IV and two bytes of zeros.
However, there's a wrinkle here. The underlying protocol is stateless broadcast. The only way to get an IV is to use a unique packet identifier, and there might not be one. Without about 10 additional bytes I would have a very hard time coming up with a unique IV generator.
You can use ECB-based Ciphertext Stealing (CTS) with a block cipher that has a block size smaller than 14 byte. I won't go into detail how CTS works, because the Wikipedia article does a pretty good job.
If you heard that ECB is bad then you are correct. Sadly any other mode requires some sort of IV which will eat away your payload constraint. Since CTS moves a part of the ciphertext to the last plaintext block the bad property of ECB goes away.
Block ciphers with small block sizes such as 64-bit have worse security properties than say block ciphers with 128-bit blocks. Just look at the Sweet32 attack. In your case I would guess that this is not really an issue since an attacker cannot get you to generate many many encrypted broadcasts and if they tried it would take them a really long time.
A popular block cipher with 64-bit block size is DES. You might have heard that DES is easily brute forceable due to the small key size and you would be correct. Triple-DES (EEE or EDE) comes to the rescue which has a key size that is three times larger and has a much better protection against brute force attacks.
Sadly, you cannot use AES because CTS needs at least two blocks to work and a single block of AES already breaks your size constraint.
Both AES and DES are Block Cipher algorithms, so you're right that they have minimum sizes for the blocks they can handle. BUT there are many different ways to use block encryption, some of which can process streams of data of arbitrary length. Check out "s-bit Cipher Feedback Mode" where the s is the size of the actual chunks that are individually being encrypted. Here you could use s=2.
Why not frame your data so that it features:
header
payload
padding
The header would contain the length of the data, plus maybe a "magic" code to check synchronisation. The payload is your data. The padding is then a block of zeroes (or random numbers if you so wish) in order to fit the necessary multiple of blockside for the block-cipher.
Assuming you want to transmit in the same 14 bytes you are a bit stuck. The suggestions above mean that you would need to transmit 16 bytes (or even more), then ignore the last 2 bytes.
How secure do you need the data to be? One answer might be to use DES to encrypt all the full blocks (one block of 8 bytes in your case), then use something weaker to encode the remaining (6 in your case) bytes.
A reasonably secure way would be to simply xor the previous 6-byte decoded byte values over your remaining 6 bytes of tail data. Until the DES protected data has been decoded, the xor value cannot be determined.
Of course, if the DES portion was all-zeros then your tail codes are going to be visible. If this is a rare occurrence this may not be an issue as the hacker does not know that the DES data is zeros. You don't have a lot of data, so it is hard to think of much more that you could do.
In general, you could generate a 64-bit (8-byte) checksum of the previous 1K of original data, and use this as the xor. In general you will have a number less than 8 bytes of tail data, which you would xor, and only transmit the number of bytes. On decode, the remaining bytes are ignored.

crypt library and block size

I am using a 128-bit AES symmetric-key encryption function that was given to me. I keep getting this seg fault while decrypting:
:error:0606506D:lib(6):func(101):reason(109):evp_enc.c:518:
At first when testing encrypting/decrypting together, I would get this error because my buffer to store the encryption and decryption wasn't large enough. Please help me troubleshoot:
When storing the key (using fgets), for some reason the char array to store it required size 34 instead of 33 (i dont think this is the problem but who knows)
the formatting i'm using to decrypt is wrong (I am pretty sure it requires raw binary, ive tried hex as well)
something else is messing with the block size.
What else could this be from?
128-bit aes symmetric-key length must have to be 16 byte.
also 256-bit aes symmetric-key length must have to be 32 byte.

Encryption and Decryption using AES in Linux Kernel

I want to encrypt files during their creation and decrypt files during their read operation using AES algorithm. I have also written code in vfs_write() and vfs_read() for encryption and decryption respectively and also it is working nicely, but the only problem now is that k whenever I pass a file to vfs_write() whose length is not multiple of 16 (AES BLOCK SIZE) den AES does padding to it to make it a multiple of 16 and bcz of this the size of the file increases but the write() function does not know about this and so it rejects
e.g.:- suppose i enter data as "123", here length is 4 (3 length of data + 1 '\0' character) and so AES padds 12 bytes to it to make it 16 bytes (as AES works on 16 bytes blocks), but write() only takes original length which was 4, and so i want to know how to change the file size to 16 (in this case) and also where to do it in kernel code.
i tried this
inode->i_size=new_length;
inode->i_op->truncate(inode);
also i tried
if(file->f_flags & O_APPEND)
*pos=i_size_read(inode);
but this is not working bcz kernel hangs and also i am not understanding where to do such things i.e., in which function and how.
also i tried changing the count variable with new length in vfs_write() but then it gives error as "cat write error: No space left on device".
it works fine when i pass file which is a multiple of 16.
Your current mode requires padding; and it can be hard to do padding in some cases (like what you meet). Usually, disk/filesystem encryption is done in other mode, which require no padding (and easy to do random reads/writes).
Overview of block cipher modes: http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
Modes: ECB, CBC, PCBC, CFB, OFB require padding
and mode CTR (Counter) doesn't require padding.
This mode is easy and it is even easier to implement it in wrong (unsafe, easy-to-break) way.
There is an overview of Disk encryption http://en.wikipedia.org/wiki/Disk_encryption_theory with even more advanced modes (XEX, XTS). Some of them still require padding.
Even with universal cipher mode you will get a lot of problems.. Some of them are covered in "Cryptfs: A Stackable Vnode Level Encryption File System"
why dont you deliberately make it 16 bytes, encrypt it and then after decryption discard the padding. I mean instead of relying on aes alone, do it yourself. By this you wil be sure that the data you are getting is correct

how to resize string [ group of numbers and char]?

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

Resources