Crypto-js decrypt file encrypted with crypto - javascript

I encrypt a file using crypto on a node.js server. When a client then downloads the file and tries to decrypt it using crypto-js, the output is not correct.
This is the code I use to encrypt:
var fileName = 'test.txt';
var key = Buffer.from(KEY_STRING, "utf8");
var iv = Buffer.from(IV_STRING, "utf8");
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
var input = fs.createReadStream(fileName);
var output = fs.createWriteStream(fileName + '.enc');
input.pipe(cipher).pipe(output);
The client downloads test.txt.enc, reads its content into a string (fileContent in the following code) and decrypts:
var decrypted = CryptoJS.AES.decrypt(
fileContent,
CryptoJS.enc.Utf8.parse(KEY_STRING),
{
iv: CryptoJS.enc.Utf8.parse(IV_STRING),
mode: CryptoJS.mode.CBC
}
);
var cleartext = CryptoJS.enc.Utf8.stringify(decrypted);
When the client converts the WordArray back to the utf-8 text it gets an "Error: Malformed UTF-8 data" message. The file is received correctly because I use the hash to check.
EDIT: Filling of fileContent
fs.readFile('test.txt.enc', readContent);
function readContent (err, data) {
err ? Function("error","throw error")(err) : fileContent = data.toString();
};

Related

Get filename and length from blob stream

I am using websockets to send a file from my c# server to my browser. I added the file name and filebytelength along with the file in the bytestream.
My c# code to include file name in the byte stream
string filename = "#\C:\Users\Username\Downloads\RAW1MB data.txt";
string shortName = System.IO.Path.GetFileName(FileName);
byte[] fileNameByte = Encoding.UTF8.GetBytes(shortName);
byte[] fileNamelen = BitConverter.GetBytes(shortName.Length);
byte[] filedata = File.ReadAllBytes(FileName);
byte[] senddata = new byte[4 + fileNameByte.Length + filedata.Length];
fileNamelen.CopyTo(senddata, 0);
fileNameByte.CopyTo(senddata, 4);
filedata.CopyTo(senddata, 4 + fileNameByte.Length);
await webSocket.SendAsync(new ArraySegment<byte>(senddata,0,senddata.Length),WebSocketMessageType.Binary,true,CancellationToken.None );
This is my Javascript included in my HTML
websocket.onmessage = function (e) {
if(e.data instanceof Blob){
window.alert("Getting file");
var filedata = e.data;
var filenameLen = filedata.slice(0,4);
Console.log(filenamelen);// I am getting Blob{ size: 4 ,type: ""}
}
else{
writeToScreen("<span>RESPONSE: " + e.data + "</span>");
}
};
From the console.log I am getting Blob{ size:4,type :""}.
How do I get the integer and string from first 4 bytes and the following respectively?
So without getting the filenamelen I am unable to get the filename as well.

Encryption in C# and Decryption in javascript with AES Algorithm

I am trying to decrypt the string in JavaScript which is encrypted by using AES 256 algorithm in a C# application. The code of encryption and decryption is as below
I am able to decrypt the string in a C# application. I used the below code to decrypt the string JavaScript but I am not able to decrypt
public string Encrypt(string content)
{
if (string.IsNullOrEmpty(content))
{
throw new ArgumentNullException("content");
}
byte[] encryptedData = null;
try
{
using (AesCryptoServiceProvider aesMod = new AesCryptoServiceProvider())
{
//Set the key manullay to predefined values
aesMod.Key = m_Key;
aesMod.IV = m_IV;
ICryptoTransform encryptor = aesMod.CreateEncryptor(aesMod.Key, aesMod.IV);
// Create the streams used for encryption.
using (MemoryStream memstreamEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(memstreamEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Writing data to the stream.
swEncrypt.Write(content);
}
encryptedData = memstreamEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encryptedData);
}
catch (Exception ex)
{
throw new Exception("Exception in Encrypting .", ex);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<script>
function decryptMessage(encryptedMessage = '', secretkey = ''){
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(encryptedMessage)
});
var decrypted = CryptoJS.AES.decrypt(cipherParams, secretkey);
var decryptedMessage = decrypted.toString(CryptoJS.enc.Utf8);
return decryptedMessage;
}
</script>
The problem could be that the strings in C# are encoded in UTF-16
Try to change the encoding in the JavaScript code, if possible.

Javascript Incorrect header check decompressing zlib buffer generated by Python

I am compressing a string in Python and trying to decompress it in JavaScript.
Compress a string in Python:
import zlib, base64
text = "Test string"
result = base64.b64encode(zlib.compress(text.encode("utf-8"))
In JavaScript:
const zlib = require('zlib');
var data = atob(<text encoded in base64 from Python>);
zlib.inflate(data, function(err, buffer){
if(!err){
// doing something
}
else{
console.log(err); // <-- Error: data error: incorrect header check
}
});
In JavaScript, it returns "Incorrect header check" error. How should I compress the data in Python to obtain the same value of zlib.inflate() in JavaScript?
You are passing a string to zlib.inflate in your javascript code, but it expects a Buffer instance.
var data = Buffer.from('eJwLSS0uUSguKcrMSwcAGWAEWA==', 'base64')
zlib.inflate(data, function(err, buffer) {
if (!err) {
console.log(buffer.toString());
} else {
console.log(err);
}
})
Test string

How to decode protobuf base64 string to js object

I'm try to decode protobuf message from server side (base64 string) to javascript object. Use for decode protobuf.js.
As doc suggest :
var builder = ProtoBuf.newBuilder({ convertFieldsToCamelCase: true });
var YourMessage = builder.build("YourMessage");
var buffer = ...; // E.g. a buffer received on a WebSocket
var myMessage = YourMessage.decode(buffer);
...
var b64str = ...; // E.g. a string fetched via AJAX
var myMessage = YourMessage.decode64(b64str);
This is how I try to do it (data - base64 string) :
var proto = dcodeIO.ProtoBuf;
var buffer = dcodeIO.ByteBuffer;
var b = buffer.wrap(data,"binary");
var builder = proto.newBuilder({ convertFieldsToCamelCase: true });
builder.define("Events");
var message = builder.build("Events");
var result = message.decode(b); //also try to decode base64 string - message.decode64(data);
I get error
decode/decode64 undefined
Missing the line to import the proto definition as below (where tests/example1.proto is your file name)
ProtoBuf.loadProtoFile("tests/example1.proto", builder);
or if loading from proto string
ProtoBuf.loadProto(...protoString..., "example1.proto");
without this the builder will say undefined because there is nothing for it to build its definition with

Encrypt parameters to JWT(JSON web token) using JS in HTML page

I want to generate JWT using JavaScript on HTML page.
I looked at Online JWT service Click Here, but can't get proper idea.
So is there any solution to generate JWT using JavaScript in HTML page.
I've encode and decode method in c# code. but i want to encode parameter from java script and will decode in c# code.
My c# Code look like:
public static string Encode(object payload, byte[] key, JwtHashAlgorithm algorithm)
{
var segments = new List<string>();
var header = new { typ = "JWT", alg = algorithm.ToString() };
byte[] headerBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(header));
byte[] payloadBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(payload));
segments.Add(Base64UrlEncode(headerBytes));
segments.Add(Base64UrlEncode(payloadBytes));
var stringToSign = string.Join(".", segments.ToArray());
var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
byte[] signature = HashAlgorithms[algorithm](key, bytesToSign);
segments.Add(Base64UrlEncode(signature));
return string.Join(".", segments.ToArray());
}
public static string Decode(string token, byte[] key, bool verify = true)
{
var parts = token.Split('.');
var header = parts[0];
var payload = parts[1];
byte[] crypto = Base64UrlDecode(parts[2]);
var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
var headerData = jsonSerializer.Deserialize<Dictionary<string, object>>(headerJson);
var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
if (verify)
{
var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));
var keyBytes = key;
var algorithm = (string)headerData["alg"];
var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign);
var decodedCrypto = Convert.ToBase64String(crypto);
var decodedSignature = Convert.ToBase64String(signature);
if (decodedCrypto != decodedSignature)
{
throw new SignatureVerificationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature));
}
}
return payloadJson;
}
Your answer will appreciable.
Thanks,
Hardik

Categories