5

From this on how to achieve password based encryption it is clear that i need to save salt, IV and cipher text in order to decrypt it later.

From this iv and salt can be stored along with cipher text

I am storing the hex value in this format

DatatypeConverter.printHexBinary(salt) + DatatypeConverter.printHexBinary(iv) + DatatypeConverter.printHexBinary(ciphertext);

Do i need to store the values in Binary format ?

DatatypeConverter.printBase64Binary(salt) + DatatypeConverter.printBase64Binary(iv) + DatatypeConverter.printBase64Binary(ciphertext));

output clearly indicates the where the salt , iv is ending which is awful

lIvyAA/PZg4=fE4gTZUCPTrKQpUKo+Z1SA==4/gAdiOqyPOAzXR69i0wlC7YFn9/KOGitZqpOW2y3ms=

Will storing in hex format have any effects of data loss ?

Will the length of IV is constant ? in my case it is always 32 characters (hexadecimal) Or i need to even store length of IV as well ? as the salt length is fixed initially to 8 bits (16 hexadecimal characters)

(I am using PBKDF2WithHmacSHA1 algorithm for key generation and AES/CBC/PKCS5Padding for cipher)

Community
  • 1
  • 1
forum.test17
  • 2,119
  • 6
  • 30
  • 62

2 Answers2

5

I think it is worth emphasizing again what the accepted answer above mentioned in passing.

That is, it is unnecessary and unwarranted to make any attempt to hide the salt or the IV. The security of your cryptography is entirely dependent on the secrecy of the secret key, and that of the secret key alone. The IV and the salt can be handed out in clear text along with the ciphertext, and as long as the secret key remains a secret, the ciphertext remains secure.

It's important to understand and accept that, or you will wind yourself about an axle trying to obfuscate things that don't matter. There is no security in obscurity.

It is important to note, however, that the salt should be generated in a cryptographically strong pseudorandom number generator. A new salt should be generated for each new plain text that is being encrypted. Likewise, the IV should be randomly generated for each new ciphertext.

Those parameters need to be independent and unpredictable but need not be secret.

So you can store them in separate fields or delimit them in a single field, or use fixed lengths for the first two of three fields. For maximum flexibility and future proofing, though, I suggest delimited fields, and include all parameters needed to deal with the data. If you are using PBE, I would include the algorithm name and the iteration count, too, rather than rely on default values.

Frugal Guy
  • 71
  • 1
  • 5
  • i am a crypto-newbie, but if the attacker has the cipher-text, the iv, the salt, the iteration count and algo-name,....isn't that easy for an attacker to create the key by brute force? I am just asking, because I am about to save all those info in my small project. And I was asking myself how secure this approach really is. – Manfred Aug 20 '18 at 15:23
  • Yes, @Manfred, that's the point. Their **only** way to attack is brute force. OP doesn't mention his key length, but the choices for AES are 128, 192, and 256 bits. That is, there are a **minimum** of 2^128 possible keys to try. That's a very large _key space_, and gives us confidence that the attacker won't hit upon the right key before the information is no longer relevant. – Frugal Guy Jan 25 '19 at 16:36
  • If it's easier to visualize: `2^128 = 10^x ==> log2(10^x) = 128 ==> x * log2(10) = 128 ==> x = (128) / (log2(10)) ==> x =~ 38.53` so that's about 10^38 keys, or 100,000,000,000,000,000,000,000,000,000,000,000,000 keys. For 256-bit AES, that's 10^77 or 100,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,00,000,000 keys to try. Note there are between 10^78 and 10^82 atoms in the known, observable universe. **That's** why we call it secure. Easy in theory, very close to impossible in practice. – Frugal Guy Jan 25 '19 at 16:48
2

Base64 encodes in chunks of 3 bytes into 4 base64 chars. If the number of bytes that needs to be encoded ain't a multiplum of 3 the last block is padded with one or two =, to indicate that this block ain't full 3 bytes.

As neither the salt nor the IV needs to be kept secret, there really ain't any problem about being able to detect where they start or stop. The base64 padding char = ain't a problem - but you ought to have a way to separate the three encoded strings. You could e.g. simply seperate the parts with a :.

The size of the IV is the same as the block size of your encryption algorithm. In this case you use AES that have a block size of 128 bits, which is 16 bytes. This would give 32 bytes if hex encoded, or 24 bytes if base64 encoded. Salt don't really have a fixed length, and will depend on your implementation.

Ebbe M. Pedersen
  • 7,250
  • 3
  • 27
  • 47