I'm trying to implement secure encryption of the files to be sent over insecure channel or stored in an insecure place. I use bouncy castle framework, my code is written in scala. I decided to use aes-256 (to be more specific - Rinjael with 256 bit block size, here is why). And it seems like I can use Rinjael with any (128|160|192|256) block length.
I cannot understand the whole process overview correctly. Here is one of good answers, in this question there is some useful code specific to bouncy castle. But both leaving some questions unanswered for me (questions below).
So this is how I understand the workflow:
For creating a block cipher instance I have to get an instance of padded block cipher with some output feedback:
// create an instance of the engine
val engine = new RijndaelEngine(bitLength)
// wrap engine with some feedback-blocking cipher mode engine
val ofb = new OFBBlockCipher(engine , bitLength)
// wrap this with some padded-blocking cipher mode
val cipher = new PaddedBufferedBlockCipher(ofb, new PKCS7Padding())
Now I have to run init()
on the cipher engine
2.1. first generate a key, to do this the best solution suggested here was to use Scrypt
to derive a secret from password instead of using PBKDF2-HMAC-xxx
. In russian wikipedia article on Scrypt it is said that the recommended parameters for Scrypt are as follows: N = 16384, r = 8, p = 1
So I'we wrirtten this code to generate the password:
SCrypt.generate(password.getBytes(encoding), salt, 16384, 8, 1, bitLength / 8)
2.2. This leads to that I need a salt. Salt should be an array of random bytes. Most answers here use 8 bytes. So I do
// helper method to get a bunch of random bytes
def getRandomBytes(size: Int) = {
val bytes = Array.ofDim[Byte](size)
val rnd = new SecureRandom()
rnd.nextBytes(bytes)
bytes
}
// generate salt
val salt = getRandomBytes(8)
2.3. For cipher to initialize we need an initialization vector (please take a look at my question (2) below).
val iv = getRandomBytes(bitLength / 8)
2.4. Now we are ready to initialize the cipher.
cipher.init(mode, params(password, salt, iv, bitLength))
8
bytes, not more?cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
or to be just random as i did?Thanks in advance!