Closed andresmejia3 closed 1 year ago
Thanks for reporting!
Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.
Thanks for reporting!
Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.
I believe the code I posted above should reproduce it. The only thing I'm missing from it is the import statements. This is the code with the import statements added.
import { algo, PBKDF2, SHA256 } from 'crypto-js'
import WordArray from 'crypto-js/lib-typedarrays'
import Base64 from 'crypto-js/enc-base64'
import Utf8 from 'crypto-js/enc-utf8'
// @ts-ignore
import { PassThrough, Transform, pipeline, Stream } from 'readable-stream'
// @ts-ignore
import { createGzip, createGunzip } from 'browserify-zlib'
import * as Buffer from 'buffer'
import RNBlob, { RNFetchBlobReadStream } from 'rn-fetch-blob'
const decryptionTest = () => {
const password = 'password123'
const source = new PassThrough()
const destination = new PassThrough()
const { encryptor, salt, iv } = createEncryptor(password, 'base64')
const decryptStream = createDecryptor(password, salt, iv, 'base64')
destination.on('data', (chunk: Buffer) => console.log('Result:', chunk.toString()))
pipeline(source, encryptor, decryptStream, destination, (error: any) => {
if (error)
console.error('Pipeline Error:', error)
})
source.write('Hello World')
}
const createEncryptor = (password: string, encoding: 'utf8' | 'base64'): EncryptorParams => {
const hashedPassword = SHA256(password)
const salt = WordArray.random(64) // Create 64 byte salt
const iv = WordArray.random(16) // Create 16 byte iv
// Generate key of size 256 bits (keySize is the size the key should be in 32 bit Words)
const key = PBKDF2(hashedPassword, salt, { keySize: 512 / 32, iterations: 1000 })
const encryptor = algo.AES.createEncryptor(key, { iv })
const encoder = encoding === 'base64' ? Base64 : Utf8
const encryptorStream = new Transform({
transform(chunk: Buffer, enc, callback) {
const encodedChunk = chunk.toString(encoding)
const encryptedChunk = encryptor.process(encodedChunk).toString(encoder)
this.push(encryptedChunk)
callback()
}
})
return { encryptor: encryptorStream, salt, iv }
}
const createDecryptor = (password: string, salt: WordArray, iv: WordArray, encoding: 'utf8' | 'base64'): Transform => {
const hashedPassword = SHA256(password)
const key = PBKDF2(hashedPassword, salt, { keySize: 512 / 32, iterations: 1000 })
const decryptor = algo.AES.createDecryptor(key, { iv })
const encoder = encoding === 'base64' ? Base64 : Utf8
return new Transform({
transform(chunk: Buffer, enc, callback) {
const encodedChunk = chunk.toString(encoding)
const decryptedChunk = decryptor.process(encodedChunk).toString(encoder)
this.push(decryptedChunk)
callback()
}
})
}
Just to clarify: are you running this on React Native?
Just to clarify: are you running this on React Native?
Yes on React Native 0.70.1
Figured it out
I made 2 streams, an encryptor stream and a decryptor stream using CryptoJS's progressive ciphers. I'm using streams/pipeline from readable-stream as this is being run on React Native so it has to be Browserfied.
I keep getting the result in Base64. An example of the output I get is (of course it changes every time due to a random salt/iv): Result: zvkpfuiRtVPzkbL89aR/Xw==
I'm not sure where I'm going wrong here. I'd appreciate any help, thank you so much.
I've been tinkering with it for awhile so I tried different orders of encodings, using WordArray.create() instead of const encodedChunk = chunk.toString(encoding), but most things I did either led to a UTF8 malform error or the result of the decryption being an empty string after calling toString().