I am starting to learn NodeJS and started to make a small application that encrypts and decrypts a file upon user click request. The below code works fine on first encryption request but crashes on another.
App.js
var fs = require('fs')
var crypto = require('crypto')
const express = require('express')
const app = express()
const port = 3000
var key = '1bd';
var cipher = crypto.createCipher('aes-256-cbc', key);
var decipher = crypto.createDecipher('aes-256-cbc', key);
app.use(express.static('public'))
app.get('/', (req, res) => {
res.sendFile('/enc-dec.html', { root: __dirname })
})
app.post('/encrypt', (req, res) => {
fs.createReadStream('input.txt')
.pipe(cipher)
.pipe(fs.createWriteStream('input.txt.enc'))
.on('finish', function() {
res.end("Encrypted")
});
})
app.listen(port, () => console.log(`App listening on port ${port}!`))
Error:
NodeError: write after end
at writeAfterEnd (_stream_writable.js:237:12)
at Cipher.Writable.write (_stream_writable.js:287:5)
at ReadStream.ondata (_stream_readable.js:646:20)
at ReadStream.emit (events.js:180:13)
at addChunk (_stream_readable.js:269:12)
at readableAddChunk (_stream_readable.js:256:11)
at ReadStream.Readable.push (_stream_readable.js:213:10)
at fs.read (fs.js:2123:12)
at FSReqWrap.wrapper [as oncomplete] (fs.js:680:17)
Emitted 'error' event at:
at Cipher.onerror (_stream_readable.js:670:12)
at Cipher.emit (events.js:180:13)
at writeAfterEnd (_stream_writable.js:239:10)
at Cipher.Writable.write (_stream_writable.js:287:5)
[... lines matching original stack trace ...]
at fs.read (fs.js:2123:12)
I am not expert in that but it seems issue with fs. Any help would be greatly appreciated. Thanks!
Your problem is that you're reusing the same cipher multiple times. After it's used in a stream once, it cannot be reused; a new one must be created.
You should create your cipher in the request handler, like this:
app.post('/encrypt', (req, res) => {
var cipher = crypto.createCipher('aes-256-cbc', key);
fs.createReadStream('input.txt')
.pipe(cipher)
.pipe(fs.createWriteStream('input.txt.enc'))
.on('finish', function() {
res.end("Encrypted")
});
})
It doesn't look like you have the decrypt functionality done yet, but when you build that, you'll also need to move var decipher = crypto.createDecipher('aes-256-cbc', key); down into the request handler, because deciphers can't be reused either.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With