How to get Binary data with javascript using FileReader api with correct encoding - filereader

I got a mp4 data using FileReader api, but I have a problem at encoding!
With this function,
var reader = new FileReader();
var blob = new Blob([this.response], {type : "video/mp4"});
reader.onload= function (evt) {
mp4text = evt.target.result;
mp4text = mp4text.toString()
//mp4text = mp4text.slice(22);
//mp4text = CryptoJS.AES.encrypt(mp4text, "test");
//mp4text = window.atob(mp4text);
var myBlob = new Blob([evt.target.result], {type : "video/mp4"});//NOT SAME contrast to blob!
var downloadUrl = URL.createObjectURL(myBlob);
document.getElementById('myVideo').src = downloadUrl;
}
reader.readAsBinaryString(blob);
I thought myBlob has same filedata as blob but some data changed! With more detail, Many of character are same but some hex code is different. How can I solve this problem?

Strings in JavaScript cannot represent arbitrary binary data, so doing readAsBinaryString may not be what you think.
What readAsBinaryString does is for each source byte it gives you a destination character(I don't which character encoding it uses off the top of my head).
So if you have a utf-8 character say ✔, then readAsBinaryString will give you â since that character is tree bytes long %E2%9C%94.
If you try to turn this back to binary/blob the string â is treated as utf-8 which is not 3 bytes but 7(%C3%A2%C5%93%E2%80%9D)
My suggestion would be to use readAsArrayBuffer, I'm sure CryptoJS supports arraybuffers.

Related

I am trying to decode and extract octet string from the extension of X509Certificate, but I did not get any valid string

I have been trying to decode the octet string as per steps mentioned in
https://developer.apple.com/documentation/devicecheck/validating_apps_that_connect_to_your_server?language=objc
Here is what I have tried:
X509Certificate cert1 = getParentCertificate(new String(decodedCredCert));
System.out.println(cert1);
cert1.checkValidity(); // verify against apple app attest root ca
byte[] ext = cert1.getExtensionValue("1.2.840.113635.100.8.2");
ASN1InputStream bIn = new ASN1InputStream(ext);
ASN1Primitive obj = bIn.readObject();
ASN1OctetString string = (ASN1OctetString) obj;
byte[] octs = string.getOctets();
ASN1InputStream dIn = new ASN1InputStream(octs);
String octetString = ASN1Dump.dumpAsString(dIn.readObject());
I got the output as: "[[1]#8333585e692916d8cbcdce3c6aa2bd71617d54fed758957cfd6b50a2093fd506]"
For Ios AppAttestation, follow as below to get the extension value and it's corresponding octet string. As mentioned in that page,
Obtain the value of the credCert extension with OID
1.2.840.113635.100.8.2, which is a DER-encoded ASN.1 sequence. Decode the sequence and extract the single octet string that it contains.
Here is the sample code:
byte[] oidValue = credCert.getExtensionValue(ooid);
DEROctetString envelope = (DEROctetString) new ASN1InputStream(oidValue).readObject();
DLSequence sequence = (DLSequence) new ASN1InputStream(envelope.getOctetStream()).readObject();
DLTaggedObject taggedObject = (DLTaggedObject) sequence.getObjectAt(0);
DEROctetString taggedObjectOctet = (DEROctetString) taggedObject.getObject();
log.debug("Octet String : {}", taggedObjectOctet.getOctets());
"Octet string" is just a spec phrase that modern languages call "byte array". You've extracted the value as of octs, and should compare that value to whatever nonce you're supposed to compare it against.

Executable binary file not working after XOR encryption and decyption

I want to encrypt an exe file (file.exe), write the encrypted version to a text file (fileenc.txt) and decrypt the data in the text file back to another exe file (filedec.exe).
file.exe and filedec.exe are the same and are expected to function the same way.
However, when I try to do this the filedec.exe does not work. Error Popup says: "This app cannot run on your PC".
Please what could be the problem?
However, when I just read the file.exe, write to fileenc.txt without encryption or decryption, and then read fileenc.txt and write data to filedec.exe without encryption or decryption, filedec.exe seems to work fine.
Also, when I try encrypting and decrypting a text file with this code, it works fine too.
But when I encrypt and decrypt an exe on the fly, filedec.exe doesn't work.
Please help me out. Thank you everyone.
Here is my full code:
Main();
function Main() {
var arrKey;
arrKey = "encryptionkey";
//Encrypt file.exe and write the encrypted form to file.txt
Crypt( "C:\\...\\file.exe", "C:\\...\\fileenc.txt", arrKey );
//Decrypt the previously encrypted file.txt and write the decrypted form to filedec.exe
Crypt( "C:\\...\\fileenc.txt", "C:\\...\\filedec.exe", arrKey );
//NOTE: file.exe and filedec.exe are expected to work fine when executed
}
function Crypt(fileIn, fileOut, key) {
var fileInRead;
//Read fileIn
var adTypeBinaryRead = 1;
var BinaryStreamRead;
BinaryStreamRead = new ActiveXObject("ADODB.Stream");
BinaryStreamRead.Type = adTypeBinaryRead;
BinaryStreamRead.Open();
BinaryStreamRead.LoadFromFile(fileIn);
fileInRead = BinaryStreamRead.Read();
//Convert fileIn binary data to string
var objRS = new ActiveXObject("ADODB.Recordset");
var DefinedSize = 1024;
var adSaveCreateOverWrite = 2;
var adFldLong = 0x80;
var adVarChar = 201;
var adTypeText = 2;
objRS.Fields.Append("filedata", adVarChar, DefinedSize, adFldLong);
objRS.Open();
objRS.AddNew();
objRS.Fields("filedata").AppendChunk(fileInRead);
var binString = objRS("filedata").value;
objRS.close();
//Make key as long as string version of fileIn
while (key.length < binString.length) {
key += key;
}
key = key;
//crypt converted string with key
var k, ss, q;
var cryptresult = "";
i = 0;
for (var index = 0; index < binString.length; index++) {
k = key.substr(i, 1);
q = binString.substr(i, 1);
ss = q.charCodeAt(0);
cryptresult = cryptresult + String.fromCharCode(q.charCodeAt(0) ^ k.charCodeAt(0));
i = i +1;
}
// write crypted string to file
var outStreamW = new ActiveXObject("ADODB.Stream");
outStreamW.Type = adTypeText;
// Charset: the default value seems to be `UTF-16` (BOM `0xFFFE` for text files)
outStreamW.Open();
outStreamW.WriteText(cryptresult);
outStreamW.Position = 0;
var outStreamA = new ActiveXObject("ADODB.Stream");
outStreamA.Type = adTypeText;
outStreamA.Charset = "windows-1252"; // important, see `cdoCharset Module Constants`
outStreamA.Open();
outStreamW.CopyTo(outStreamA); // convert encoding
outStreamA.SaveToFile(fileOut, adSaveCreateOverWrite);
outStreamW.Close();
outStreamA.Close();
}
EDIT:
More troubleshooting into my code shows that when I encrypt and decrypt file.exe ON THE FLY, and then write the decrypted data to fileenc.exe, fileenc.exe works well.
But when I encrypt file.exe and write the encrypted data to fileenc.txt and then read the fileenc.txt, decrypt the read encrypted data and write to fileenc.exe (just like in my code), fileenc.exe gets corrupted. My understanding suggests that the manner through which I write the encrypted data to fileenc.txt could be the problem here.
Please I need help, how do I go about with this.

Using as3Crypto to encrypt/decrypt without ampersands

I was using as3Crypto with no probs
http://www.zedia.net/2009/as3crypto-and-php-what-a-fun-ride/
but then I saw some special characters and I realised I could encounter ampersands.
Which is a pain because they will be inserted into a query string.
Is there a way to ensure the as3Crypto encryption does not produce ampersands?
public function encrypt(txt:String = ''):String
{
var data:ByteArray = Hex.toArray(Hex.fromString(txt));
var pad:IPad = new PKCS5;
var mode:ICipher = Crypto.getCipher(type, key, pad);
pad.setBlockSize(mode.getBlockSize());
mode.encrypt(data);
return ''+Base64.encodeByteArray(data);
}
Assuming a standard base64 implementation, Base64.encodeByteArray(data); will not produce ampersands.

FLEX XMLDecoder turns `09.00` to "09.00", but `10.00` to 10

Could someone explain why the FLEX 4.5 XMLDecoder does this to my XML-data?
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>08.00</xmltag> );
// object = "08.00"
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
// Object = "11" (HEY! Where did my '.00' part of the string go?)
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.30</xmltag> );
// Object = "11.3" (HEY! Where did my '0' part of the string go?)
The Flex deserializer also gave me issues with this. It may be interpreting them as Number objects and thus they will return short representations when toString() is called.
Try using .toFixed(2) whenever you need to print a value such as 11.00
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
trace($object); //11
trace($object.toFixed(2)); //11.00
So, to the answer the original question of why this is happening:
In the source code for SimpleXMLDecoder (which I'm guessing has similar functionality to XMLDecoder), there's a comment in the function simpleType():
//return the value as a string, a boolean or a number.
//numbers that start with 0 are left as strings
//bForceObject removed since we'll take care of converting to a String or Number object later
numbers that start with 0 are left as strings - I guess they thought of phone numbers but not decimals.
Also, because of some hacky implicit casting, you actually have three different types -
"0.800" : String
11 : int
11.3: Number

What is proper encoding for converting a string to a byte array

I am having some sort of problem with encoding in my ASP.NET HTTPHandler, which uploads a file. The file content is passed in a hidden form variable from a ColdFusion web page which is using something called "ToBase64".
In ColdFusion, the code used to place the file content into a form is as follows:
<cffile action="readBinary" file="#FileName#" variable="objBinaryData">
<cfset b64file = #toBase64(objBinaryData)#>
<form name="sendToHandler"
action="http://myserver/mysite/UploadHandler.ashx" method="post">
<cfoutput>
<input type="hidden" name="objBinaryData" value="#b64file#" />
When my UploadHandler.ashx is posted, I am getting a string out of the form as follows:
string fileContent = context.Request.Form["objBinaryData"];
Next, I am converting the string to a byte array as follows:
byte[] binData = StringToByteArray(fileContent, EncodingType.ASCII);
Here is the function I'm using to convert the string:
public static byte[] StringToByteArray(string str, EncodingType encodingType)
{
System.Text.Encoding encoding = null;
switch (encodingType)
{
case EncodingType.ASCII:
encoding = new System.Text.ASCIIEncoding();
break;
case EncodingType.Unicode:
encoding = new System.Text.UnicodeEncoding();
break;
case EncodingType.UTF7:
encoding = new System.Text.UTF7Encoding();
break;
case EncodingType.UTF8:
encoding = new System.Text.UTF8Encoding();
break;
}
return encoding.GetBytes(str);
}
public enum EncodingType
{
ASCII,
Unicode,
UTF7,
UTF8
}
It's obvious to me that calling the above function with EncodingType.ASCII is wrong but I am very confused about what would be correct? What is the proper "match" between "Base64" sent from ColdFusion and the way the string should be encoded in .Net?
Please note that all the code "works" but the subsequent retrieval of a file shows it to be scrambled and I'm pretty sure I have the wrong encoding here.
EDIT-update:
I added the enum code previously omitted. I've tried all of these Encoding Types; they all result in "garbage". That is: I have tried each of these variations:
byte[] binData = StringToByteArray(fileContent, EncodingType.ASCII);
byte[] binData = StringToByteArray(fileContent, EncodingType.Unicode);
byte[] binData = StringToByteArray(fileContent, EncodingType.UTF7);
byte[] binData = StringToByteArray(fileContent, EncodingType.UTF8);
None of these work properly. As I read your suggested function, it should be Unicode. Note that I want to return a byte array not a converted string. Still very confused.
ANSWER:
I simply eliminated the enum and the function I wrote called StringToByteArray. Instead I coded the following:
byte[] binData = Convert.FromBase64String(fileContent);
Look at the Convert.FromBase64String() function
Base64 is an encoding scheme that enables you to represent binary data as a series of ASCII characters so that it can be included in text files and e-mail messages in which raw binary data is unacceptable. The below examples show encoding and decoding of unicode strings. Let me know if this is what you wanted,if not I can refind this further for you.
//Encoding
public static string StringToBase64 (string src) {
// Get's byte representation unicode string
byte[] b = Encoding.Unicode.GetBytes(src);
// Returns Base64-encoded string
return Convert.ToBase64String(b);
}
//Decoding
public static string Base64ToString (string src) {
// Decodes Base64-encoded string to a byte array
byte[] b = Convert.FromBase64String(src);
// Returns decoded Unicode string
return Encoding.Unicode.GetString(b);
}

Resources