Hello I am building an API on python to create a user and insert password in database. The problem is that the application is on Laravel PHP and using bcrypt. For example encrypting "test1234$%" in PYTHON gives "$2b$12$rsGZPtjctbI6bSGzS4P3mOSdrABnJuHfnKxEQwvm4KFu72BN3XNKK" and encrypting same in PHP gives "$2y$10$cO2nvRURLRdlW8j6CbWu8OeVlv7dyeozpBZcxVB2nd8hbyILyg7Xa"
and when trying to login with users created by the api on the app it does not work.
Even if i test with this it does not work the output is invalid:
$hash = '$2b$12$rsGZPtjctbI6bSGzS4P3mOSdrABnJuHfnKxEQwvm4KFu72BN3XNKK';
//validade hash in php
if(password_verify ( "test1234$%", $hash )){
echo "valid";
} else {
echo "invalid";
}
echo("\n".phpversion());
on python side used the following code:
pip install bcrypt
import bcrypt
password = item.password
bpassword = b"password"
hashed = bcrypt.hashpw(bpassword, bcrypt.gensalt())
on PHP side:
if (! function_exists('bcrypt')) {
/**
* Hash the given value against the bcrypt algorithm.
*
* #param string $value
* #param array $options
* #return string
*/
function bcrypt($value, $options = [])
{
return app('hash')->driver('bcrypt')->make($value, $options);
}
}
bcrypt use different salt each runtime that is why its perfect for storing password on database... unless you force it to use the same salt each time it will keep generating different resulting hash
I found a solution in the Python api i call bcrypt in PHP using subprocess
code = """echo password_hash("""'"'+item.password+'"'""",PASSWORD_BCRYPT);"""
hashed_password = await myClass.php(code)
async def php(self, code):
p = subprocess.Popen(["php", "-r", code],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out = p.communicate()
if out[1] != b'': raise Exception(out[1].decode('UTF-8'))
return out[0].decode('UTF-8')
Related
With the code below I am executing a python script from an ASP.Net Core app which runs in IIS. I want to run the python script with a different user which has limited rights.
I am able to change the user. I verified this by running the command getpass.getuser() in the script. But the script still has access to parts of the drive which it should not.
When running the script via command line and changing the user via runas it works perfectly. The user only as limited access.
How can I restricted the python script from my ASP.Net Core app?
public string ExecutePythonSnippet(string pythonSnippetFilePath, string pkgFilePath, string parameterString, string command = null)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = pythonPath;
string argsString = $"\"{pythonSnippetFilePath}\"";
argsString += $" \"{pkgFilePath}\"";
argsString += $" \"{parameterString}\"";
if (command != null)
argsString += $" \"{command}\"";
start.Arguments = argsString;
if (!string.IsNullOrWhiteSpace(_username))
{
start.Verb = "runasuser";
start.UserName = _username;
start.Password = new NetworkCredential("", _password).SecurePassword;
}
start.UseShellExecute = false;// Do not use OS shell
start.CreateNoWindow = true; // We don't need new window
start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
string result = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
if (string.IsNullOrEmpty(result))
return result;
else
throw new Exception(result);
}
}
EDIT: Changed runas to runasuser but with no success
On my local PC I want to use Python to both send and receive data on a remote MySQL database, via a PHP file that is located on the same webserver as the MySQL database.
I can already UPDATE the MySQL database when I run the following PHP script on the webserver:
<?php
$host_name = 'host';
$database = 'db';
$user_name = 'user';
$password = 'pass';
$conn = new mysqli($host_name, $user_name, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "UPDATE test
SET test = 1
WHERE test = 0";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
I have searched for hours but so far cannot make any decent attempt at Python code that will send a variable to the PHP code that will in turn update the MySQL database.
The PHP file seems to be publicly accessible so I don't imagine webserver credentials are required in my Python?
Thank you in advance SO!
With a local PHP server running using php -S localhost:8881 receive.php
send.py
import requests
url = 'http://localhost:8881'
myobj = {'key1': 'value1'}
x = requests.post(url, data = myobj)
print (x.text)
receive.php
<?php
var_dump($_POST);
Output of running send.py will be:
array(1) {
["key1"]=>
string(6) "value1"
}
For future potential visitors, below is the combination of Python and PHP that finally wrote a value from my local Python file -> to the remote PHP file -> which wrote successfully to a MySQL database.
I write the integer 6 where the value 2 exists in the database table.
Python:
import requests
url = 'https://url/file_name.php'
myobj = {'key1': 6}
x = requests.post(url, data = myobj)
print (x.text)
PHP on server (file_name.php):
<?php
$host_name = 'hostname';
$database = 'db_name';
$user_name = 'user_name';
$password = 'password';
$conn = new mysqli($host_name, $user_name, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Set variable post_data to equal the value of 'key1', which also had to be converted into an integer
$post_data = intval($_POST['key1']);
// SQL Query
$sql = "UPDATE table_name
SET column_name = $post_data
WHERE value = 2";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
I get the feeling there's probably a lot of useless information in the PHP file, but I'm a PHP newbie and just glad it's working now :)
I want to use python client to create a Nessus Security Scanner and check the status by getStatus and get the result by getReport method. While, I have read these helps by php(SoftLayer API Nessus Scan Status / Report via PHP). But how can i use these by python client?
When I call setInitParameter(scan_id) in by python, the exception as flows:
SoftLayerAPIError(Client): Function ("setInitParameter") is not a valid method for this service
i recomend you to read documentation of the client first:
https://github.com/softlayer/softlayer-python
https://softlayer-api-python-client.readthedocs.io/en/latest/
the init parameters are set like this:
clientService.getObject(id=myInitParameter)
here you can find more examples using the client:
https://softlayer.github.io/python/
Here you can find additional documentation:
http://sldn.softlayer.com/blog
And renember that with the Softlayer's python client unlike the php client the data are sending in json format so the request:
$client = SoftLayer_SoapClient::getClient('SoftLayer_Account', null, $apiUsername, $apiKey);
$accountInfo = $client->getObject();
$hardware = $client->getHardware();
foreach ($hardware as $server){
$scanclient = SoftLayer_SoapClient::getClient('SoftLayer_Network_Security_Scanner_Request', '', $apiUsername, $apiKey)
$scantemplate = new stdClass();
$scantemplate->accountId = $accountInfo->id;
$scantemplate->hardwareId = $server->id;
$scantemplate->ipAddress = $server->primaryIpAddress;
try{
// Successfully creates new scan
$scan = $scanclient->createObject($scantemplate);
} catch (Exception $e){
echo $e->getMessage() . "\n\r";
}
would be like this:
clientAccount = client['SoftLayer_Account']
accountInfo = clientAccount.getObject() #for this case we do not need init parameter
hardware = clientAccount.getHardware() #for this case we do not need init parameter
for server in hardware:
scanclient = client['SoftLayer_Network_Security_Scanner_Request']
scantemplate = {
"accountId": accountInfo["id"],
"hardwareId": server["id"],
"ipAddress": server["primaryIpAddress"]
}
scanclient.createObject(scantemplate)
I'm porting over a Django site to Node.js and I am trying to re implement the Django set password method in Node. This is the Django code
from django.utils.crypto import (
pbkdf2, get_random_string)
import hashlib
password = 'text1'
algorithm = "pbkdf2_sha256"
iterations = 10000
salt = 'p9Tkr6uqxKtf'
digest = hashlib.sha256
hash = pbkdf2(password, salt, iterations, digest=self.digest)
hash = hash.encode('base64').strip()
print "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
and here's the Node.js code I have so far:
var password = 'text1';
var hashed = crypto.createHash('sha256').update(password, 'utf8').digest();
var salt = 'p9Tkr6uqxKtf';
var algorithm = "pbkdf2_sha256";
var iterations = 10000;
crypto.pbkdf2(hashed, salt, iterations, 32, function(err, encodedPassword) {
var newPass = new Buffer(encodedPassword).toString('base64');
console.log(encodedPassword);
// console.log(Buffer(encodedPassword, 'binary').toString('hex'));
var finalPass = algorithm +'$'+ iterations +'$'+ salt +'$'+ newPass;
console.log(finalPass);
});
My solution in Node doesn't output the same results as the Python / Django code. At this point I'm pretty much over my head and any help would be very much appreciated. Thanks in advance.
Here is a better solution using pbkdf2-sha256:
var pbkdf2 = require('pbkdf2-sha256');
var password = 'text1';
var salt = 'p9Tkr6uqxKtf';
var algorithm = "pbkdf2_sha256";
var iterations = 10000;
var hashed = pbkdf2(password, new Buffer(salt), iterations, 32).toString('base64');
var finalPass = algorithm +'$'+ iterations +'$'+ salt +'$'+ hashed;
The above code should be sufficient to validate passwords stored in Django using Node.
So my solution to this was to create a python script that takes the salt and users password and returns the hashed password. I call this script from node and parse the results. I check if the hashed password starts with: pbkdf2_sha256, then I validate it against what my python script returned, if it validates use my new systems hashing function to reset the password.
Use pbkdf2-sha256 instead. Had the exact same problem you were dealing with (Django -> NodeJS) and that did the trick for me! :)
Thank you #paldepind for your answer that helped me! However, the pbkdf2-sha256 module is deprecated. And while it is replaced with pbkdf2, that isn't necessary either; Node provides the built-in crypto module with a pbkdf2 function which works if you give it the correct parameters. Here's the code with the OP's password. I've also verified this code with my own passwords:
const crypto = require("crypto");
// Given the following password, using algorithm pbkdf2_sha256:
// pbkdf2_sha256$10000$p9Tkr6uqxKtf$9OTqv/1X3jvhdyWRm1vwQzMYO9cOzth7hYpoFe0qboA=
var password = "text1";
var salt = "p9Tkr6uqxKtf";
var iterations = 10000;
crypto.pbkdf2(password, salt, iterations, 32, "sha256", (err, derivedKey) => {
if (err) throw err;
console.log(derivedKey.toString("base64"));
});
You can also use pbkdf2Sync.
Following bababa's answer, my approach was to create a Python script as well using
"from django.contrib.auth import hashers"
The functions hashers.check_password() and hashers.make_password() provide the functionality needed to validate or create passwords against a Django installation.
More documentation on this functions can be found on https://docs.djangoproject.com/en/1.5/topics/auth/passwords/
I have been struggling with this for over two days and I could use your help. Here's the problem:
Whenever a request is made to the Facebook REST server, we have to send an additional parameter called "sig". This sig is generated using the following algorithm:
<?php
$secret = 'Secret Key'; // where 'Secret Key' is your application secret key
$args = array(
'argument1' => $argument1,
'argument2' => $argument2); // insert the actual arguments for your request in place of these example args
$request_str = '';
foreach ($args as $key => $value) {
$request_str .= $key . '=' . $value; // Note that there is no separator.
}
$sig = $request_str . $secret;
$sig = md5($sig);
?>
More information about this: http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application
I have been trying to reproduce this piece of code in Python, here is my attempt:
def get_signature(facebook_parameter):
sig = ""
for key, value in facebook_parameter.parameters:
sig += key + "=" + value
sig += facebook_parameter.application_secret
return hashlib.md5(sig).hexdigest()
facebook_paremeter.parameters is a list that looks like this:
[('api_key', '...'), ('v', '1.0'), ('format', 'JSON'), ('method', '...')]
and facebook_paremeter.application_secret is a valid app secret.
This code is running on the Google App Engine development platform (if that makes any difference). Python 2.6.4.
Can somebody help me find out where my code is going wrong?
Thanks,
Sri
List had to be sorted.