computeHash byte[] and Stream difference - stream

I've been having some trouble with computeHash. I'm using both computeHash(Stream) and computeHash(byte[]). For some reason, they are giving back different result. I've tried writing the byte[] into a MemStream but result was the same when using Byte[]
FileStream zz = new FileStream(t.Filename, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(zz, Encoding.ASCII);
byte[] data = Encoding.ASCII.GetBytes(sr.ReadToEnd());
MemoryStream memStream = new MemoryStream(data);
byte[] test = md5hash.ComputeHash(memStream);
I've closed the file to make sure that the seek position is at the starting point.
zz = new FileStream(t.Filename, FileMode.Open, FileAccess.Read);
zz.Position = 0;
byte[] test1 = md5hash.ComputeHash(zz);
Any suggestions? My only guess is that it's an either an Encoding problem or the Stream has a different size.
Any help would be really appreciated.
Best Regards,
SunSatION

Some file encodings have hidden characters to alert a consumer application of the file format. One combination is:

I have a file formatted as UTF8, and ran the following:
byte[] asciidata, streamdata;
using (var zz = new FileStream("utf8.txt", FileMode.Open, FileAccess.Read))
{
var sr = new StreamReader(zz, Encoding.ASCII);
asciidata = Encoding.ASCII.GetBytes(sr.ReadToEnd());
}
using (var zz = new FileStream("utf8.txt", FileMode.Open, FileAccess.Read))
{
streamdata = new byte[asciidata.Length + 3];
zz.Read(streamdata, 0, streamdata.Length);
}
The variable asciidata contained the four characters in my text file, but streamdata contained the four characters prefixed by the three magic characters described above (for a total of seven characters).
In conclusion, I believe your suspicion that encoding is to blame is correct.

Related

How to do encryption like android's "PBEWithMD5AndDES" in flutter dart?

I'm trying to recreate an existing mobile apps into flutter but struggling in the "PBEWithMD5AndDES" encryption on android which I can't seem to find similar way in dart.
This is so far what I've tried to achieve the same using Flutter_Des.dart, Password_Hash.dart and Crypto.dart library but still can't get the same output.
encryptPassword(String keyStr, String passwordStr) async {
if (keyStr.length == 0 || passwordStr.length == 0) {
return "";
}
var generator = new PBKDF2(hashAlgorithm: md5);
String saltStr = generateSaltBase64String();
var hash = generator.generateBase64Key(keyStr, saltStr, round, keyLength);
var encryptBase64 = await FlutterDes.encryptToBase64(passwordStr, hash.toString());
return encryptBase64;
}
Below is what I have currently on Android.
KeySpec keySpec = new PBEKeySpec(str.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
ecipher = Cipher.getInstance("PBEWithMD5AndDES");
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
byte[] utf8 = password.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
enc = Base64.encode(enc, Base64.DEFAULT);
return new String(enc);
I'm expecting the same output as android so my backend able to decrypt it.
PBEWithMD5AndDES uses PBKDF1 to generate the key material (not PBKDF2). This gives you 128 bits of key material that you then use as two 64 bit halves as the key and the IV for DES.
Derive the key and IV as follows - I've plugged in some arbitrary values for iteration, password and salt and confirmed against JCrypto.
int iterations = 31;
List<int> salt = [0x21, 0x21, 0xf0, 0x55, 0xc3, 0x9f, 0x5a, 0x75];
List<int> password = utf8.encode('test');
List<int> saltedKey = password + salt;
Digest d = md5.convert(saltedKey);
for (int i = 1; i < iterations; i++) {
d = md5.convert(d.bytes);
}
print(d);
List<int> key = d.bytes.sublist(0, 8);
List<int> iv = d.bytes.sublist(8, 16);
print(key);
print(iv);
I can't find a Dart implementation of DES which takes a key and IV as bytes. triple_des wants them as strings - i.e. it's dumbed down. Pointy castle doesn't do DES. FlutterDes also seems to want strings. You might be able to modify triple_des to take binary keys and IVs. Or use a different cipher.
Solved by using flutter's methodchannel and call platform specific code to do the encryption and its working now. Thanks

Writing a native messaging host in GJS

I'm trying to write a native messaging host for a chrome/firefox extension in GJS (since it will rely on code already written in GJS) but encountering some hurdles. I'm using chrome-gnome-shell as a rough template since it also uses GLib/Gio instrospection and GApplication, but it has the advantage of python struct that I don't have.
Quickly, native messaging hosts exchange messages through stdin/stdout which are an Int32 (4-bytes) length following by a string of utf-8 encoded JSON.
chrome-gnome-shell uses GLib.IOChannel with set_encoding('utf-8') and struct to handle int32 bytes. I've had trouble using that class in GJS and don't have struct so have been trying Gio.UnixInputStream wrapped in Gio.DataInputStream (and output counterparts), with put_int32()/read_int32() and put_string()/read_string().
Apparently I'm mightily confused about what I'm doing. If I call Gio.DataInputStream.read_int32() it returns a number 369098752, so I'm guessing the int32 is not being converted to a regular Number. If I call Gio.DataInputStream.read_bytes(4, null).unref_to_array() to get a ByteArray; ByteArray.toString() returns '\u0016' while ByteArray[0] returns '22' which appears to be the actual length.
Some pointers on reading/writing int32's to a datastream and would be much appreciated.
chrome-gnome-shell references:
on_input()
send_message()
I don't know if this is the best way to solve this, but here's what I came up with.
Two functions using the ByteArray import (modified from somewhere on SO):
const ByteArray = imports.byteArray;
function fromInt32 (byteArray) {
var value = 0;
for (var i = byteArray.length - 1; i >= 0; i--) {
value = (value * 256) + byteArray[i];
}
return value;
};
function toInt32 (num) {
var byteArray = [0, 0, 0, 0];
for (var index_ = 0; index_ < byteArray.length; index_++) {
var byte = num & 0xff;
byteArray [index_] = byte;
num = (num - byte) / 256 ;
}
return ByteArray.fromArray(byteArray);
};
For receiving/sending:
const Gio = imports.gi.Gio;
// Receiving
let stdin = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({ fd: 0 })
});
let int32 = stdin.read_bytes(4, null).toArray();
let length = fromInt32(int32);
let data = stdin.read_bytes(length, null).toArray().toString();
let message = JSON.parse(data);
// Sending
let stdout = new Gio.DataOutputStream({
base_stream: new Gio.UnixOutputStream({ fd: 1 })
});
let data = JSON.stringify(message);
let int32 = toInt32(data.length);
stdout.write(int32, null);
stdout.put_string(data, null);
Of course, you should wrap these in try-catch as appropriate and you'll probably want to connect a source to the input (you can use the Gio.UnixInputStream):
let source = stdin.base_stream.create_source(null);
source.set_callback(onReceiveFunc);
source.attach(null);
You may be able to use Gio.DataOutputStream.put_int32() and Gio.DataInputStream.read_int32() the same way as you use read_bytes() and put_string().

Youtube URL extractions

I have a program that will take the HTML from a youtube page, extract an encoded MP4 playback URL, deconstruct the key value pairs, and then recombine to create a valid URL
Pattern p = Pattern.compile("url_encoded_fmt_stream_map\":\".*?([^,]|[^\"]+?type=video%2Fmp4.*?)(?=,)");
Matcher m = p.matcher(html);
m.find();
String encodedMP4URL = URLDecoder.decode(m.group(1), "UTF-8");
//get MP4 encoded URL
HashMap<String, String> pairs = new HashMap<String, String>();
String[] temp = encodedMP4URL.split("&");
for (int i = 0; i < temp.length; i ++)
if (!temp[i].contains("url="))
pairs.put(temp[i].split("=")[0], temp[i].split("=")[1]);
else {
String URLPart = temp[i].split("\\?")[0] + "?";
pairs.put(URLPart.split("=")[0], URLPart.split("=")[1]);
String otherPart = temp[i].split("\\?")[1];
pairs.put(otherPart.split("=")[0], otherPart.split("=")[1]);
}
//decode String into key value pairs
pairs.remove("quality");
pairs.remove("type");
//remove pairs that aren't used
StringBuilder realURL = new StringBuilder(pairs.get("url"));
pairs.remove("url");
//add url base then remove key/value pair from map
for (String s : pairs.keySet())
if (s.equals("s"))
realURL.append("signature=" + pairs.get(s) + "&");
else
realURL.append(s + "=" + pairs.get(s) + "&");
//encode URL properly with required params
This works for what i assume to be all non-copyright videos (ie. any homemade video). However it does not seem to work for videos that i assume have some sort of copyright associated with them. With the videos that it does not work with, the url_encoded_fmt_stream_map does not seem to contain any other data that i could use.

How to create an array of character lines while reading a whole line from file in windows phone

fileReader = new StreamReader(new IsolatedStorageFileStream("textfiles\\easy.txt", FileMode.Open, filestorage));
var obj = App.Current as App;
var lines = fileReader.ReadToEnd();
obj.textfile = (string[])fileReader.ReadToEnd();
Getting an error
"cannot convert string to string[]" in obj.textfile =
(string[])fileReader.ReadToEnd();
If you want an array of lines from a single string, you can do
var arrayOfLines = lines.split("\n");

sending cyrillic text from flash as2 to database

I have a really big problem with saving data from Flash as2 to database. I tried solved it myself, read many topics on different forums but no result.
I have an Input Text field (mess_txt) in as2 project and Send button with the next code:
on(release){
var formData = new LoadVars();
formData.etext = mess_txt.text;
formData.sendAndLoad("sendmail.php", formData, "POST");
formData.onLoad = function(){
// receive actions...
}
}
Code in sendmail.php:
include("connect.php");
$text = $_POST['etext'];
$text = str_replace("\r", "<br/>", trim(strip_tags($text)));
$text = str_replace("\n", "", $text);
$text = str_replace("\"", """, $text);
$text = str_replace("'", "'", $text);
$query = "insert into reviews (text, status) values ('".$text."', 'new')";
mysql_query($query) or die (mysql_error());
mail("mail#gmail.com", "Title!", "Message text: ".$text);
When I use latin symbols both code works well but when I input cyrillic symbols in Input Text I have an empty string in PHP code.
In Input Text I use _self font and embed all glyphs. But I think that problem is in sending data because when send simple cyrillic string instead mess_txt.text I have an empty string as well.
Interesting, that when I used mb_detect_encoding($_POST['etext']) in PHP code I obtained ASCII not UTF
Please, help me!!!!
SOLVED!!!
I found how to solve this problem! May be it will be interesting for someone else...
Before sending data from as2 to php I transformed it from text to unicode codes. This is my function in as2 project:
on(release){
var txt = getRealText(mess_txt.text);
var formData = new LoadVars();
formData.etext = txt;
formData.sendAndLoad("sendmail.php", formData, "POST");
formData.onLoad = function(){
// receive actions...
}
function getRealText(str){
var newStr = "";
for(i=0, s=str.length; i<s; i++){
newStr += "&#"+ord(str.charAt(i))+";";
}
return newStr;
}
}
As result I sending string "тест" instead "тест".
In PHP file I received this string:
$text = html_entity_decode($_POST['etext'], ENT_NOQUOTES, 'UTF-8');
After that I obtained normal cyrillic (or any another) text.
Have a hope that this will be useful for someone!

Resources