Encryption in C# and Decryption in javascript with AES Algorithm - javascript

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.

Related

Crypto-js decrypt file encrypted with crypto

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();
};

Javascript gzip decompression

I want do decompress images in JavaScript. I have compressed the images with C# using gzip. How do I decompress gzipped data in JavaScript?
C# code
public static byte[] Compress(byte[] raw)
{
using (MemoryStream memory = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(memory, CompressionMode.Compress, true))
{
gzip.Write(raw, 0, raw.Length);
}
return memory.ToArray();
}
}
First of all you have to close the GZipStream when you are done with it.
public static byte[] Compress(byte[] raw)
{
using (MemoryStream memory = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(memory, CompressionMode.Compress, true))
{
gzip.Write(raw, 0, raw.Length);
gzip.Close();
}
return memory.ToArray();
}
}
You can use pako for decompressing in javascript.
var base64Data = "COMPRESSED_BASE64_GZIP";
var compressData = atob(base64Data);
compressData = compressData.split('').map(function (e) {
return e.charCodeAt(0);
});
var originalText = pako.ungzip(compressData, {to:"string"});

Java and JavaScript same sha256 hex

To get a Java SHA256 hash I use the following method:
public String getSha256(String text, String encoding){
String sha = "";
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(text.getBytes(encoding));
byte[] digest = md.digest();
sha = new String(digest);
sha = sha.replace("\n", "");
} catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
}
return sha;
}
Like so:
String testValue = getSha256("test", "UTF-8");
Then to get the HEX value out of it I do the following:
public String getHexFromString(String text){
String hex = "";
try {
byte[] myBytes = text.getBytes("UTF-8");
hex = DatatypeConverter.printHexBinary(myBytes);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
}
return hex;
}
System.out.print(getHexFromString(testValue));
The result of this is:
C5B8E280A0C390EFBFBDCB864C7D65C5A12FC3AAC2A0C3855AC39015C2A3C2BF4F1B2B0BE2809A2CC3915D6C15C2B0C3B008
In javascript I do the following (using this library):
var hash = sjcl.hash.sha256.hash("test");
console.log(sjcl.codec.hex.fromBits(hash));
And the result is:
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
How can I get same hex in Java and Javascript?
What am I doing wrong, is it the Java or Javascript code?
#JonSkeet was right, changed the method, it now looks like this:
public String getSha256Hex(String text, String encoding){
String shaHex = "";
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(text.getBytes(encoding));
byte[] digest = md.digest();
shaHex = DatatypeConverter.printHexBinary(digest);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
}
return shaHex;
}
And the result is:
9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08
The only difference is that the Java hex is upper case, but thats a minor thing to solve.

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

How to pass image in string format to JavaScript and write it to document

I am passing JSON string to JavaScript code which contains {"imagePath":"a.svg"} Now instead of passing the path I want to send the image as string(some byte code maybe). I will be parsing this string in JavaScript and writing this as image to document.
Convert svg string to base64 and add base64 string to json as property.
Look at example: https://jsfiddle.net/wLftvees/1/
var decodedJson = {
img:
"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBB"+
"ZG9iZSBJbGx1c3RyYXRvciAxNS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9u"+
...
"NSw4LjU5NS0wLjA5NSwxMC42ODIsMS45MDMiLz4NCjwvc3ZnPg0K"
};
document.getElementById('image').src = 'data:image/svg+xml;base64,' + decodedJson.img;
First: Convert your image to String
public static String encodeToString(BufferedImage image, String type) {
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(image, type, bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
Second: Convert String to image
public static BufferedImage decodeToImage(String imageString) {
BufferedImage image = null;
byte[] imageByte;
try {
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
Now you can use 2 function and switch to Javascript to get Image. ^^

Categories