Search code examples
kotlinbouncycastle

manipluate bytearray, while still preserving some bytes


I need to do some encryption of a kotlin bytearray, while still preserving the first 138 bytes.

Hi, I have used bouncycastle to create a encryption function that is able to encrypt a bytearray and return a ciphertext. I now have a really long cipher, where I need to preserve the first 138 bytes, and encrypt the rest. My encryption, and key generation functions look like this:

fun genKey() : SecretKey{
    val keyBytes : ByteArray = ByteArray(keylength)
    random.nextBytes(keyBytes)
    val keyspec : SecretKeySpec = SecretKeySpec(keyBytes, "AES")
    return keyspec
}
fun enc(plaintext : String, key : SecretKey) : ByteArray{
    val cipher : Cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BCFIPS")
    val IVstr : String = "0123456789abcdef";
    val IV = IVstr.toByteArray()
    cipher.init(Cipher.ENCRYPT_MODE, key)
    return cipher.doFinal(plaintext.toByteArray())
}

And I have this drivercode

Security.addProvider(BouncyCastleFipsProvider())
val file = File("C:\\files\IMagefile.bmp").readBytes()
val cryptFile = encb(file, key)

this simply gives me the bytearray "cryptfile". Now, as mentioned I would like the first 138 to not be encrypted. What is the easiest/best way to do this? Would I have to split up the "file" plaintext up into pieces and glue them together? Or could I do it in a smarter way?


Solution

  • Straight-forward split/glue is rather consice, why not go with it?

    //element at index goes to second array
    fun ByteArray.splitAtIndex(index : Int) = copyOf(index) to copyOfRange(index, size)
    
    val (prefix, text) = plaintext.toByteArray().splitAtIndex(138)
    val cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BCFIPS").also { it.init(Cipher.ENCRYPT_MODE, key) }
    val result: ByteArray = prefix + cipher.doFinal(text)