Angular/ASP:NET - Cant upload created image from base64 - javascript

I try to upload an image that is created from an base64 URI.
When i want to upload the image my server response with an 400 Status and i dont find my issue...
Can someone please help me?
This is my function to generate the image:
convertDataUrlToBlob(dataUrl): Blob {
const arr = dataUrl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type: mime});
}
The Image Object:
ProfileImage: File
lastModified: 1603491333691
lastModifiedDate: Sat Oct 24 2020 00:15:33 GMT+0200 (Mitteleuropäische Sommerzeit) {}
name: "userprofile.png"
size: 1911552
type: "image/png"
webkitRelativePath: ""
This is my function to upload the image
onPostClick(): void {
const file = new File([this.convertDataUrlToBlob(this.imageDestination)], "userprofile.png", {type: 'image/png'});
const data = {
ProfileImage : file,
id : this.userId
}
this.errorMessage = "";
if(this.imageDestination != ""){
this.postService.post(data).subscribe(result=>{
if(result){
console.log(result)
}
},
(error:HttpErrorResponse) => {
alert(error.message);
})
}
this.dialogRef.close();
}
My controller to uploade the image:
[HttpPut]
[Authorize]
//[RequestSizeLimit(1_000_000)]
[Route("UpdateImage")]
public async Task<IActionResult> UpdateImage(ApplicationUserModel model)
{
try
{
var user = await _userManager.FindByIdAsync(model.id);
if (user.ProfileImagePath != null)
{
var file = new FileInfo(user.ProfileImagePath);
file.Delete();
}
var uniqueFileName = GetUniqueFileName(model.ProfileImage.FileName);
var uploads = Path.Combine(hostingEnvironment.WebRootPath, "Images/ProfileImages");
var filePath = Path.Combine(uploads, uniqueFileName);
await model.ProfileImage.CopyToAsync(new FileStream(filePath, FileMode.Create));
user.ProfileImagePath = filePath;
var result = await _userManager.UpdateAsync(user);
return Ok(result);
}
catch (Exception ex)
{
throw ex;
}
}
The UserModel
public class ApplicationUserModel
{
public string id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Birthdate { get; set; }
public DateTime EntryDate { get; set; }
public string Role { get; set; }
public IFormFile ProfileImage { get; set; }
public IFormFile HeaderImage { get; set; }
public string ProfileImagePath { get; set; }
}

Related

Solidity Compiler not writing any json files

VS Code suggested i install Solidity extension which I did. immediately it installed it required that I update my solidity to 0.8.17; I did then I had to update some parts of the code. after I did, I tested on remix and it worked. Back on vs code now and I've been trying to compile but it is not compiling.It creates the 'build' folder but doesn't write any JSON files in it.
Campaign.sol file:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
contract CampaignFactory {
address[] public deployedCampaigns;
function createCampaign(uint minimum) public {
Campaign newCampaign = new Campaign(minimum, msg.sender);
deployedCampaigns.push(address(newCampaign));
}
function getDeployedCampaigns() public view returns (address[] memory) {
return deployedCampaigns;
}
}
contract Campaign {
struct Request {
string description;
uint value;
address payable recipient;
bool complete;
uint approvalCount;
mapping(address => bool) approvals;
}
Request[] public requests;
address public manager;
uint public minimumContribution;
mapping(address => bool) public approvers;
uint public approversCount;
modifier restricted() {
require(msg.sender == manager);
_;
}
constructor (uint minimum, address creator) {
manager = creator;
minimumContribution = minimum;
}
function contribute() public payable {
require(msg.value > minimumContribution);
approvers[msg.sender] = true;
approversCount++;
}
function createRequest(string memory description, uint value, address payable recipient) public restricted {
Request storage newRequest = requests.push();
newRequest.description = description;
newRequest.value = value;
newRequest.recipient = recipient;
newRequest.complete = false;
newRequest.approvalCount = 0;
}
function approveRequest(uint index) public {
Request storage request = requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender] = true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount > (approversCount / 2));
require(!request.complete);
request.recipient.transfer(request.value);
request.complete = true;
}
function getSummary() public view returns (
uint, uint, uint, uint, address
) {
return(
minimumContribution,
address(this).balance,
requests.length,
approversCount,
manager
);
}
function getRequestsCount() public view returns (uint) {
return requests.length;
}
}
compile.js file
const path = require("path");
const solc = require("solc");
const fs = require("fs-extra");
const buildPath = path.resolve(__dirname, "build");
fs.removeSync(buildPath);
const campaignPath = path.resolve(__dirname, "contracts", "Campaign.sol");
const source = fs.readFileSync(campaignPath, "utf8");
const output = solc.compile(source, 1).contracts;
fs.ensureDirSync(buildPath);
for (let contract in output) {
fs.outputJsonSync(
path.resolve(buildPath, contract.replace(":", "") + ".json"),
output[contract]
);
}

AES Encryption/Decryption with Java and Typescript

i encrypt my string in JAVA like:
public String encrypt(String toEncrypt) {
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encVal = c.doFinal(toEncrypt.getBytes());
return Base64.getEncoder().encodeToString(encVal);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
and I want to decrypt it in typescript:
public static decrypt(key, value){
key = btoa(key);
let decryptedData = CryptoJS.AES.decrypt(value, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decryptedData.toString( CryptoJS.enc.Utf8 );
}
the decryptedData.toString( CryptoJS.enc.Utf8 ) returns the following Error: Malformed UTF-8 data
I followed along this tutorial
here is a working example
JAVA:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class Crypter {
private final String key = "1234567890123456";
public String encrypt(String toEncrypt) {
try {
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return new String(Base64.getEncoder().encode(encrypted));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public String decrypt(String toDecrypt) {
try {
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] cipherText = cipher.doFinal(Base64.getDecoder().decode(toDecrypt));
return new String(cipherText);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
TypeScript:
import * as CryptoJS from 'crypto-js';
export class Crypter{
public static encrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
let ciphertext = CryptoJS.AES.encrypt(value, key, {iv: key}).toString();
return ciphertext;
}
public static decrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
let decryptedData = CryptoJS.AES.decrypt(value, key, {
iv: key
});
return decryptedData.toString( CryptoJS.enc.Utf8 );
}
}

Encrypt By javascript and decrypt by Java

I use AES encryption in my react-native app as below
import CryptoJS from 'crypto-js' ;
encryptFun() {
var data = "123456";
var key = CryptoJS.enc.Latin1.parse('1234567812345678');
var iv = CryptoJS.enc.Latin1.parse('1234567812345678');
var encrypted = CryptoJS.AES.encrypt(
data,
key,
{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding
});
console.log('encrypted: ' + encrypted) ;
var decrypted = CryptoJS.AES.decrypt(encrypted,key,{iv:iv,padding:CryptoJS.pad.ZeroPadding});
console.log('decrypted: '+decrypted.toString(CryptoJS.enc.Utf8));
}
Out come= encrypted: aK7+UX24ttBgfTnAndz9aQ==
following is the code I use in my backend using java for get the decrypt
public static String desEncrypt() throws Exception {
try
{
String data = "aK7+UX24ttBgfTnAndz9aQ==" ;
String key = "1234567812345678";
String iv = "1234567812345678";
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(data);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
output= decryted : = 123456[][][][][][][][][][]
Iam getting out put as 16 bit as above.
what I want is out put should come as only 123456.
I Suggest you use java.util.Base64 for decoding. The following worked out correctly. I would also suggest using trim in return originalString and see if it works out.
public class Decrypt {
public static void main(String[] args) {
try
{
String data = "aK7+UX24ttBgfTnAndz9aQ==" ;
String key = "1234567812345678";
String iv = "1234567812345678";
Decoder decoder = Base64.getDecoder();
byte[] encrypted1 = decoder.decode(data);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
System.out.println(originalString.trim());
}
catch (Exception e) {
e.printStackTrace();
}
}
}
As you padded with zeros in the JS you can't decrypt with NoPadding, solutions would be to operate on the array or the String
trim the array
int i = original .length - 1;
while (i >= 0 && original [i] == 0) {
--i;
}
return new String(Arrays.copyOf(original , i + 1));
trim the String
return new String(original).trim();
remove manually the zero values
return new String(original).replace("\0", "");
Or, as it seems there is no ZeroPAdding in Java implemented (Cipher Documentation), take a look at How Encrypt with AES CBC Zero Padding in Javascript and decrypt with Java that suggests to use CryptoJS.pad.Pkcs
Controller part to generate RSA key ( public & private )
package com.secure.encryption.decryption.controller;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.secure.encryption.decryption.rsa.keystore.KeyStore;
import com.secure.encryption.decryption.rsa.service.RSAKeyPairGenerator;
import com.secure.encryption.decryption.util.AesUtil;
#RestController
public class EncryptDecryptController {
#Autowired
RSAKeyPairGenerator rsa;
#Autowired
KeyStore keystore;
#CrossOrigin
#GetMapping(value = "get/rsa/public")
public Map<String, Object> generateRSA_PUBLIC_PRIVATE_KEY()
{
Map<String, Object> response = new HashMap<>();
/**
* Below function creates rsa public & private key
* While this api only share PUBLICKEY
* Whereas PRIVATEKEY is stored in bean/model
*/
String public_KEY = null;
public_KEY = rsa.KeyPairGenerator();
response.put("public", public_KEY);
return response;
}
#CrossOrigin
#PostMapping(value = "/decrypt/AES_encyptedKEY/with/RSA_privateKEY/decryptdata/with/aes")
public Map<String, Object> decrypt(#RequestBody Map<String, Object> req) throws UnsupportedEncodingException
{
/**
* First decrypt AES-Key which is encrypted with RSA Public Key
* Use RSA privateKey for decryption
*/
String Decrypted_AES_Key = rsa.decrypt(req.get("phrase").toString(),keystore.getPrivateKey());
byte[] decoded = Base64.getDecoder().decode(req.get("data").toString());
String encryptedAES_Data = new String(decoded, StandardCharsets.UTF_8);
/**
* Decode data to base 64
* Use AES key to decrypt the data
*/
AesUtil aesUtil = new AesUtil(128, 1000);
String decryptedAES_Data = aesUtil.decrypt(
req.get("salt").toString(),
req.get("iv").toString(),
Decrypted_AES_Key,
encryptedAES_Data);
/**
* Map actual data as response
*/
req.put("data", decryptedAES_Data);
return req;
}
#CrossOrigin
#GetMapping(value = "/decryptfrom/backend/aes/plain/decrypt/frontend")
public Map<String, Object> sendAESencryptedData()
{
/**
* Generate random key
* Encrypt data using same
* pass key to UI
* Decrypt using same key, iv and salt
*/
Map<String, Object> response = new HashMap<>();
int i = (int) (new Date().getTime()/1000);
//String iv = generateIv().toString();
AesUtil aesUtil = new AesUtil(128, 1000);
String phrase = String.valueOf(i);//"my secret key 123";
//String salt = new String(generateSalt(32));
String iv = "bb6a69ace7a11a38fba164238e000c7c";
String salt = "6c3674b6469467ab0b9f2b57ce36e78d";
String encryptedAES_Data =
Base64.getEncoder().encodeToString(
aesUtil.encrypt(
salt,
iv,
phrase,
"ganesha")
);
response.put("data", encryptedAES_Data);
response.put("salt", salt);
response.put("iv", iv);
response.put("key", phrase);
return response;
}
/*
public IvParameterSpec generateIv() {
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
private byte[] generateSalt(int size) {
try {
byte[] salt = new byte[size];
SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
rand.nextBytes(salt);
return salt;
} catch (Exception e) {
System.err.println(e);
}
return null;
}
*/
}
Service to generate and RSA random Key
package com.secure.encryption.decryption.rsa.service;
public interface RSAKeyPairGenerator {
public String KeyPairGenerator();
public byte[] encrypt(String data, String publicKey);
public String decrypt(String data, String base64PrivateKey);
}
Implementation Class
package com.secure.encryption.decryption.rsa.service;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.secure.encryption.decryption.rsa.keystore.KeyStore;
#Service
public class RSAKeyPairGeneratorImpl implements RSAKeyPairGenerator{
#Autowired
KeyStore keystore;
#Override
public String KeyPairGenerator() {
Map<String, Object> keypair = new HashMap<String, Object>();
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair pair = keyGen.generateKeyPair();
final String privatestring = Base64.getEncoder().encodeToString(pair.getPrivate().getEncoded());
final String publicstring = Base64.getEncoder().encodeToString(pair.getPublic().getEncoded());
keystore.setPrivateKey(privatestring);
return publicstring;
} catch (Exception e) {
System.err.println(e);
}
return null;
}
private static PublicKey getPublicKey(String base64PublicKey){
PublicKey publicKey = null;
try{
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
private static PrivateKey getPrivateKey(String base64PrivateKey){
PrivateKey privateKey = null;
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes()));
KeyFactory keyFactory = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
privateKey = keyFactory.generatePrivate(keySpec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
public byte[] encrypt(String data, String publicKey) {//throws BadPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {
try {
//AES/CBC/PKCS5Padding
//RSA/ECB/PKCS1Padding
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey));
return cipher.doFinal(data.getBytes());
} catch (Exception e) {
System.err.println(e);
}
return null;
}
private static String decrypt(byte[] data, PrivateKey privateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(cipher.doFinal(data));
}
public String decrypt(String data, String base64PrivateKey) {//throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
try {
return decrypt(Base64.getDecoder().decode(data.getBytes()), getPrivateKey(base64PrivateKey));
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
AesUtil class
package com.secure.encryption.decryption.util;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.tomcat.util.codec.binary.Base64;
public class AesUtil {
private final int keySize;
private final int iterationCount;
private final Cipher cipher;
public AesUtil(int keySize, int iterationCount) {
this.keySize = keySize;
this.iterationCount = iterationCount;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw fail(e);
}
}
public byte[] encrypt(String salt, String iv, String passphrase, String plaintext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, iv, plaintext.getBytes("UTF-8"));
System.out.println(encrypted);
return encrypted;//Base64.getEncoder().encodeToString(encrypted);
//String s = Base64.getEncoder().encodeToString(encrypted);
}
catch (UnsupportedEncodingException e) {
throw fail(e);
}
}
public String decrypt(String salt, String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));
return new String(decrypted, "UTF-8");
}
catch (UnsupportedEncodingException e) {
return null;
}catch (Exception e){
return null;
}
}
private byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
cipher.init(encryptMode, key, new IvParameterSpec(hex(iv)));
return cipher.doFinal(bytes);
}
catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException e) {
return null;
}
}
private SecretKey generateKey(String salt, String passphrase) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hex(salt), iterationCount, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
return key;
}
catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
return null;
}
}
public static byte[] base64(String str) {
return Base64.decodeBase64(str);
}
public static byte[] hex(String str) {
try {
return Hex.decodeHex(str.toCharArray());
}
catch (DecoderException e) {
throw new IllegalStateException(e);
}
}
private IllegalStateException fail(Exception e) {
return null;
}
}
Steps followed
Consume the RSA key
Generate random AES (key, iv, salt) - using crypto.js
Use AES and encrypt vulnerable data
Use RSA public key for encrypting AES key
Send encrypted data & key over network
Service consumes data decrypt key to AES
Use AES key to decrypt data
Send the data back to front end
Html page for reference
<!DOCTYPE html>
<html>
<body>
<script src="jquery.min.js"></script>
<script src="jsencrypt.min.js"></script>
<script type="text/javascript" src="crypto-js.min.js"></script>
<script type="text/javascript" src="aes.js"></script>
<script type="text/javascript">
const payloadsample = {
"addressLine1": "301,Kamala Mills Compound",
"addressLine2": "Gr Flr, Tulsi Pipe Rd, Lower Parel ",
"addressLine4": "Mumbai, Maharashtra",
"zipcode": 400071
};
/**
Step 1 ) - get data
**/
/**
Step 2 ) - get RSA pub Key
**/
function hybridEncryption()
{
$.ajax({
type: 'GET',//post
url: 'http://localhost:1818/get/rsa/public',
success: function(res) {
let RSAEncrypt = new JSEncrypt();
RSAEncrypt.setPublicKey(res.public);//set RSA public key
const key = Math.random().toString(36).slice(2);//Generate random AES key
console.log("key ", key);
var iv = CryptoJS.lib.WordArray.random(128/8).toString(CryptoJS.enc.Hex);
var salt = CryptoJS.lib.WordArray.random(128/8).toString(CryptoJS.enc.Hex);
var aesUtil = new AesUtil(128, 1000);
debugger
console.log(key)
var data = JSON.stringify({ payloadsample });
var ciphertext = aesUtil.encrypt(salt, iv, key, data);
/**
Step 3 ) - generate key
**/
senData(RSAEncrypt, iv, salt, key, btoa(ciphertext))
},
error:function(e) {
console.error(e);
},
contentType: "application/json",
dataType: 'json'
});
}
function senData(RSAEncrypt, iv, salt, key, base64Content)
{
const payload = {
"phrase":RSAEncrypt.encrypt(key),//encrypt with RSA
"data":base64Content,
"iv":iv,
"salt":salt
}
console.log("sending : ", payload);
$.ajax({
type: 'POST',
url: 'http://localhost:1818/decrypt/AES_encyptedKEY/with/RSA_privateKEY/decryptdata/with/aes',
data: JSON.stringify (payload), // or JSON.stringify ({name: 'jonas'}),
success: function(data) {
console.log(data);
},
error:function(e) {
console.error(e);
},
contentType: "application/json",
dataType: 'json'
});
}
hybridEncryption();
/**
* Incase of Backend encryption to Front end Decryption
* decryptBE() - will get AES encrypted data with associated data
* */
function decryptBE()
{
$.ajax({
type: 'GET',//post
url: 'http://localhost:1818/decryptfrom/backend/aes/plain/decrypt/frontend',
success: function(res) {
debugger
var aesUtil = new AesUtil(128, 1000);
var ciphertext = aesUtil.decrypt(res.salt, res.iv, res.key, res.data);
console.log(ciphertext);
},
error:function(e) {
console.error(e);
},
contentType: "application/json",
dataType: 'json'
});
}
</script>
</body>
</html>
This is a working example using reference
Other lib used is aes.js
var AesUtil = function(keySize, iterationCount) {
this.keySize = keySize / 32;
this.iterationCount = iterationCount;
};
AesUtil.prototype.generateKey = function(salt, passPhrase) {
var key = CryptoJS.PBKDF2(
passPhrase,
CryptoJS.enc.Hex.parse(salt),
{ keySize: this.keySize, iterations: this.iterationCount });
return key;
}
AesUtil.prototype.encrypt = function(salt, iv, passPhrase, plainText) {
var key = this.generateKey(salt, passPhrase);
var encrypted = CryptoJS.AES.encrypt(
plainText,
key,
{ iv: CryptoJS.enc.Hex.parse(iv) });
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}
AesUtil.prototype.decrypt = function(salt, iv, passPhrase, cipherText) {
var key = this.generateKey(salt, passPhrase);
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(cipherText)
});
var decrypted = CryptoJS.AES.decrypt(
cipherParams,
key,
{ iv: CryptoJS.enc.Hex.parse(iv) });
return decrypted.toString(CryptoJS.enc.Utf8);
}
rest are
JSEncrypt v2.3.1 https://npmcdn.com/jsencrypt#2.3.1/LICENSE.txt
and finally crypto-js.min.js
Thank you i hope this would be usefull

How Do I bind javascript type of File to a Nancy Model containing HttpFile?

I'm trying to bind a put request that contains File in typescript to Nancy's HttpFile. The request always sets the HttpFile in C# to null. Is there a way to do this?
#Injectable()
export class FileUploadService {
#Output() progress: EventEmitter<number> = new EventEmitter<number>();
/**
* uploads a file to the service and returns the document's id
*/
public upload(req: IUploadRequest): Observable<number> {
let promise = new Promise((resolve: any, reject: any) => {
let xhr: XMLHttpRequest = new XMLHttpRequest();
xhr.upload.onprogress = (event: any) => {
let progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
this.progress.emit(progress);
};
xhr.onload = () => {
let json = JSON.parse(xhr.response);
resolve(<number>json.documentId);
};
xhr.onerror = () => {
reject(xhr.response);
};
xhr.onabort = () => {
reject(xhr.response);
};
xhr.open("PUT", `${environment.API_ROOT}/document`, true);
xhr.setRequestHeader(environment.AUTH_HEADER_NAME, getToken());
let formData: FormData = new FormData();
formData.append("file", <File>req.file, req.file.name);
formData.append("description", req.description);
formData.append("chapterId", req.chapterId.toString());
xhr.send(formData);
});
return Observable.fromPromise(promise);
}
}
export class IUploadRequest {
public file: File;
public description: string;
public chapterId: number;
}
The model I'm trying to bind to...
public class FileUploadRequest
{
public long ContentSize { get; set; }
public HttpFile File { get; set; }
public string Description { get; set; }
public int ChapterId { get; set; }
}
And in the C# API...
var request = this.Bind<FileUploadRequest>();
What am I doing wrong? "file" always comes back as null in C#.
Just an FYI... I fixed this by going into the request itself and grabbing the File in Request.File.

Twitch Alert in self-hosted bot on a Mac?

using Discord.Commands;
using Discord;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Services;
using System.Threading;
using System.Collections.Generic;
using NadekoBot.Services.Database.Models;
using System.Net.Http;
using NadekoBot.Attributes;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NLog;
using NadekoBot.Extensions;
using System.Diagnostics;
namespace NadekoBot.Modules.Searches
{
public partial class Searches
{
public class StreamStatus
{
public bool IsLive { get; set; }
public string ApiLink { get; set; }
public string Views { get; set; }
public string Game { get; set; }
public string Status { get; set;}
}
public class HitboxResponse {
public bool Success { get; set; } = true;
[JsonProperty("media_is_live")]
public string MediaIsLive { get; set; }
public bool IsLive => MediaIsLive == "1";
[JsonProperty("media_views")]
public string Views { get; set; }
}
public class TwitchResponse
{
public string Error { get; set; } = null;
public bool IsLive => Stream != null;
public StreamInfo Stream { get; set; }
public class StreamInfo
{
public int Viewers { get; set; }
public string Game { get; set; }
public ChannelInfo Channel { get; set;}
public class ChannelInfo {
public string Status { get; set; )
}
}
}
public class BeamResponse
{
public string Error { get; set; } = null;
[JsonProperty("online")]
public bool IsLive { get; set; }
public int ViewersCurrent { get; set; }
}
public class StreamNotFoundException : Exception
{
public StreamNotFoundException(string message) : base("Stream '" + message + "' not found.")
{
}
}
[Group]
public class StreamNotificationCommands : ModuleBase
{
private static Timer checkTimer { get; }
private static ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static Logger _log { get; }
private static bool FirstPass { get; set; } = true;
static StreamNotificationCommands()
{
_log = LogManager.GetCurrentClassLogger();
checkTimer = new Timer(async (state) =>
{
oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(cachedStatuses);
cachedStatuses.Clear();
IEnumerable<FollowedStream> streams;
using (var uow = DbHandler.UnitOfWork())
{
streams = uow.GuildConfigs.GetAllFollowedStreams();
}
await Task.WhenAll(streams.Select(async fs =>
{
try
{
var newStatus = await GetStreamStatus(fs).ConfigureAwait(false);
if (FirstPass)
{
return;
}
StreamStatus oldStatus;
if (oldCachedStatuses.TryGetValue(newStatus.ApiLink, out oldStatus) &&
(oldStatus.IsLive != newStatus.IsLive)
{
var server = NadekoBot.Client.GetGuild(fs.GuildId);
if (server == null)
return;
var channel = server.GetTextChannel(fs.ChannelId);
if (channel == null)
return;
try
{
var msg = await channel.EmbedAsync(fs.GetEmbed(newStatus)).ConfigureAwait(false);
}
catch { }
}
}
catch { }
}));
FirstPass = false;
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
}
private static async Task<StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true)
{
string response;
StreamStatus result;
switch (stream.Type)
{
case FollowedStream.FollowedStreamType.Hitbox:
var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username.ToLowerInvariant()}";
if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result))
return result;
using (var http = new HttpClient())
{
response = await http.GetStringAsync(hitboxUrl).ConfigureAwait(false);
}
var hbData = JsonConvert.DeserializeObject<HitboxResponse>(response);
if (!hbData.Success)
throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]");
result = new StreamStatus()
{
IsLive = hbData.IsLive,
ApiLink = hitboxUrl,
Views = hbData.Views
};
cachedStatuses.AddOrUpdate(hitboxUrl, result, (key, old) => result);
return result;
case FollowedStream.FollowedStreamType.Twitch:
var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username.ToLowerInvariant())}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6";
if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result))
return result;
using (var http = new HttpClient())
{
response = await http.GetStringAsync(twitchUrl).ConfigureAwait(false);
}
var twData = JsonConvert.DeserializeObject<TwitchResponse>(response);
if (twData.Error != null)
{
throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]");
}
result = new StreamStatus()
{
IsLive = twData.IsLive,
ApiLink = twitchUrl,
Views = twData.Stream?.Viewers.ToString() ?? "0"
Game = twData.Stream?.Game,
Status = twData.Stream?.Channel?.Status
};
cachedStatuses.AddOrUpdate(twitchUrl, result, (key, old) => result);
return result;
case FollowedStream.FollowedStreamType.Beam:
var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username.ToLowerInvariant()}";
if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result))
return result;
using (var http = new HttpClient())
{
response = await http.GetStringAsync(beamUrl).ConfigureAwait(false);
}
var bmData = JsonConvert.DeserializeObject<BeamResponse>(response);
if (bmData.Error != null)
throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]");
result = new StreamStatus()
{
IsLive = bmData.IsLive,
ApiLink = beamUrl,
Views = bmData.ViewersCurrent.ToString()
};
cachedStatuses.AddOrUpdate(beamUrl, result, (key, old) => result);
return result;
default:
break;
}
return null;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task Hitbox([Remainder] string username) =>
await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Hitbox)
.ConfigureAwait(false);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task Twitch([Remainder] string username) =>
await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Twitch)
.ConfigureAwait(false);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task Beam([Remainder] string username) =>
await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Beam)
.ConfigureAwait(false);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task ListStreams()
{
IEnumerable<FollowedStream> streams;
using (var uow = DbHandler.UnitOfWork())
{
streams = uow.GuildConfigs
.For(Context.Guild.Id,
set => set.Include(gc => gc.FollowedStreams))
.FollowedStreams;
}
if (!streams.Any())
{
await Context.Channel.SendConfirmAsync("You are not following any streams on this server.").ConfigureAwait(false);
return;
}
var text = string.Join("\n", await Task.WhenAll(streams.Select(async snc =>
{
var ch = await Context.Guild.GetTextChannelAsync(snc.ChannelId);
return $"`{snc.Username}`'s stream on **{(ch)?.Name}** channel. 【`{snc.Type.ToString()}`】";
})));
await Context.Channel.SendConfirmAsync($"You are following **{streams.Count()}** streams on this server.\n\n" + text).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task RemoveStream(FollowedStream.FollowedStreamType type, [Remainder] string username)
{
username = username.ToLowerInvariant().Trim();
var fs = new FollowedStream()
{
ChannelId = Context.Channel.Id,
Username = username,
Type = type
};
bool removed;
using (var uow = DbHandler.UnitOfWork())
{
var config = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(gc => gc.FollowedStreams));
removed = config.FollowedStreams.Remove(fs);
if (removed)
await uow.CompleteAsync().ConfigureAwait(false);
}
if (!removed)
{
await Context.Channel.SendErrorAsync("No such stream.").ConfigureAwait(false);
return;
}
await Context.Channel.SendConfirmAsync($"Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task CheckStream(FollowedStream.FollowedStreamType platform, [Remainder] string username)
{
var stream = username?.Trim();
if (string.IsNullOrWhiteSpace(stream))
return;
try
{
var streamStatus = (await GetStreamStatus(new FollowedStream
{
Username = stream,
Type = platform,
}));
if (streamStatus.IsLive)
{
await Context.Channel.SendConfirmAsync($"Streamer {username} is online with {streamStatus.Views} viewers.");
}
else
{
await Context.Channel.SendConfirmAsync($"Streamer {username} is offline.");
}
}
catch
{
await Context.Channel.SendErrorAsync("No channel found.");
}
}
private static async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type)
{
username = username.ToLowerInvariant().Trim();
var fs = new FollowedStream
{
GuildId = channel.Guild.Id,
ChannelId = channel.Id,
Username = username,
Type = type,
};
StreamStatus status;
try
{
status = await GetStreamStatus(fs).ConfigureAwait(false);
}
catch
{
await channel.SendErrorAsync("Stream probably doesn't exist.").ConfigureAwait(false);
return;
}
using (var uow = DbHandler.UnitOfWork())
{
uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FollowedStreams))
.FollowedStreams
.Add(fs);
await uow.CompleteAsync().ConfigureAwait(false);
}
await channel.EmbedAsync(fs.GetEmbed(status), $"🆗 I will notify this channel when status changes.").ConfigureAwait(false);
}
}
}
public static class FollowedStreamExtensions
{
public static EmbedBuilder GetEmbed(this FollowedStream fs, Searches.StreamStatus status)
{
var embed = new EmbedBuilder().WithTitle(fs.Username)
.WithUrl(fs.GetLink())
.WithThumbnailUrl(fs.GetLink())
.WithDescription(status.Status)
.AddField(efb => efb.WithName("Status")
.WithValue(status.IsLive ? "Online" : "Offline")
.WithIsInline(true))
.AddField(efb => efb.WithName("Viewers")
.WithValue(status.IsLive ? status.Views : "-")
.WithIsInline(true))
.AddField(efb => efb.WithName("Game">
.WithValue(status.Game)
.WithIsInlin(true))
.AddField(efb => efb.WithName("Platform")
.WithValue(fs.Type.ToString())
.WithIsInline(true))
.WithColor(status.IsLive ? "NadekoBot.OkColor" : "NadekoBot.ErrorColor");
return embed;
}
public static string GetLink(this FollowedStream fs) {
if (fs.Type == FollowedStream.FollowedStreamType.Hitbox)
return $"http://www.hitbox.tv/{fs.Username}/";
else if (fs.Type == FollowedStream.FollowedStreamType.Twitch)
return $"http://www.twitch.tv/{fs.Username}/";
else if (fs.Type == FollowedStream.FollowedStreamType.Beam)
return $"https://beam.pro/{fs.Username}/";
else
return "??";
}
}
}
I'm attempting to get this discord bot to announce when someone streaming on Twitch goes Live by amending its code to give me more information (ie Game and Status) but I keep getting an error that I can't for the life of me find and fix! I was told the issue is between coding on a PC and coding on a Mac? Not sure that's 100% accurate. Can someone please run this code and help me get this to work properly? Thanks!

Categories