How to download base64 which is encrypted? and Decrypt after that - javascript

I want to make image ecrypt and decrypt in client browser.
I have create upload image an encrypt base64. But, i don't know how to download this encrypted image (On format image not text).
after that i want to upload this encrypted image for decrypt.
Thanks for advance, i'm sorry for my bad english.
$(document).ready(function() {
$("#form-encrypt").on('submit', function(e){
e.preventDefault();
disabledButton('btn-submit-encrypt');
let filesSelected = document.getElementById("inputFileToLoad").files;
let fileExtension = filesSelected[0].name.split('.').pop()
const password = $('#password').val();
if (filesSelected.length > 0) {
let fileToLoad = filesSelected[0];
let fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent) {
let base64value = fileLoadedEvent.target.result;
let encrypt = CryptoJS.AES.encrypt(base64value, password).toString();
};
fileReader.readAsDataURL(fileToLoad);
}
});
$("#form-decrypt").on('submit', function(e){
e.preventDefault();
const ciphertext = document.querySelector('#encrypt-text').value;
const pass = document.querySelector('#password-decrypt').value;
try {
let bytes = CryptoJS.AES.decrypt(ciphertext, pass);
const originalText = bytes.toString(CryptoJS.enc.Utf8);
const preview = document.getElementById('preview');
preview.setAttribute('src', originalText);
$("#preview").show();
} catch (error) {
alert('Wrong Password, or Encrypt Text Not Right');
}
});
});
function downloadTxt(filename, data, mimeType) {
let element = document.createElement('a');
element.setAttribute('download', filename);
mimeType = mimeType || 'text/plain';
element.setAttribute('href', 'data:' + mimeType + ';charset=utf-8,' + [enter image description here][1]encodeURIComponent(data));
element.click();
}
function disabledButton(elm) {
const element = document.getElementById(elm);
element.setAttribute('disabled', true);
element.innerHTML = 'Loading..';
}

yeah, i already know.
I wrong because i encrypt all result in fileReader, you must split a base64 value.
example :
data:image/png;base64,iVBOblablabla
split with ( , ) and you get array
data[0] = data:image/png;base64
data[1] = iVBOblablabla
and you should just encrypt data[1]

Related

Programmatically download the QR image

I tried to create a QR code with QRcode.js library. As of the UI, I can manually click on the button download to download it but I would to download automatically without clicking the button.
Base on my code bellow.
function genQR(link_string){
let qr_code_element = document.querySelector(".qr-code");
if (link_string != "") {
if (qr_code_element.childElementCount == 0) {
generate(qr_code_element, link_string);
} else {
qr_code_element.innerHTML = "";
generate(qr_code_element, link_string);
}
} else {
alert("not valid QR input");
qr_code_element.style = "display: none";
}
}
function generate(qr_code_element, link_string) {
qr_code_element.style = "";
var qrcode = new QRCode(qr_code_element, {
text: link_string,
width: 200,
height: 200,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
let download = document.createElement("button");
// qr_code_element.appendChild(download);
let download_link = document.createElement("a");
download_link.setAttribute("download", "qr.png");
download_link.setAttribute("id", "downloadbtn");
download_link.innerText = "Download";
// download.appendChild(download_link);
let qr_code_img = document.querySelector(".qr-code img");
let qr_code_canvas = document.querySelector("canvas");
if (qr_code_img.getAttribute("src") == null) {
setTimeout(() => {
download_link.setAttribute("href", `${qr_code_canvas.toDataURL()}`);
}, 300);
} else {
setTimeout(() => {
download_link.setAttribute("href", `${qr_code_img.getAttribute("src")}`);
}, 300);
}
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
//I expect the below line will automatically download the QR but nothing fires.
download_link.dispatchEvent(clickEvent);
}
If I use button to click and download by hand will works fine for me but I want to reduce too many steps.
I think I almost done here but failed.
Could anyone show me how to automatic download?
Thank you in advance.
I've had this issue in the past, and I've worked around it by creating a small util function I can invoke upon button pressing. But invoking it directly at the end of your function should have the same result as a user click, effectively automatically downloading the QR code without user input.
export function download(blob, filename) {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = filename
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}
I'm guessing you could try passing generate as the first parameter if the object you're getting is a Blob. Otherwise, you'll probably need to convert it before.
I done my target by adding the source you shared at the bottom of my code and then added this function to convert dataURL to Blob
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var blob = new Blob([ab], {type: mimeString});
return blob;
}
Thank you very much #Gianmarco Rengucci
I rate for you

Encryption of files with CryptoJs and decryption in Python (AES CBC)

I'm trying to encrypt files (trying with png) in Javascript (ReactJs) and I want to be able to decrypt the files and restore their original state in Python.
I've tried multiple approaches but the below JS code was the only one I got working properly. With the JS code, I'm able to get back the png in its original form. However, I seem to be missing something with padding as I keep getting:
Traceback (most recent call last):
File "***/encrypt_decrypt_using_aes.py", line 110, in <module>
decrypted = decrypt(encData, key, iv)
File "***/encrypt_decrypt_using_aes.py", line 103, in decrypt
return unpad(cipher.decrypt(enc),16)
File "/usr/local/lib/python3.9/site-packages/Crypto/Util/Padding.py", line 90, in unpad
raise ValueError("Padding is incorrect.")
ValueError: Padding is incorrect.
I tried playing with ZeroPadding, NoPadding, PKCS7 but nothing worked.
Any ideas on what I am missing?
JS code:
function decrypt(input) {
var file = input;
var reader = new FileReader();
reader.onload = () => {
var key = "1234567887654321";
var decrypted = CryptoJS.AES.decrypt(reader.result, key, {mode: CryptoJS.mode.CBC}); // Decryption: I: Base64 encoded string (OpenSSL-format) -> O: WordArray
var typedArray = convertWordArrayToUint8Array(decrypted); // Convert: WordArray -> typed array
var fileDec = new Blob([typedArray]); // Create blob from typed array
var a = document.createElement("a");
var url = window.URL.createObjectURL(fileDec);
var filename = file.name.substr(0, file.name.length - 4);
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
};
reader.readAsText(file);
}
function encrypt(input) {
var file = input
console.log("In Encrypt")
console.log(file)
var reader = new FileReader();
var iv = CryptoJS.enc.Utf8.parse('53509bee-8207-11');
reader.onload = () => {
var key = "1234567887654321";
var wordArray = CryptoJS.lib.WordArray.create(reader.result); // Convert: ArrayBuffer -> WordArray
var encrypted = CryptoJS.AES.encrypt(wordArray, key, {iv: iv, mode: CryptoJS.mode.CBC}).toString(); // Encryption: I: WordArray -> O: -> Base64 encoded string (OpenSSL-format)
var fileEnc = new Blob([encrypted]); // Create blob from string
// var a = document.createElement("a");
// var url = window.URL.createObjectURL(fileEnc);
var filename = input.name + ".enc";
console.log(filename)
var file = new File([fileEnc], filename);
// a.href = url;
// a.download = filename;
// a.click();
// window.URL.revokeObjectURL(url);
setFiles2State(files2State => ({
fileList2: [...files2State.fileList2, file],
}));
console.log("OUT LIST")
console.log(files2State)
};
reader.readAsArrayBuffer(file);
}
Python code (Not working):
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
def encrypt(data,key,iv):
data= pad(data.encode(),16)
cipher = AES.new(key.encode('utf-8'),AES.MODE_CBC,iv)
return base64.b64encode(cipher.encrypt(data))
def decrypt(enc,key,iv=None):
enc = base64.b64decode(enc)
# enc = enc.encode('utf-8')
if iv == None:
cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC)
else:
cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc),16)
with open("demo_file.png.enc", "r+") as fileIn:
encData = fileIn.read()
key = "1234567887654321"
iv = "53509bee-8207-11".encode('utf-8')
decrypted = decrypt(encData, key, iv)
with open("demo_file.png", "wb") as fileOut:
fileOut.write(decrypted)

using web-dictaphone need to save audio to server

I have the web-dictaphone working: https://github.com/mdn/web-dictaphone/
My goal is to have it work just like it does by default, but I want to add a save button that will save the recorded file onto the wordpress server.
Anyone have any suggestions on how to do this? Here is the code that executes after recording,
I imagine I need to do something with the audioURL and use something like file_put_contents() in php. I'm not sure if I need to convert to base64 or anything? Any help is appreciated, thanks.
mediaRecorder.onstop = function(e) {
console.log("data available after MediaRecorder.stop() called.");
const clipName = prompt('Enter a name for your sound clip?','My unnamed clip');
const clipContainer = document.createElement('article');
const clipLabel = document.createElement('p');
const audio = document.createElement('audio');
const deleteButton = document.createElement('button');
clipContainer.classList.add('clip');
audio.setAttribute('controls', '');
deleteButton.textContent = 'Delete';
deleteButton.className = 'delete';
if(clipName === null) {
clipLabel.textContent = 'My unnamed clip';
} else {
clipLabel.textContent = clipName;
}
clipContainer.appendChild(audio);
clipContainer.appendChild(clipLabel);
clipContainer.appendChild(deleteButton);
soundClips.appendChild(clipContainer);
audio.controls = true;
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
chunks = [];
const audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;
console.log("recorder stopped");
deleteButton.onclick = function(e) {
let evtTgt = e.target;
evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
}
clipLabel.onclick = function() {
const existingName = clipLabel.textContent;
const newClipName = prompt('Enter a new name for your sound clip?');
if(newClipName === null) {
clipLabel.textContent = existingName;
} else {
clipLabel.textContent = newClipName;
}
}
}
It is not needed to convert to base64, just append blob to an instance of the FormData class and send.
var formData = new FormData();
formData.append('attachment', blob);
var request = new XMLHttpRequest();
request.open('POST', 'URL', true); // edit URL
request.onload = function() { console.log("Status: %s", request.responseText) };
request.send(formData);
On the backend side, receiving can be archived with $_FILES and move_uploaded_file() like a normal upload procedure.

How to convert base64 byte data into downloadable pdf file?

I have an encoded base64 data from an API response and stored in a variable encodedBase64.
let encodedBase64 = 'some base64 encoded long data';
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
console.log('binaryString ', binaryString);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
function saveByteArray(reportName, byte) {
var blob = new Blob([byte], {type: "application/pdf"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
};
var sampleArr = base64ToArrayBuffer(encodedBase64);
saveByteArray("Sample Report", sampleArr);
after executing this code i am able to download pdf file names SampleReport.pdf but when i open this it is showing Failed to load PDF document. error
what is the wrong in my code ?
difficult to get it done using front end side
but it can be done easily using Nodejs using the following code.
fs.writeFile('pdfFileName.pdf', base64DataString, {encoding: 'base64'}, error => {
if (error) {
throw error;
} else {
console.log('buffer saved!');
}
});

Upload image from URL to Firebase Storage

I'm wondering how to upload file onto Firebase's storage via URL instead of input (for example). I'm scrapping images from a website and retrieving their URLS. I want to pass those URLS through a foreach statement and upload them to Firebase's storage. Right now, I have the firebase upload-via-input working with this code:
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var file = evt.target.files[0];
var metadata = {
'contentType': file.type
};
// Push to child path.
var uploadTask = storageRef.child('images/' + file.name).put(file, metadata);
// Listen for errors and completion of the upload.
// [START oncomplete]
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var url = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', url);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';}
Question what do I replace
var file = evt.target.files[0];
with to make it work with external URL instead of a manual upload process?
var file = "http://i.imgur.com/eECefMJ.jpg"; doesn't work!
There's no need to use Firebase Storage if all you're doing is saving a url path. Firebase Storage is for physical files, while the Firebase Realtime Database could be used for structured data.
Example . once you get the image url from the external site this is all you will need :
var externalImageUrl = 'https://foo.com/images/image.png';
then you would store this in your json structured database:
databaseReference.child('whatever').set(externalImageUrl);
OR
If you want to actually download the physical images straight from external site to storage then this will require making an http request and receiving a blob response or probably may require a server side language ..
Javascript Solution : How to save a file from a url with javascript
PHP Solution : Saving image from PHP URL
This answer is similar to #HalesEnchanted's answer but with less code. In this case it's done with a Cloud Function but I assume the same can be done from the front end. Notice too how createWriteStream() has an options parameter similar to bucket.upload().
const fetch = require("node-fetch");
const bucket = admin.storage().bucket('my-bucket');
const file = bucket.file('path/to/image.jpg');
fetch('https://example.com/image.jpg').then((res: any) => {
const contentType = res.headers.get('content-type');
const writeStream = file.createWriteStream({
metadata: {
contentType,
metadata: {
myValue: 123
}
}
});
res.body.pipe(writeStream);
});
Javascript solution to this using fetch command.
var remoteimageurl = "https://example.com/images/photo.jpg"
var filename = "images/photo.jpg"
fetch(remoteimageurl).then(res => {
return res.blob();
}).then(blob => {
//uploading blob to firebase storage
firebase.storage().ref().child(filename).put(blob).then(function(snapshot) {
return snapshot.ref.getDownloadURL()
}).then(url => {
console.log("Firebase storage image uploaded : ", url);
})
}).catch(error => {
console.error(error);
});
Hopefully this helps somebody else :)
// Download a file form a url.
function saveFile(url) {
// Get file name from url.
var filename = url.substring(url.lastIndexOf("/") + 1).split("?")[0];
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", transferComplete);
xhr.addEventListener("error", transferFailed);
xhr.addEventListener("abort", transferCanceled);
xhr.responseType = 'blob';
xhr.onload = function() {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(xhr.response); // xhr.response is a blob
a.download = filename; // Set the file name.
a.style.display = 'none';
document.body.appendChild(a);
a.click();
delete a;
if (this.status === 200) {
// `blob` response
console.log(this.response);
var reader = new FileReader();
reader.onload = function(e) {
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
var metadata = {
'contentType': 'image/jpeg'
};
var file = e.target.result;
var base64result = reader.result.split(',')[1];
var blob = b64toBlob(base64result);
console.log(blob);
var uploadTask = storageRef.child('images/' + filename).put(blob, metadata);
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var download = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', download);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';
// [END_EXCLUDE]
});
// `data-uri`
};
reader.readAsDataURL(this.response);
};
};
xhr.open('GET', url);
xhr.send();
}
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function transferComplete(evt) {
window.onload = function() {
// Sign the user in anonymously since accessing Storage requires the user to be authorized.
auth.signInAnonymously().then(function(user) {
console.log('Anonymous Sign In Success', user);
document.getElementById('file').disabled = false;
}).catch(function(error) {
console.error('Anonymous Sign In Error', error);
});
}
}
function transferFailed(evt) {
console.log("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
console.log("The transfer has been canceled by the user.");
}

Categories

Resources