I have a table column called salt and it is a required field but I don't want to users to input their own salts
is there a way for our system to generate a salt for each password which are encrypted via sha1?
You are using Yii, so lets do this in YII style
I use
Yii::app()->securityManager->generateRandomString($length,true)
To learn about it click here
The Yii framework offers a class CPasswordHelper, which generates safe BCrypt hashes with an included salt per password. With this class you can do without a separate field for the salt. An example from the Yii docu:
$hash = CPasswordHelper::hashPassword($password);
if (CPasswordHelper::verifyPassword($password, $hash))
// password is good
else
// password is bad
You can use a random value for each entry as a salt. It doesn't matter what the value is as long as it looks random.
Check this link :
https://crackstation.net/hashing-security.htm
Use simplest encrypt & decrypt info in PHP
$salt ='whatever_you_want';
function simple_encrypt($text)
{
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
function simple_decrypt($text)
{
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $salt, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
Related
While developing a multi-tenant app with ASP.NET Core I noticed that it brings 2 new indices: NormalizedUserName & NormalizedEmail.
The main problem is that it gets too difficult to have a unique user per tenant.
What I mean is having multiple users with the same UserName & Email but different TenantID.
In order to achieve this I have to remove those indices
public static void RemoveIndexes(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<ApplicationUser>(entity =>
{
var normalizedUserNameIndex = entity.HasIndex(u => new { u.NormalizedUserName }).Metadata;
entity.Metadata.RemoveIndex(normalizedUserNameIndex.Properties);
var normalizedEmailIndex = entity.HasIndex(u => new { u.NormalizedEmail }).Metadata;
entity.Metadata.RemoveIndex(normalizedEmailIndex.Properties);
});
}
My questions are:
What is the purpose of these 2 new indices?
What would it affect if we just remove them?
Is there anything we need to pay close attention to after removing them? (e.g. overriding default UserManager functionality or something to that effect)
First of all, I wouldn't change anything of the Identity Framework if I can't oversee the effects. If you insist, you can test what happens yourself. But, do you need to remove the fields?
If the relation of user-to-tenant is one-to-many, then tenantId should not be a field of ApplicationUser but rather be stored in a seperate table, like UserClaims.
You can add multiple tenantId's as claim of the same type, like http://tenant.company.com/Id. It will then become a collection of values, like what happens with roles.
If you don't want this then you can use different claimtypes, like http://tenant.company1.com/Id, http://tenant.company2.com/Id or something like that.
You can choose to include only claims that are linked to the tenant, which could be determined from the site binding or the url, for instance.
This design allows the user to login using the same password everywhere. Please note, this is about identity: who is the user? The user doesn't need to have a different password for every tenant.
It also makes it easier to change a password. Because I wonder, how does your scenario look like with multiple user records for each tenant? Will you update all records at once when a password changes? And how will you support 'forgot password' and other features?
I have already one application built using Yii2 advance and working perfectly.
Now, client's requirement is to create new separate (but related with first) application using Laravel 5.3 and this new system must use the same database of Yii2.
A user should be able to login into both the application.
So, I'm curious is it even possible?
Any help would be appreciated.
Thanks,
Parth vora
Finally, I am able to achieve what I wanted.
So, here are the steps you need follow in your Laravel in order to login into Laravel application using auth table of Yii2:
Yii2 uses "user" name for the auth table, whereas Laravel uses "users".
So add this into your User model:
protected $table = "user";
Yii2 uses "password_hash" field to store the user password, whereas Laravel uses "password".
So add this into your User model:
public function getAuthPassword()
{
return $this->password_hash;
}
Yii2 uses "auth_key" field to store the user's remember token, whereas Laravel uses "remember_token". You also need to increase size of this field from 32 to 100, otherwise you will get an error upon logout.
So add this into your User model:
public function getRememberTokenName()
{
return 'auth_key';
}
You also need to increase the size of 'auth_key' field from 32 to 100, otherwise you will get an error upon logout.
Yii2 uses "int(11)" for created_at and updated_at field type, whereas Laravel uses "timestamp" type.
So add this into your User model:
protected $dateFormat = 'U';
Hope it might helpful to someone.
Thanks
I am trying to create a change password form in web2py. I am using db.auth_user table. I want to create a form with fields ['current_password', 'new_password', 'repeat_password']
Form should give a warning to user if the password is not entered correctly.
My code is:
request.vars.current_password = request.vars.current_password if request.vars.current_password else 'xxx'
user_password_form = SQLFORM.factory(Field('current_password', 'password',
requires=IS_EQUAL_TO(db(db.auth_user.id == auth.user_id).select('password').first().password)(
str(db.auth_user.password.validate(request.vars.current_password)[0]))),
Field('new_password', 'password'),
Field('repeat_password', 'password',
requires=IS_EQUAL_TO(request.vars.new_password,
'Passwords do not match')))
I have tested the validation for the following code and it sets a=1 if password is entered correctly. But on the form validation I couldn't figure it out how to implement it
if request.vars.current_password:
if db.auth_user.password.validate(request.vars.current_password)[0] == db(
db.auth_user.id == auth.user_id).select('password').first().password:
a=1
Any ideas how password validation can be achieved?
The web2py Auth system includes a built-in password change action. If you are using the default user action in the default.py controller, you access this form via /myapp/default/user/change_password.
If you prefer to create a separate controller action just for this purpose, you can simply do:
def change_password():
return dict(form=auth.change_password())
and in the associated view:
{{=form}}
Regarding your custom code, you cannot use the IS_EQUAL_TO validator alone, as it takes an expression that must be equal to the value submitted with the form (you cannot call the validator with a transformed value as you have, as that will return a tuple, but the requires attribute must be a callable object that takes a field and a value).
Instead, you could use the CRYPT validator followed by the IS_EQUAL_TO validator in a list -- the first validator will transform the submitted password to a hash, and the second will then test for equality with the stored password hash.
Alternatively, you could use:
def check_password(password):
new_hash = db.auth_user.password.validate(password)[0]
return new_hash == auth.user.password
form = SQLFORM.factory(Field('current_password', 'password')
requires=IS_EXPR(check_password)),
...)
The IS_EXPR validator can take a function that will be passed the value, and the function should return True or False (note, this usage is not documented -- the book only shows the alternative usage, where you provide Python code as a string, which will be exec'ed).
I have a Laravel 4 app in which I have set up one user. In my login route I'm calling Auth::attempt with the email and password but it always comes back as false. I definitely have the password correct and the correct hash in the database as Hash::check returns true.
I think it may be due to using email as the login field instead of username, but I can't see any setting for that. This question implied you could add an option to config/auth.php but it didn't work. This question says to use username as the array key, but then I get SQL error because it tries to select on a username field in the database.
Do I need to add something to the User model to specify the username field? Here is my login route:
Route::post('login', function() {
// data from login form
$credentials = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
$auth = Hash::check(Input::get('password'), Hash::make('mypass'));
var_dump($auth); // this is TRUE
// login was good
$auth = Auth::attempt($credentials);
var_dump($auth); // this is FALSE
});
I found the problem. As suggested by Jason in the comment above, I had modified the models/User.php file and removed some functions that I didn't realise were necessary.
The getAuthIdentifier() and getAuthPassword() methods must be included in the User model for authentication!
In app/config/app.php make sure you have the 'key' set. This made me pull my hair out. Everything will apear to work, password seems hashed in the DB, but it will always return false until you set this key and re-hash your password into the DB.
"php artisan key:generate"
Had the same problem and made me sweat for hours. Definitively check your User.php model and make sure you have not overwritten the default one. Thanks Jason!
This post is kindo of asking what I need but not very well... How to encrypt password
Essentially I have a model "User"
Public Class User
Public Property ID As Integer
Public Property NickName As String
Public Property EmailAddress As String
Public Property Password As String
End Class
I want to be able to do something like this....
Public Class User
Public Property ID As Integer
Public Property NickName As String
Public Property EmailAddress As String
Public Property Password As String
Get
Return Password
End Get
Set(value As String)
Password = DoMyHashing(value)
End Set
End Property
End Class
Is there any way to do this simply?
EDIT : I have since started using BrockAllen.MembershipReboot which uses the federated identity system. It's much better than membership provider in my opinion!
Security is not something that should be taken lightly and even better not reinvented. Simple doesn't necessarily mean secure. So you could use the existing membership provider which already implements security for you and stores only hashed versions of passwords in the database.
And if you don't want to use the membership provider but implement password hashing yourself, here's a good guide you might consider going through before getting into coding.
Here's a secure way to generate password hashes:
To Store a Password
Generate a long random salt using a CSPRNG.
Prepend the salt to the
password and hash it with a standard cryptographic hash function such
as SHA256.
Save both the salt and the hash in the user's database
record.
To Validate a Password
Retrieve the user's salt and hash from the database.
Prepend the salt
to the given password and hash it using the same hash function.
Compare the hash of the given password with the hash from the
database. If they match, the password is correct. Otherwise, the
password is incorrect.