I need to log users into eXist-db using XQuery. Of course I can use this code:
xquery version "3.0";
declare namespace exist = "http://exist.sourceforge.net/NS/exist";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xmldb="http://exist-db.org/xquery/xmldb";
declare option exist:serialize "method=json media-type=text/javascript";
let $userName := request:get-parameter("userName", ())
let $hash := request:get-parameter("hash", ())
let $login := xmldb:authenticate('/db', $userName, $hash)
return
<ajax-response>
<success>{$login}</success>
<username>{$userName}</username>
</ajax-response>
The problem is that, due to the fact that I receive the password and the username from another service, I receive them in hash form encrypted with MD5 (because they can't be passed in clear from a service to another).
But the xmldb:authenticate function needs the password in clear. How can I resolve this? Any idea? Is there a way to login 'manually' in eXist-db without using the authenticate function?
No, this is not possible: eXist-db does not work with hashes on the authentication functions, that would be a security risk since MD5 is not safe. In addition, eXist-db does not use MD5 internally for hashing the passwords, so validating a password would be difficult (matching two different hashing techniques is impossible)
Unfortunately there is no way to work around this with the standard functions.
Related
I'm writing a program and before it loads I want the user to enter the correct password without storing the password anywhere in my code. I've implemented MD5 hashes before but from what I've read they're outdated and can be broken. There are a few sites out there that attempt to reverse engineer and MD5 hash. What's the strongest encryption I can use to keep prying eyes out of my program (e.g., The NSA)?
"Encryption" is not the right thing to do for storing user passwords - as by design an encrypted password can be decrypted. As you said - hashing is the way to go.
MD5 is outdated, and I believe the current recommendation is sha1.
Note that there are ways to reverse any hashing algorithm to acceptable input. The commonly accepted standard to make this much more dificult is to add a unique "salt" to all passwords before putting them through the hashing function. A common mistake made when adding salts to passwords is to use the same salt value on every password in the database.
When salting passwords, use a unique value, for example the user ID, or the created date/time string for the user record. This will prevent attacks based on rainbow tables because there will be no existing ready to use rainbow table for your stored password hashes.
I personally like the approach of using the created date / time string of the user as it's a value that should never change and will be available and will likely be different for each user the the database.
Eexamples below assume you are familiar with PHP - however the concepts can be applied to any language.
Example:
Before saving a new user into the database:
$date = date('Y-m-d H:i:s');
// save this same value into the user record somewhere
$passwordHash = sha1($user['created_date'].$_POST['password']);
// and save the $passwordHash value into the password field for that user
To authenticate a login attempt, use something like the following:
function authenticateUserLogin($email, $password) {
$user = $db->fetchRow('SELECT * FROM users WHERE email=?', array($email));
if (!$user) return false;
$passwordHash = sha1($user['created_date'].$password);
return $user['password_hash'] !== $passwordHash;
}
To update an existing users password, use something like...
$passwordHash = sha1($user['date_created'].$newPassword);
$db->query('UPDATE users set password_hash=? WHERE id = ?', array($passwordHash, $user['id']));
i have a mysql query as below :
select * from users where email='xxx#xxx.com' and password = SHA1(CONCAT(SHA1(SHA1("123456")),salt))
i want to convert to cake PHP find using beforSave Function :
public function beforeFind(array $queryData) {
if(isset($queryData['conditions']['User.password'])) {
$queryData['conditions']['User.password'] = 'SHA1(CONCAT(SHA1(SHA1("'.$queryData['conditions']['User.password'].'")),User.salt))';
}
$this->log($queryData);
return $queryData;
}
the mysql query is run okie but in cakephp find this not work.
Thank for help.
Don't include plain-text passwords in your queries!
You should never do this; you're including plain-text passwords as part of your query and including your 'salt' values as readable string as well.
SQL queries may be logged (and backed up), so those log files can contain all this information in readable format!
You should 'hash' the password using PHP and use the hashed password to query your database
Hashing passwords via the AuthComponent
First of all, if you're using the AuthComponent, CakePHP will do all this kind of actions automatically; it will look up/identify a user and (if correct) allow you to log-in that user.
See: Authentication
To encrypt passwords 'manually', use AuthComponent::Password() or Security::hash()
I'm in a hurry right now, but if you need more information or an example, place a comment, then I will add that information
If I have understood your problem correctly then you want to search for a user with given username and password. You don't need to use beforeSave for this. If you want to encode password then surely you could use beforeFind or IMO you can do it in a single line itself, just before you execute the query.
You can use Cakephp find by query method. Something like this $this->Users->query("your mysql query"); or if you want to use normal find, that would also work.
$user = $this->Users->find('first', array(
'conditions' => array('Users.email' => $email, 'Users.password' => $password)
));
Hope that helps.
I have a pointer to TLS certificate and I need to get commonName property;
I at first create X509 object with function d2i_X509 like ;
x = d2i_X509(NULL, &p, certificate_lenght);
if (x == NULL)
return https_failure;
Than I call function X509_NAME_get_text_by_NID for getting commonName
X509_NAME_get_text_by_NID(X509_get_subject_name(x),NID_commonName, hc->https_domain_name, 256);
It works for me but I am worried about performance . I think, all certificate object is parsed when I only need commonName . Is there any better method for getting commonName with more efficiency .
There is no more efficient way using OpenSSL high-level API. If you are really interested in having the best performance possible, you'll need to use the low-level ASN.1 parsing API.
But keep in mind that you cannot fully validate a certificate without parsing it entirely, so I would be concerned with the security implications of only extracting the CN.
I'd like to store some trivial values for each user in the database, like if the user can see the new comers' banner, the instruction on how to use each of the features etc. The number of values can increase as we come across new ideas.
So I've thought about two solutions for storing these data. Either having a field for each of these values (So the structure of the table will change a few times at least), or have one field for all these types of data, so they're stored as a dictionary in the field (In this case, I'm worried about if it's hurting db performance, I also need to write more logics for parsing the dictionary in string and the way around, and if storing dictionaries in db contradicts with what db does).
models.py
class Instruction(models.Model):
user=models.ForeignKey('auth.User')
can_see_feature_foo_instruction=models.BooleanField()
can_see_feature_bar_instruction=models.BooleanField()
...
or
class Instruction(models.Model):
user=models.ForeignKey('auth.User')
instruction_prefs=models.CharField() #Value will be "{'can_see_foo_inst':True, 'can_see_bar_inst':False, ...}"
Which will be the best solution?
It depends if you need to be able to search on these fields. If so, the text field option is not really suitable, as the individual flags won't be indexed. But if not, then this is a perfectly good way of going about it. You might want to consider storing it as JSON, which is useful as a method of serializing dicts objects to text and getting them back. There are plenty of implementations around of "JSONField" in Django that will take of serializing/deserializing the JSON for you.
Django has a built-in permission system. Try reading this link https://docs.djangoproject.com/en/dev/topics/auth/#permissions
Update
I think if you really want to use an Instruction model. You can use something like a JSONField and use it to store instructions. This way you can do something like instruction.key to access a value. You can try using this. https://github.com/derek-schaefer/django-json-field
You can create model for key value pair of instructions/permissions per user.
E.g.
class Instruction(models.Model):
user=models.ForeignKey('auth.User')
key = models.CharField(max_length=20)
value = models.BooleanField()
Then you can create multiple instances of this for each user depending upon permissions he has.
>>>> instr1 = Instruction()
>>>> instr1.user = user1
>>>> instr1.key = 'can_see_feature_foo'
>>>> instr1.value = True
>>>> instr1.save()
>>>> instr2 = Instruction()
>>>> instr2.user = user1
>>>> instr2.key = 'can_see_feature_bar'
>>>> instr2.value = True
>>>> instr2.save()
....
#To query
>>>> Instructions.filter(user=user1, key='can_see_feature_bar')
If you use a Model with a CharField to store the instruction and a ManyToManyField to the users you can create and assign any number of instructions to any number of users.
class Instruction(models.Model):
user = models.ManyToManyField('auth.User')
instruction = models.CharField() # Value will be a single instruction
I'm trying to use an app engine User object's user_id (returned by the User.user_id() method) as a key_name in my own User class. The problem is that it keeps telling me that it's an invalid key_name. I've tried sha2'ing it, and using the digest() as well as the hexdigest() method to reduce the number of possible characters, but still no good result. Is this because the value is too long, or because key names can't have certain characters? And also, how can I modify a user_id in such a way that it stays unique, but is also usable as a key_name for an entity? Extra bonus if it uses a hash so that thje user_id can't be guessed.
Here is the code where the error occured:
def get_current_user():
return User.get(db.Key(hashlib.sha1(users.get_current_user().user_id()).hexdigest()))
I'm now doing some more testing, concidering suggestions from the comments and answer.
I'm not sure why it isn't working for you, the following has no issues when I run it in the dev console.
from google.appengine.ext import db
from google.appengine.api import users
user = users.get_current_user()
name = user.user_id()
print db.Key.from_path ('User', name)
However if you are hashing it (which it sounds like you may be), be aware that you may get a collision. I would avoid against using a hash and would consider some other means of anonymization if you are giving the key to clients. Such as another model whose key you can give away, that has the user's key stored in it. Another method would be to encrypt the id (using the same key for all users) rather than hash it.
If you are doing something that generates binary data (encryption / hash digest) app engine (the sdk at-least) has issues, so you need to encode it first, and use that as the key_name.
name = user.user_id()
hashed_name = hashlib.sha1(name).digest()
encoded_name = base64.b64encode (name)
db.Key.from_path ('User', encoded_name)