Encrypting large file with PGP (BouncyGPG) and sending it over SFTP (JSch) in Kotlin

Viewed 448

I've been trying to encrypt large files with PGP (I'm using BouncyGPG for that) and sending it to a remote server using SFTP (using JSch). I'm using PipedOutputStream and PipedInputStream to avoid saving the final encrypted file locally before sending to the server. I believe BouncyGPG is misbehaving because of that.

Can anyone help me with this?

Here's my code:

    BouncyGPG.registerProvider()

    private val bufferSize: Int = 8 * 1024

    fun sendFileSFTP(myFile: MyFile {
        PipedInputStream().use { input ->
            GlobalScope.launch {
                PipedOutputStream(input).use { output ->
                    encrypt(myFile, output)
                }
            }
            sendSFTP(input, "mysftp-directory/${myFile.filename}")
            log.info("Finished Sending $myFile")
        }
    }

    fun encrypt(myFile: MyFile output: OutputStream) {
        log.info("ENCRYPTING - $myFile")
        val pubkey = "/home/myhome/server.gpg"
        val privkey = "/home/myhome/server.secret.gpg"
        val password = "password"
        val keyring = KeyringConfigs.forGpgExportedKeys(KeyringConfigCallbacks.withPassword(password))
        keyring.addPublicKey(FileReader(File(pubkey)).readText().toByteArray(charset("US-ASCII")))
        keyring.addSecretKey(FileReader(File(privkey)).readText().toByteArray(charset("US-ASCII")))


        BouncyGPG.encryptToStream()
            .withConfig(keyring)
            .withStrongAlgorithms()
            .toRecipients("contact@myserver.com")
            .andDoNotSign()
            .binaryOutput()
            .andWriteTo(output)

        val filepath = Paths.get(myFile.path, myFile.filename)
        BufferedInputStream(FileInputStream(filepath.toString())).use { input ->
            input.copyTo(output, bufferSize)
        }

        log.info("FINISHED ENCRYPTING - $myFile")
    }

    fun sendSFTP(inputStream: InputStream, dest: String) {
        log.info("Sending $dest")
        var jsch = JSch()
        jsch.setKnownHosts(properties.knownHosts)

        val jschSession: Session = jsch.getSession(properties.sFTPUsername, properties.sFTPHost, properties.sFTPPort)
        jschSession.setPassword(properties.sFTPPassword)
        jschSession.connect()
        val channel = jschSession.openChannel("sftp") as ChannelSftp
        channel.connect()

        channel.put(inputStream, dest)
    }

I'm assuming that BouncyGPG is not singing my file due to the lack of closing (I believe I've read somewhere that it only signs the file after the output is closed, but as far as I know, kotlin will close the output for me already. Am I missing something?

Thanks

1 Answers

After debating with this issue for a while, I gave a try and generated my own pgp keys (I was using a test key our client gave us) and guess what? It worked!

Apparently there was something wrong with them! ¯_(ツ)_/¯

So, my code is working!

Related