is it possible to Python decode base64 string to Solana Transaction Object? - javascript

This is how it is done in JS:
const obj = Transaction.from(Buffer.from(base64string, 'base64'));
this is how I think it could be done in Python:
import base64
base64string = "<some jibberish>"
decode = base64.b64decode(code)
it produces a byte type thus far. I'm not sure if I'm on the right track here... I've tried using picke.loads to no avail.

Related

Convert encryption function from Javascript to Python

I'm trying to convert this code from Javascript to Python3:
import crypto from 'crypto';
const secretKey = 'NgTriSCalcUltAbLoGResOnOuSeAKeSTraLryOuR'
function verifySignature(rawBody) {
const calculatedSignature = crypto
.createHmac('sha256', secretKey)
.update(rawBody, 'utf8')
.digest('base64');
return calculatedSignature;
}
console.log(verifySignature('a'));
With that code I get this output: vC8XBte0duRLElGZ4jCsplsbXnVTwBW4BJsUV1qgZbo=
So I'm trying to convert the same function to Python using this code:
UPDATED
import hmac
import hashlib
message = "a"
key= "NgTriSCalcUltAbLoGResOnOuSeAKeSTraLryOuR"
hmac1 = hmac.new(key=key.encode(), msg=message.encode(), digestmod=hashlib.sha256)
message_digest1 = hmac1.hexdigest()
print(message_digest1)
But I get this error: AttributeError: 'hash' object has no attribute 'digest_size'
Can someone tell me what I am missing to achieve the same output in Python?
Thanks you! :)
You're not getting base64 from the digest() on your return statement. In your javascript code it was also encoded in UTF-8 which should be specified below. The key was also not supplied in your python code.
This code snippet I just tested should generate the same result as your javascript code:
def newhashab(msg, key):
digest = hmac.new(key.encode('UTF-8'), msg.encode('UTF-8'), hashlib.sha256)
return base64.b64encode(digest.digest()).decode('UTF-8')
print(newhashab("a", 'NgTriSCalcUltAbLoGResOnOuSeAKeSTraLryOuR'))
It should return:
'vC8XBte0duRLElGZ4jCsplsbXnVTwBW4BJsUV1qgZbo='

How do I store and fetch bytea data through hasura?

I've got a blob of audio data confirmed to play in the browser but fails to play after storing, retrieving, and conversion of the same data. I've tried a few methods without success, each time returning the error:
Uncaught (in promise) DOMException: Failed to load because no supported source was found
Hasura notes that bytea data must be passed in as a String, so I tried a couple things.
Converting the blob into base64 stores fine but the retrieval and playing of the data doesn't work. I've tried doing conversions within the browser to base64 and then back into blob. I think it's just the data doesn't store properly as bytea if I convert it to base64 first:
// Storing bytea data as base64 string
const arrayBuffer = await blob.arrayBuffer();
const byteArray = new Uint8Array(arrayBuffer);
const charArray = Array.from(byteArray, (x: number) => String.fromCharCode(x));
const encodedString = window.btoa(charArray.join(''));
hasuraRequest....
`
mutation SaveAudioBlob ($input: String) {
insert_testerooey_one(
object: {
blubberz: $input
}
) {
id
blubberz
}
}
`,
{ input: encodedString }
);
// Decoding bytea data
const decodedString = window.atob(encodedString);
const decodedByteArray = new Uint8Array(decodedString.length).map((_, i) =>
decodedString.charCodeAt(i)
);
const decodedBlob = new Blob([decodedByteArray.buffer], { type: 'audio/mpeg' });
const audio4 = new Audio();
audio4.src = URL.createObjectURL(decodedBlob);
audio4.play();
Then I came across a Github issue (https://github.com/hasura/graphql-engine/issues/3336) suggesting the use of a computed field to convert the bytea data to base64, so I tried using that instead of my decoding attempt, only to be met with the same error:
CREATE OR REPLACE FUNCTION public.content_base64(mm testerooey)
RETURNS text
LANGUAGE sql
STABLE
AS $function$
SELECT encode(mm.blobberz, 'base64')
$function$
It seemed like a base64 string was not the way to store bytea data, so I tried converting the data to a hex string prior to storing. It stores ok, I think, but upon retrieval the data doesn't play, and I think it's a similar problem as storing as base64:
// Encoding to hex string
const arrayBuffer = await blob.arrayBuffer();
const byteArray = new Uint8Array(arrayBuffer);
const hexString = Array.from(byteArray, (byte) =>
byte.toString(16).padStart(2, '0')
).join('');
But using the decoded data didn't work again, regardless of whether I tried the computed field method or my own conversion methods. So, am I just not converting it right? Is my line of thinking incorrect? Or what is it I'm doing wrong?
I've got it working if I just convert to base64 and store as a text field but I'd prefer to store as bytea because it takes up less space. I think something's wrong with how the data is either stored, retrieved, or converted, but I don't know how to do it. I know the blob itself is fine because when generated I can play audio with it, it only bugs out after fetching and attempted conversion its stored value. Any ideas?
Also, I'd really like to not store the file in another service like s3, even if drastically simpler.

Javascript: how to parse base64 encoded csv to fetch the filename and actual csv content

I have a base64 string created by encoding a csv file,
const base64 = 'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTExNDc2MDgwNjM5MTM4ODk4MTc2NTYwNA0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmaWxlIjsgZmlsZW5hbWU9ImNoYXJ0T2ZBY2NvdW50LmNzdiINCkNvbnRlbnQtVHlwZTogdGV4dC9jc3YNCg0K77u/QWNjb3VudE51bWJlcixBY2NvdW50TmFtZSxEZWR1Y3RhYmlsaXR5DQoxMTExLHRlZWUsMTAwDQoyMjIyMix0ZXN0LDEwMA0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTExNDc2MDgwNjM5MTM4ODk4MTc2NTYwNC0tDQo='
I want to get the name of the file and create the same file back with the filename. What I need to use. I am using node.js here.
If I understand your question right, your base64 variable needs to be decoded. buffer can do this:
const base64 = 'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTExNDc2MDgwNjM5MTM4ODk4MTc2NTYwNA0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmaWxlIjsgZmlsZW5hbWU9ImNoYXJ0T2ZBY2NvdW50LmNzdiINCkNvbnRlbnQtVHlwZTogdGV4dC9jc3YNCg0K77u/QWNjb3VudE51bWJlcixBY2NvdW50TmFtZSxEZWR1Y3RhYmlsaXR5DQoxMTExLHRlZWUsMTAwDQoyMjIyMix0ZXN0LDEwMA0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTExNDc2MDgwNjM5MTM4ODk4MTc2NTYwNC0tDQo=';
// decode base64
const decodedBase64String = Buffer.from(base64, 'base64').toString();
const filename = decodedBase64String.match(/filename="(.*).csv/)[1];
console.log(decodedBase64String);
With a some regex you can extract your filename ("chartOfAccount.csv") from decodedBase64String. And then use fs (explained here) to create from your content a file.

Nodejs decode base64 and save them into a file using streams

Over my node.js application I decode base64 encoded images using the following line of code:
const fileDataDecoded = Buffer.from(base64EncodedfileData,'base64');
So far I can write a file with the following piece of code:
const fs = require('fs');
....
const fileDataDecoded = Buffer.from(base64EncodedfileData,'base64');
fs.writeFile("/tmp/test.png", fileDataDecoded, function(err) {
//Handle Error
});
Now what I want to achieve is the decoded files via the buffer to get written into a file via streams in order to acheive better efficiency on the executed application.
In other words I want the filedata to get written at the same time that the data is getting base64-decoded, in order to write large files with an efficient way. If is not possible via a Buffer to stream base64 decoded data then I would like to know how is possible to decode base64 data.
You can create a readable stream and push the image buffer. Then pipe it to a writeable stream like this.
var base64 = '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';
var fs = require('fs')
var Readable = require('stream').Readable
const imgBuffer = Buffer.from(base64, 'base64')
var s = new Readable()
s.push(imgBuffer)
s.push(null)
s.pipe(fs.createWriteStream("test.png"));
Just another solution with base-64 & utf8 in case we're using react-native which doesn't have Buffer global object:
function (base64Str) {
return utf8.decode(base64.decode(base64Str))
}

How to decrypt an ArrayBuffer?

I've been trying to decrypt an ArrayBuffer object using CryptoJS, but so far it always returns a blank WordArray. The files (images) are encrypted in an iOS and Android app, sent to a server, and downloaded in this web app to be decrypted and displayed. The iOS and Android apps are able to decrypt the files without problems, so there's nothing wrong with the encryption process.
The files are downloaded with an XMLHttpRequest with responseType set to arraybuffer. Here's my code so far:
// Decrypt a Base64 encrypted string (this works perfectly)
String.prototype.aesDecrypt = function(key) {
var nkey = CryptoJS.enc.Hex.parse(key.sha256());
return CryptoJS.AES.decrypt(this.toString(), nkey, {
iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);
}
// Decrypt a plain encrypted ArrayBuffer (this is the problem, it always outputs an empty WordArray)
ArrayBuffer.prototype.aesDecrypt = function(key) {
// Get key
if (!key) return null;
var nkey = CryptoJS.enc.Hex.parse(key.sha256());
// Get input (if I pass the ArrayBuffer directly to the create function, it returns
// a WordList with sigBytes set to NaN)
//var input = CryptoJS.lib.WordArray.create(this);
var input = CryptoJS.lib.WordArray.create(new Uint8Array(this));
// Decrypt
var output = CryptoJS.AES.decrypt(input, nkey, {
iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// Output is an empty WordList
console.log("Output: ", output);
}
Another question I have is how do you convert a WordArray to an ArrayBuffer?
The conversion of ArrayBuffer -> WordArray has been discussed in CryptoJS's issue 46. For that reason a TypedWordArraywhere you can also pass an ArrayBuffer has been added.
To use that additionally include the following script:
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/lib-typedarrays.js"></script>
Then you can simply do:
var wordArray = CryptoJS.lib.WordArray.create(arrayBuffer);
/* perform decryption of `wordArray` */
To reconvert the resulting decryptedWordArray to an ArrayBuffer, the simplest approach would probably be, to first convert it to a Base64-String (as discussed here) and then decode that String to the desired ArrayBuffer (see here). The whole procedure would look something like this:
dcWordArray = ... // your decrypted WordArray
dcBase64String = dcWordArray.toString(CryptoJS.enc.Base64); // to Base64-String
dcArrayBuffer = base64DecToArr(dcBase64String).buffer; // to ArrayBuffer
Edit:
For a more efficient conversion (no intermediate Base64String necessary) check out Aletheios answer to that question (the function wordToByteArray(wordArray) and then do .buffer).
you can use the web crypto API to directly decrypt arrayBuffer.
No need to convert binary data to a string, which is so inefficient, and it could cause memory and CPU rises.

Categories