How to do the correct way to encrypt to AES256 using CryptoJs - reactjs

Hi i'm new to React Native,
i can encrypt the data in the PHP but not with React Native using Crypto JS. (result in JS always different, the correct one is from the PHP)
This is the example in PHP :
<?php
$data = 'my1234567';
$iv = 'yourivare1234567';
$key = '356d9abc7532ceb0945b615a622c3370';
$abc = openssl_encrypt($data, 'aes-256-cbc', $key, 0, $iv);
var_dump($abc);
// result is : string(24) "9EF/QLpR+o/KrVueiI4L0g=="
Now i try to replicate it in my React Native apps using Crypto JS.
But the result always different, where i'm expecting the result using hardcoded data and iv like above is : "9EF/QLpR+o/KrVueiI4L0g=="
Below is the source code in JS :
const data = 'my1234567';
const iv = 'yourivare1234567';
const key = '356d9abc7532ceb0945b615a622c3370';
const fkey = CryptoJS.enc.Hex.parse(key);
const fiv = CryptoJS.enc.Hex.parse(iv);
const enc = CryptoJS.AES.encrypt(data, md5key, {
iv: fiv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
const final = enc.ciphertext.toString(CryptoJS.enc.Base64);
console.log('encrypted password: ' , final) // result is kYLFiwI1IDZcFfsKsbrbzg==
Can somebody help on this?
Thanks before

fkey and fiv must be parsed using the UTF8 encoder. md5key is not defined and must be replaced by fkey:
const data = 'my1234567';
const iv = 'yourivare1234567';
const key = '356d9abc7532ceb0945b615a622c3370';
const fkey = CryptoJS.enc.Utf8.parse(key);
const fiv = CryptoJS.enc.Utf8.parse(iv);
const enc = CryptoJS.AES.encrypt(data, fkey, {
iv: fiv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
const final = enc.ciphertext.toString(CryptoJS.enc.Base64);
console.log('encrypted password: ' , final) // result is 9EF/QLpR+o/KrVueiI4L0g==
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
Note that (except for testing purposes) no static IV may be used for security reasons.

Related

DiscordAPIError[50035]: Invalid Form Body | 5[APPLICATION_COMMANDS_DUPLICATE_NAME]: Application command names must be unique

This Is My index.js
const LOAD_SLASH = process.argv[2] == "load"
const CLIENT_ID = "981858607362629663"
const GUILD_ID = "970702726348546078"
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildVoiceStates
]
})
client.slashcommands = new Discord.Collection()
client.player = new Player(client, {
ytdlOptions: {
quality: "highestaudio",
highWaterMark: 1 << 25
}
})
let commands = []
const slashFiles = fs.readdirSync("./slash").filter(file => file.endsWith(".js"))
for (const file of slashFiles){
const slashcmd = require(`./slash/${file}`)
client.slashcommands.set(slashcmd.data.name, slashcmd)
if (LOAD_SLASH) commands.push(slashcmd.data.toJSON())
}
I Recieve The Following Error After I Run node index.js load :-
DiscordAPIError[50035]: Invalid Form Body 5[APPLICATION_COMMANDS_DUPLICATE_NAME]: Application command names must be unique at SequentialHandler.runRequest
I have tried uninstalling and re-installing discord.js, still I am experiencing this error, I would really like some help!
You have a duplicate command name somewhere in your files. Try finding it with the following snippet:
const slashFiles = fs.readdirSync("./slash").filter(file => file.endsWith(".js"))
for (const file of slashFiles){
const slashcmd = require(`./slash/${file}`)
console.log(slashcmd.data.name)
}
Find the command name which is logged twice and edit the command file accordingly.
In one of the files you duplicated name with another file

RSA encryption in Flutter (Dart)

I have the code below working in node.js and I am trying to convert it to make the API call directly from my flutter app... but I am having problems with the RSA encryption
import fetch from "node-fetch";
import nodeRSA from "node-rsa";
const KEYVER = '23'
const ID = '123456789123456789'
const PRIVATE_KEY = "vvkmlkmmvcmemmcmdmdmm.......cddncndndncn ="
generateRequestHeader(){
const hashString = `${ID}\n{Date.now().toString()}\n{KEYVER}\n`;
const signer = new nodeRSA(PRIVATE_KEY, "pkcs1");
const signature = signer.sign(hasString);
const sign_enc = signature.toString("base64");
return {
"AUTH_SIGNATURE": sign_enc,
"TIMESTAMP": Date.now().toString(),
"ID": ID,
"KEY_VERSION":KEYVER
};
}
async function callAPI(){
const options = {
method: 'GET',
headers: generateRequestHeader()
};
const response = await fetch(url, options);
return response;
}
The authentication works fine in node but I can't seem to find a package to replicate it in flutter. I was recommended fast_rsapackage :
#fast_rsa: ^3.4.6
import 'package:fast_rsa/fast_rsa.dart';
class Signature{
String Id = 'c93e7094-327b-4ff3-bf2e-c52f29a8277f';
String privateKey = "ABCDEG....Z=";
String keyVer = '23.0';
generateRequestHeaders() async {
String timeStamp = DateTime.now().toString();
String hashString = "${Id}\n${timeStamp}\n${keyVer}\n";
var signer = await RSA.convertPrivateKeyToPKCS1(privateKey);
var signature = await RSA.signPKCS1v15(signer, Hash.SHA256, privateKey);
var signature_enc = await RSA.base64(signature);
return {
"AUTH_SIGNATURE": signature_enc,
"TIMESTAMP": timeStamp,
"ID": Id,
"KEY_VERSION": keyVer,
};
}
Future<dynamic> rsaRequest() async {
var options = {'method': 'GET', 'headers': generateRequestHeaders()};
String url = 'https://api.........';
http.Response response = await http.get(url, headers: options);
try {
if (response.statusCode == 200) {
print(response.body);
var document = parse(response.body);
return document;
} else {
return "failed";
}
} catch (exp) {
print(exp);
return "failed";
}
}
}
but the server keeps returning auth_error. Can anyone help me please or show me a way to use the .js function directly inside flutter.
Thanks.
you can use https://pub.dev/packages/encrypt package to perform RSA encryption and decryption in dart and flutter.
import 'dart:io';
import 'package:encrypt/encrypt.dart';
import 'package:pointycastle/asymmetric/api.dart';
void main() {
final publicKey = await parseKeyFromFile<RSAPublicKey>('test/public.pem');
final privKey = await parseKeyFromFile<RSAPrivateKey>('test/private.pem');
final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
final encrypter = Encrypter(RSA(publicKey: publicKey, privateKey: privKey));
final encrypted = encrypter.encrypt(plainText);
final decrypted = encrypter.decrypt(encrypted);
print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit
print(encrypted.base64); // kO9EbgbrSwiq0EYz0aBdljHSC/rci2854Qa+nugbhKjidlezNplsEqOxR+pr1RtICZGAtv0YGevJBaRaHS17eHuj7GXo1CM3PR6pjGxrorcwR5Q7/bVEePESsimMbhHWF+AkDIX4v0CwKx9lgaTBgC8/yJKiLmQkyDCj64J3JSE=
}
I focus on the signing part. The NodeJS code creates a signature using RSA. For padding and digest the node-rsa default values are applied: PKCS#1v1.5 padding and SHA256, s. here. The private key is imported as DER encoded PKCS#1 key (Base64 encoded). The signature is Base64 encoded.
Note that in the NodeJS code posted in the question, the $ signs for the 2nd and 3rd variables regarding hashString are missing, which is probably a copy/paste error. This must be fixed, otherwise the signatures will differ!
On the Dart side, the following fixes are needed:
The PKCS#1 key is to be passed directly to RSA.signPKCS1v15(), i.e. the RSA.convertPrivateKeyToPKCS1() call is to be removed. RSA.signPKCS1v15() expects a PEM encoded key, i.e. header and footer are to be added and in the Base64 encoded body there is a line break after every 64 characters.
The timestamp is to be converted to the format used in the NodeJS code: DateTime.now().millisecondsSinceEpoch.toString().
RSA.signPKCS1v15() returns the signature already base64 encoded, i.e. the RSA.base64() call must be removed.
A possible dart counterpart with the fast_rsa library that fixes the above issues is:
Future<Map<String,String>> generateRequestHeaders() async {
String privateKey = '''-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBANoHbFSEZoOSB9Kxt7t8PoBwmauaODjECHqJgtTU3h4MW5K3857+
04Flc6x6a9xxyvCKS5RtOP2gaOlOVtrph0ECAwEAAQJBALu8LpRr2RWrdV7/tfQT
HIJd8oQnbAe9DIvuwh/fF08IwApOE/iGL+Ded49eoHHu1OXycZhpHavN/sQMnssP
FNECIQDyDIW7V5UUu16ZAeupeQ7zdV6ykVngd0bb3FEn99EchQIhAOaYe3ll211q
SIXVjKHudMn3xe6Vvguc9O7cwCB+gyqNAiEAsr3kk6/de23SMZNlf8TR8Z8eyybj
BAuQ3BMaKzWpyjECIFMR0UFNYTYIyLF12aCoH2h2mtY1GW5jj5TQ72GFUcktAiAf
WWXnts7m8kZWuKjfD0MQiW+w4iAph+51j+wiL3EMAQ==
-----END RSA PRIVATE KEY-----''';
String keyVer = "23";
String Id = "123456789123456789";
String timeStamp = DateTime.now().millisecondsSinceEpoch.toString(); // "1649917884089" for testing
String hashString = "${Id}\n${timeStamp}\n${keyVer}\n";
String signature = await RSA.signPKCS1v15(hashString, Hash.SHA256, privateKey);
return {
"AUTH_SIGNATURE": signature,
"TIMESTAMP": timeStamp,
"ID": Id,
"KEY_VERSION": keyVer,
};
}
...
var result = await generateRequestHeaders();
print(result["AUTH_SIGNATURE"]); // nRuX6eY+66Ca2ZbB/ZK6ealRdS8gYJ4UKNwUOdJySqujGnwpflE8aZ45L4PfQK3qAMJh02o0SVG8uy2Mz+BFpg== for datetime = '1649917884089'
Test:
Since signing with PKCS#1 v1.5 is deterministic, the same input data provides the same signature. This makes it easy to check the functional equivalence of both codes. If the same timestamp is used in both codes (e.g. the commented out 1649917884089), both codes return the same signature (nRuX6eY+66Ca2ZbB/ZK6ealRdS8gYJ4UKNwUOdJySqujGnwpflE8aZ45L4PfQK3qAMJh02o0SVG8uy2Mz+BFpg==), which proves the equivalence of both codes.
This is the fixed NodeJS code used for the test. It is essentially the same as the NodeJS code posted in the question:
// DER encoded PKCS#1 key, Base64 encoded
// Note: For testing purposes, a 512 bits key is used. In practice, key sizes >= 2048 bits must be applied for security reasons!
const PRIVATE_KEY = "MIIBOwIBAAJBANoHbFSEZoOSB9Kxt7t8PoBwmauaODjECHqJgtTU3h4MW5K3857+04Flc6x6a9xxyvCKS5RtOP2gaOlOVtrph0ECAwEAAQJBALu8LpRr2RWrdV7/tfQTHIJd8oQnbAe9DIvuwh/fF08IwApOE/iGL+Ded49eoHHu1OXycZhpHavN/sQMnssPFNECIQDyDIW7V5UUu16ZAeupeQ7zdV6ykVngd0bb3FEn99EchQIhAOaYe3ll211qSIXVjKHudMn3xe6Vvguc9O7cwCB+gyqNAiEAsr3kk6/de23SMZNlf8TR8Z8eyybjBAuQ3BMaKzWpyjECIFMR0UFNYTYIyLF12aCoH2h2mtY1GW5jj5TQ72GFUcktAiAfWWXnts7m8kZWuKjfD0MQiW+w4iAph+51j+wiL3EMAQ=="
const KEYVER = '23';
const ID = '123456789123456789';
const timeStamp = Date.now().toString(); // '1649917884089' for testing
function generateRequestHeader(){
const hashString = `${ID}\n${timeStamp}\n${KEYVER}\n`; // Fix: Add the $ sign
const signer = new nodeRSA(PRIVATE_KEY, "pkcs1");
const signature = signer.sign(hashString); // default signing scheme: PKCS#1 v1.5 with SHA256
const sign_enc = signature.toString("base64");
return {
"AUTH_SIGNATURE": sign_enc,
"TIMESTAMP": Date.now().toString(),
"ID": ID,
"KEY_VERSION":KEYVER
};
}
...
var result = generateRequestHeader();
console.log(result.AUTH_SIGNATURE); // nRuX6eY+66Ca2ZbB/ZK6ealRdS8gYJ4UKNwUOdJySqujGnwpflE8aZ45L4PfQK3qAMJh02o0SVG8uy2Mz+BFpg== for datetime = '1649917884089'

Get total amount of tokens received from a specific address using Web3.js

in a scenario, WalletA is receiving TokenB in a regular basis from AddressC.
AddressC only sends TokenB, nothing else.
in etherscan or bscscan it is simple to see how much of TokenB is received in WalletA and "from" field is there so you can do some math to get total.
How can this be done using web3? I couldn't find any relevant api call in web3 documents.
I can get total balance of TokenB in WalletA by web3.js but I need the count of tokens only sent from AddressC.
Thanks.
As per the ERC-20 standard, each token transfer emits a Transfer() event log, containing the sender address, receiver address and token amount.
You can get the past event logs using the web3js general method web3.eth.getPastLogs(), encode the inputs and decode the outputs.
Or you can supply ABI JSON of the contract (it's enough to use just the Transfer() event definition in this case) and use the web3js method web3.eth.Contract.getPastEvents(), which encodes the inputs and decodes the outputs for you based on the provided ABI JSON.
const Web3 = require('web3');
const web3 = new Web3('<provider_url>');
const walletA = '0x3cd751e6b0078be393132286c442345e5dc49699'; // sender
const tokenB = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; // token contract address
const addressC = '0xd5895011F887A842289E47F3b5491954aC7ce0DF'; // receiver
// just the Transfer() event definition is sufficient in this case
const abiJson = [{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}];
const contract = new web3.eth.Contract(abiJson, tokenB);
const fromBlock = 10000000;
const toBlock = 13453500;
const blockCountIteration = 5000;
const run = async () => {
let totalTokensTranferred = 0;
for (let i = fromBlock; i <= (toBlock - blockCountIteration); i += blockCountIteration) {
//console.log("Requesting from block", i, "to block ", i + blockCountIteration - 1);
const pastEvents = await contract.getPastEvents('Transfer', {
'filter': {
'from': walletA,
'to': addressC,
},
'fromBlock': i,
'toBlock': i + blockCountIteration - 1,
});
}
for (let pastEvent of pastEvents) {
totalTokensTranferred += parseInt(pastEvent.returnValues.value);
}
console.log(totalTokensTranferred);
}
run();

Coinbase Websocket, signature in authentication

How should the signature parameter be generated for opening an authenticated connection to Coinbase Websocket? I can't find any concise description anywhere.
For GET/PUT API calls, I successfully generated it with the below code, but with the Websocket there is neither a "method" nor a "path_url", so what should contain the "message"?
timestamp = str(time.time())
message = timestamp + request.method + request.path_url + (request.body or '')
hmac_key = base64.b64decode(self.secret_key)
signature = hmac.new(hmac_key, message.encode('utf-8'), hashlib.sha256)
signature_b64 = base64.b64encode(signature.digest())
I was finally able to solve this problem. Granted the code doesn't look all that interesting.
I'm using the following in conjunction with the CCXT library. More specifically, the Websockets fork implementation here.
const id = this.marketId (symbol)
const timestamp = Date.now() / 1000
const p_passphrase = this.safeValue(params, 'password')
const p_apiKey = this.safeValue(params, 'apiKey')
const p_secret = this.safeValue(params, 'secret')
const what = timestamp + 'GET' + '/users/self/verify'
const key = Buffer.from(p_secret, 'base64')
const hmac = require('crypto').createHmac('sha256', key)
const signature = hmac.update(what).digest('base64')
this.websocketSendJson({
'type': 'subscribe',
'product_ids': [id],
'channels': ['user'],
'key': p_apiKey,
'signature': signature,
'timestamp': timestamp,
'passphrase': p_passphrase,
})
Hopefully that helps!

Generate md5 checksum scala js

I am trying to calculate hex md5 checksum at in scala js incrementally. The checksum will be verified at server side once file is transferred.
I tried using spark-md5 scala js web jar dependency:
libraryDependencies ++= Seq("org.webjars.npm" % "spark-md5" % "2.0.2")
jsDependencies += "org.webjars.npm" % "spark-md5" % "2.0.2" / "spark-md5.js"
scala js Code:-
val reader = new FileReader
reader.readAsArrayBuffer(data) // data is javascript blob object
val spark = scala.scalajs.js.Dynamic.global.SparkMD5.ArrayBuffer
reader.onload = (e: Event) => {
spark.prototype.append(e.target)
print("Checksum - > " + spark.end)
}
Error:-
Uncaught TypeError: Cannot read property 'buffer' of undefined
at Object.SparkMD5.ArrayBuffer.append (sampleapp-jsdeps.js:596)
at FileReader. (SampleApp.scala:458)
I tried google but most of the help is available are for javascript, couldn't find anything on how to use this library in scala js.
Sorry If I missed something very obvious, I am new to both javascript & scala js.
From spark-md5 readme, I read:
var spark = new SparkMD5.ArrayBuffer();
spark.append(e.target.result);
var hexHash = spark.end();
The way you translate that in Scala.js is as follows (assuming you want to do it the dynamically typed way):
import scala.scalajs.js
import scala.scalajs.js.typedarray._
import org.scalajs.dom.{FileReader, Event}
val SparkMD5 = js.Dynamic.global.SparkMD5
val spark = js.Dynamic.newInstance(SparkMD5.ArrayBuffer)()
val fileContent = e.target.asInstanceOf[FileReader].result.asInstanceOf[ArrayBuffer]
spark.append(fileContent)
val hexHashDyn = spark.end()
val hexHash = hexHashDyn.asInstanceOf[String]
Integrating that with your code snippet yields:
val reader = new FileReader
reader.readAsArrayBuffer(data) // data is javascript blob object
val SparkMD5 = js.Dynamic.global.SparkMD5
val spark = js.Dynamic.newInstance(SparkMD5)()
reader.onload = (e: Event) => {
val fileContent = e.target.asInstanceOf[FileReader].result.asInstanceOf[ArrayBuffer]
spark.append(fileContent)
print("Checksum - > " + spark.end().asInstanceOf[String])
}
If that's the only use of SparkMD5 in your codebase, you can stop there. If you plan to use it several times, you should probably define a facade type for the APIs you want to use:
import scala.scalajs.js.annotation._
#js.native
object SparkMD5 extends js.Object {
#js.native
class ArrayBuffer() extends js.Object {
def append(chunk: js.typedarray.ArrayBuffer): Unit = js.native
def end(raw: Boolean = false): String = js.native
}
}
which you can then use much more naturally as:
val reader = new FileReader
reader.readAsArrayBuffer(data) // data is javascript blob object
val spark = new SparkMD5.ArrayBuffer()
reader.onload = (e: Event) => {
val fileContent = e.target.asInstanceOf[FileReader].result.asInstanceOf[ArrayBuffer]
spark.append(fileContent)
print("Checksum - > " + spark.end())
}
Disclaimer: not tested. It might need small adaptations here and there.

Resources