How to call a contract function from a specific address - node.js

I want to use web3 to call a contract function(sendTransaction not call) from a specific address that I hold the private key to. I also have the contract instance connected. I know I have to dio something like web3.personal.unlockAccount(address,password,duration)
And then specify the from address.
So my question is, is "password" where I enter my private key? And how do I pass that address into fromAddress once I unlock it.
Or is there a more streamlined way to go about it?

is "password" where I enter my private key?
No, it's not. Actually it is a password, which you entered when you were creating account and which was used to generate your keystore file.
If you use web3.personal.unlockAccount(address,password,duration) you need to have your keystore file in the keystore folder near chaindata of geth.
Another way will be to use web3.eth.sendRawTransaction from web3.py, but it will be a little bit clunky to call contract method from it.
key = '0x' + 'YOUR-PRIVATE-KEY
transaction = {
'to': _to,
'value': 0,
'gas': 300000,
'gasPrice': 23000000000,
'nonce': web3.eth.getTransactionCount(_from),
'chainId': int(web3.admin.nodeInfo['protocols']['eth']['network']),
'data': b''
}
signed = web3.eth.account.signTransaction(transaction, key)
print("Transaction Hash: " + web3.toHex(web3.eth.sendRawTransaction(signed.rawTransaction)))
My suggestion will be to create keyfile recognisable by Ethereum clients by using web3.eth.account.encrypt (web3.py because web3.js yet lack this functionality) and after you generate it put it in the right folder and try simply to unlock account.

Related

Fetching OpenIdConnectConfiguration while offline/no connection to AuthServer

I've been working on how to save OpenIdConnecConfiguration locally in the odd case that the AuthServer is not reachable but the frontend client (e.g. Phone) still has a valid refresh token which still needs to be validated again when signing in. It is also needed to be saved locally to a file in the case that the backend (e.g. WCF) has restarted due to a update or the frequent restarts it has (once a day)
What I've done so far, I've saved the JSON object of the ".well-known/openid-configuration" to a file/variable and now I want to create the OpenIdConnectConfiguration object.
OpenIdConnectConfiguration.Create(json) does a lot of the work but the signingKeys do not get created. I think maybe it's because the authorization endpoint needs to be created in some other manner maybe?
Or maybe I'm doing this the wrong way and there is another solution to this issue. I'm working in C#.
Edit: I know there are some caveats to what I'm doing. I need to check once in awhile to see if the public key has been changed, but security wise it should be fine to save the configuration because it's already public. I only need the public key to validate/sign the jwt I get from the user and nothing more.
Figured out a solution after looking through OpenIdConnectConfiguration.cs on the official github.
When fetching the OpenIdConnectConfiguration the first time, use Write() to get a JSON string and use it to save it to file.
Afterwards when loading the file, use Create() to create the OpenIdConnectConfiguration again from the JSON string (This had the issue of not saving the signingKeys as said in the question, but alas! there is a fix)
Lastly to fix the issue with the signingKeys not being created, (this is what I found out from the github class) all we need to do is loop through the JsonWebKeySet and create them as is done in the class. We already have all the information needed from the initial load and therefore only need to create them again.
I'll leave the code example below of what I did. I still need to handle checking if he key has been changed/expired which is the next step I'll be tackling.
interface IValidationPersistence
{
void SaveOpenIdConnectConfiguration(OpenIdConnectConfiguration openIdConfig);
OpenIdConnectConfiguration LoadOpenIdConnectionConfiguration();
}
class ValidationPersistence : IValidationPersistence
{
private readonly string _windowsTempPath = Path.GetTempPath();
private readonly string _fileName = "TestFileName";
private readonly string _fullFilePath;
public ValidationPersistence()
{
_fullFilePath = _windowsTempPath + _fileName;
}
public OpenIdConnectConfiguration LoadOpenIdConnectionConfiguration()
{
FileService fileService = new FileService();
OpenIdConnectConfiguration openIdConfig = OpenIdConnectConfiguration.Create(fileService.LoadFromJSONFile<string>(_fullFilePath));
foreach (SecurityKey key in openIdConfig.JsonWebKeySet.GetSigningKeys())
{
openIdConfig.SigningKeys.Add(key);
}
return openIdConfig;
}
public void SaveOpenIdConnectConfiguration(OpenIdConnectConfiguration openIdConfig)
{
FileService fileService = new FileService();
fileService.WriteToJSONFile(OpenIdConnectConfiguration.Write(openIdConfig), _fullFilePath);
}
}

how to encrypt password text input using script mode in Katalon ?

I have a csv with a list of users and passwords that I need check the login.
Is there any way to encrypt password text input using script mode in
Katalon ?
I found an answer on katalon forums but they do that manually using a a tool of the IDE like you can see here Working with Sensitive Text
I would like to create an script that for every (user,password) encrypt the password and login using encrypted password.
#Keyword
def login(user, password, url){
WebUI.navigateToUrl(url)
WebUI.setText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormemail'),user)
def password_encript = Encrypt(password)// Fictitious method that I would like to get
WebUI.setEncryptedText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormpassword'), password_encript)
WebUI.click(findTestObject('Object Repository/Page_Sign in My Page/input_yt0'))
}
Is there a method like Encrypt(password) in Katalon?
Is there a way to do that in code?
Thanks in advance.
I came across this question while investigating other Katalon encryption questions, and thought I may offer some late insight.
The "setEncryptedText(TestObject, encryptedText)" method is to allow you to store sensitive text in an encrypted form, which is then decrypted when entered into the web application.
Since your method is being passed 'password' as a string in cleartext, then why not just have the function do:
WebUI.setText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormpassword'), password)
So to use Java Encryption : Blowfish with Text and Key.
Here is my solution :
public static String encrypt(String strClearText,String strKey) throws Exception{
String strData="";
// streData - here you put your data
try {
SecretKeySpec skeyspec=new SecretKeySpec(strKey.getBytes(),"Blowfish");
Cipher cipher=Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, skeyspec);
byte[] encrypted=cipher.doFinal(strClearText.getBytes());
strData=new String(encrypted);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return strData;
}

Youtube Search for Videos in given Channel only

How can (a user) SEARCH FOR OUR VIDEOS BY KEYWORDS (Public Videos -- OUR Channel Only..)..
We were basing our approach in https://developers.google.com/youtube/v3/code_samples/javascript#search_by_keyword
We want to use API KEY for Authorization.. and Access is via browser.. (JS)
So when the user enters KEYWORDS in a Search box the CONTEXT (where to search) should already be the given Channel XXXX (its Public Videos)..
What would be the API/methods to use and with what params..??
The search endpoint is the correct one to use, passing the keywords as the 'q' parameter and the channel as the 'channelId' parameter. So, using the sample function you linked to, you might try something like this:
function search() {
var q = $('#query').val();
var request = gapi.client.youtube.search.list({
q: q,
part: 'snippet',
channelId: {whatever your ID is}
});

How to store public/private key securely

Looking to store public/private key information securely on an iOS device. I know I want to store this in the KeyChain however I am not 100% sure what sort of attributes I need to populate in the SecRecord. I was going to do something like:
// private key
SecKeyChain.Add(new SecRecord(SecKind.Key)
{
Accessible = SecAccessible.AlwaysThisDeviceOnly,
KeySizeInBits = 512,
KeyClass = SecKeyClass.Private,
CanSign = true,
ValueData = privateKeyValue,
Account = publicKeyValue
});
Which would store the private key, then follow a similar approach for the public key replacing the Account attribute with a value unique to the user e.g. username. However, not sure if this is the right way to use this.
Does anyone have a good examples on how you would do this specifically for keys?
Decided to go with the following approach:
// store public key
SecKeyChain.Add(new SecRecord(SecKind.Key)
{
ApplicationLabel = userName,
Accessible = SecAccessible.AlwaysThisDeviceOnly,
KeySizeInBits = 512,
KeyClass = SecKeyClass.Public,
ValueData = NSData.FromString(publicKey)
});
// store private key
SecKeyChain.Add(new SecRecord(SecKind.Key)
{
ApplicationLabel = publicKey,
Accessible = SecAccessible.AlwaysThisDeviceOnly,
KeySizeInBits = 512,
KeyClass = SecKeyClass.Private,
CanSign = true,
ValueData = NSData.FromString(secretKey)
});
This means each public key is mapped to an individual user and each private key is mapped to a public key which allows me to store multiple user keys (rather than only storing current logged in users).
Seems to work ok, however, still not 100% sure it is the correct way to do this kind of thing so some clarification would be nice.

Noob way to login the user in Prestashop

This is a walkthrough on how to make a user login on prestashop without passing through the login screen. This is helpful if you do not want the user to login again like when you want to transfer his session from one website to prestashop.
Step 1 Eliminate the need for password salting. Under config/settings.inc.php, set _COOKIE_KEY_ to blank. Note this also means that you must create a new customer. Or you can delete the old md5 password from DB and add your own.
Step 2 In the authentication.php file paste the following lines after line 6:
$customer = new Customer();
//$authentication = $customer->getByEmail(trim($email), trim($passwd));
$authentication = $customer->getByMd5(trim($email), trim($passwd)); //modified version of getByEmail if we are not accepting $passwd in cleartext but in md5.
/* Handle brute force attacks */
sleep(1);
if (!$authentication OR !$customer->id)
$errors[] = Tools::displayError('authentication failed');
else
{
$cookie->id_customer = intval($customer->id);
$cookie->customer_lastname = $customer->lastname;
$cookie->customer_firstname = $customer->firstname;
$cookie->logged = 1;
$cookie->passwd = $customer->passwd;
$cookie->email = $customer->email;
if (Configuration::get('PS_CART_FOLLOWING') AND (empty($cookie->id_cart) OR Cart::getNbProducts($cookie->id_cart) == 0))
$cookie->id_cart = intval(Cart::lastNoneOrderedCart(intval($customer->id)));
Module::hookExec('authentication');
if ($back = Tools::getValue('back'))
Tools::redirect($back);
//Tools::redirect('my-account.php'); //cut redirection to break infinite loop
}
The above code is what makes the user login using $email as username and $passwd as password in plaintext. The original code comes from the if (Tools::isSubmit('SubmitLogin')) function inside the authentication.php file.
Step 3 Paste the above code in the products.php file just under line 5
Step 4 In case you are sending $passwd directly in md5 format, here is the modified version of getByEmail()(customer.php):
public function getByMd5($email, $passwd = NULL)
{
$result = Db::getInstance()->GetRow('SELECT * FROM `'._DB_PREFIX_ .'customer` WHERE `active` = 1 AND `email` = \''.pSQL($email).'\' '.(isset($passwd) ? 'AND `passwd` = \''.pSQL(_COOKIE_KEY_.$passwd).'\'' : '').' AND `deleted` = 0');
if (!$result)
return false;
$this->id = $result['id_customer'];
foreach ($result AS $key => $value)
if (key_exists($key, $this))
$this->{$key} = $value;
return $this;
}
You can get access to the username/passwd either through the $_COOKIE[] function or through $_GET[]. Either way its a big security risk. Cookie reading can be placed in the index.php file.
This approach you have proposed is extremely insecure. A salt is required for password safety and should never be removed. Further more by authenticating a user with their MD5 hash you effectively voiding all protection that hashing passwords provides you. People hash passwords because attacks like SQL injection allow an attacker to obtain this hash which then needs to be cracked. In this scenario the attacker can grab the admin's hash and just login right away.
The correct way to do session sharing:
Create a simple table to store session state. In this case the Cryptgoraphic Nonce is a large random value used to reference the data.
'insert into session_state (sess,token) value ('.pSQL(serialize($_SESSION)).', '.$cryptographic_nonce.')'
When the browser is redirected to another shop give them a redirect like this:
header('location: https://some_other_shop/landing.php?token=$cryptographic_nonce');
When the new server gets this landing request it fetches the session state from the previous server:
$sess=http_get($_SERVER['HTTP_REFERER']."?token=$_GET[token]");
$_SESSION=unserialize($sess);
Note you might have to transfer the user's data in the database as well.

Resources