I have a simple web app that has a login page, the front end domain has a simple model with:
string username {get;set;}
string password {get;set;}
However it is encrypted with sha256 before it is sent over to the data domain object, originally the data domain was:
string username {get;set;}
string password {get;set;}
So I would take the password from the ui, encrypt it then using the Encoding.GetString() method, get back a string for persisting. However when I try to persist the data it just seems to give an exception, which I believe to be down to the characters in the string not being valid.
After looking around some people have recommended storing it as a varbinary(32) and using a byte[] password {get;set;} within the data layer, however I couldn't get Nhibernate to map it correctly.
So can anyone tell me the best practise on storing hashed passwords with Nhibernate and SqlServer or MySql. (The app supports both dbs)
You shouldn't use Encoding.GetString() on a SHA value since it will produce text that may not store correctly, or worse, give an exception. Rather use something like Convert.ToBase64String.
Related
can someone explain me this please? It's about AspNetUser, when we create a table, it generates an id in string, but how good is it? Isn't it bad in terms of security? Because if I want to show something only with one user, I need to compare my id (int) with id (string), I know it's simple and possible but I just need to convert the int to string, but is this method safe?
I was trying this and it worked but i'm comparing a string.
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var plans = _unitOfWork.Games.GetAll().Where(p => p.UserId.Equals(userId));
return View(plans);
The AspNetUser is a part of ASP.NET Identity, which is a framework that provides authentication and authorization services. The Id column of the AspNetUser table is typically generated as a string (GUID) to ensure that it is unique across all users. Comparing the user ID as a string with another string value (such as the value from ClaimTypes.NameIdentifier) is not a security issue. The string comparison is a simple and efficient way to retrieve the data for a specific user. Converting the user ID to an integer would not provide any additional security benefits, but it may impact performance if the integer comparison involves a large number of operations.
Refrence link:
https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.claims.claimtypes.nameidentifier?view=netframework-4.8.1
Also :
What are the best practices for using a GUID as a primary key, specifically regarding performance?
I just started playing with Grails and working on simple registration/login feature.
I have this simple domain object:
class Person {
String firstName, lastName, email
String login, password
static constraints = {
firstName nullable: true
lastName nullable: true
}
static mapping = {
password type: GormEncryptedStringType
}
}
I am saving Person object just fine. But then when I try to retrieve it for login purposes using Criteria API, it won't find it:
def criteria = Person.createCriteria()
def person = criteria.get {
and {
eq("login", params.login)
eq("password", params.password)
}
}
If I remove eq("password", params.password) or change it to something not encrypted it works just fine. Anyone have an idea how to handle that?
You're doing it wrong (security). You don't encrypt passwords, you hash them. Hashing is one-way and lossy, whereas encryption is two-way and lossless, but if you can decrypt the passwords then you're vulnerable to attackers who gain access to the decryption keys, and then they'll be able to decrypt them too.
If you use hashing, then you can (but of course shouldn't) let anyone view the hashed passwords because they're useless if you use a good hashing scheme. Bcrypt is one of the best and is easy to use.
Instead of decrypting the stored encrypted password to verify a cleartext password from a user authentication attempt, you should hash the supplied password and validate it against the stored hashed password. For some algorithms this is a simple as checking that the values are the same, but that's not the case with Bcrypt since the algorithm always generates a different hash for each invocation. But the algorithm can validate two hashed passwords, so that's not a problem.
So the real fix to your problem is to stop using encryption, and stop 'rolling your own' security. spring-security-core is a popular option.
I know how to save documents to the RavenDB but i'm trying to look in to how I can save a User object:
public class User
{
public string Username {get;set;}
public string Password {get;set;}
public string Email {get;set;}
}
Sure, I can save an object of User but, what about Password encryption? And is there a "proper" or a different way of saving a User object? Saving and Retrieving a User object is my whole goal.
Any help is highly appreciated.
Password encryption you'd have to implement yourself. See an example here:
https://github.com/synhershko/NSemble/blob/master/NSemble.Web/Modules/Welcome/WelcomeModule.cs
https://github.com/synhershko/NSemble/blob/master/NSemble.Core/Nancy/NSembleUserAuthentication.cs
The User object is not different than any other object in your system.
I have a simple post method in a MVC controller that checks whether the ModelState is valid then calls another method passing an instance of the model as a paramter. This model contains sensitive data that is easily obtained by looking at Fiddler. My goal is to somehow mask or encrypt this data so that it cannot be seen in an http trace.
I have seen posts suggesting to use Session or Temp variables but that is not an option in my case.
This is what the code looks like:
[HttpPost]
[ActionName("Search")]
[AccessControl(Xri)]
public ActionResult SearchPost(string string1, ViewModel model)
{
model.NoResults = false;
if (ModelState.IsValid)
{
if (ModelState.IsValid) return RedirectToAction("TargetAction", model);
}
}
[AccessControl(Xri)]
public ActionResult TargetAction(string arg, ViewModel viewModel)
{
.
.
.
}
Fiddler shows the following:
/TargetAction?id=01010101&date=08%2F14%2F2013%2000%3A00%3A00&To=08%2F21%2F2013%2000%3A00%3A00¶m1=somevalue¶m2=somevalue2
Is there a way to mask the url parameters shown here?
You're going to need to get SSL running on your server.
Without a server certificate from a trusted authority, there is very little you can do to encrypt the data over the wire. Why? Because you'd need to send encryption/decryption details in clear text before you start sending the data so that your client (likely JavaScript) could decode it.
Using a certificate and operating on 443 gives you built-in functionality from the server/browser that is hard to beat in a custom implementation.
If you just want to obscure the data (and put it beyond the level of most web users) you could always base64 encode the data, rather than encrypting it. Just be clear that you are NOT encrypting data and it is still possible to decode it. This approach is not a form of encryption.
If you decide to take that approach regardless, here are a few resources:
Client-side Encoding/Decoding
MSDN Reference on Encoding to Base64
Cheers.
You have two options for doing this:
Store the data on the server and give the user a token (e.g. a GUID) to pass along to retrieve the data. Since using the Session or TempData is not an option, you could store the viewmodel in the database, and then redirect the user with the token in the URL to retrieve it on the next request.
The other option would be to have the user pass the viewmodel in the URL as you're currently doing, but pass it in an encrypted format. For example, you could
serialize the model to JSON, encrypt it using one of .NET's built in encryption algorithms, and then redirect to the next action passing the encrypted string as your view model. Then you could change the target action to something like:
[AccessControl(Xri)]
public ActionResult TargetAction(string arg, string encryptedViewModel)
{
var decryptedString = Decrypt(encryptedViewModel) ; // supply the decrypt function to match your encryption
var viewModel = JsonConvert.DeserializeObject(decryptedString);
}
Today I upgraded the spring security version of the application I'm working on from 3.1.3 to 3.1.4, and I noticed a deprecation warning on the org.springframework.security.authentication.encoding.ShaPasswordEncoder class.
So I switched to the new org.springframework.security.crypto.password.StandardPasswordEncoder implementation.
I had it working and I'm able to register a new user and login in my application, but, as I feared, I'm not able to login using passwords generated with the previous ShaPasswordEncoder and my custom salt.
Since I have a database with many users already registered, what should I do to switch implementation without invalidating the old encoded passwords?
Is it even possible?
See also: How to use new PasswordEncoder from Spring Security
If you want to switch to a more secure password encoding mechanism, then I would recommend you use BCrypt. I would use something like this to migrate your users:
// Implement the old PasswordEncoder interface
public class MigrateUsersPasswordEncoder implements PasswordEncoder {
#Autowired
ShaPasswordEncoder legacyEncoder;
#Autowired
JdbcTemplate template;
BCryptPasswordEncoder bcryptEncoder = new BCryptPasswordEncoder();
#Override
public String encodePassword(String rawPass, Object salt) {
return bcryptEncoder.encode(rawPass);
}
#Override
public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
if (legacyEncoder.isPasswordValid(encPass, rawPass, salt)) {
template.update("update users set password = ? where password = ?", bcryptEncoder.encode(rawPass), encPass);
return true;
}
return bcryptEncoder.matches(rawPass, encPass);
}
}
You can check what proportion of users have been migrated by the format of the password field. BCrypt strings have a distinctive syntax beginning with a $ sign.
One of the other answers points out that this code could accidentally update multiple passwords at the same time. The question stated that a custom salt was being used, so the chance of collisions is negligible if the salt is randomly chosen, but this might not always be the case. If two passwords were updated, what would the problem be? It would then be possible to detect that accounts have the same password from the bcrypt hashes. That's the case anyway since it requires that the SHA hashes were the same for the update to occur. If you think it might be a problem (e.g. because of poor salt choice or even the use of unsalted hashes) it would be trivial to modify the SQL to detect this and perform multiple updates with separate BCrypt hash values.
I tried to add a comment to the accepted answer, but alas, I don't have enough cred yet. :(
I believe the accepted answer's code snippet is potentially dangerous where it updates the password in the database. If the ShaPasswordEncoder produces the same results when encrypting (which is why the assumption is being made that the old password can be found, and I verified this is definitely true at least with a null salt on the ShaPasswordEncoder), you still cannot guarantee that the password is unique amongst all users. You could, by chance, share the same password as another user on the system, and that SQL code would end up changing all users that happen to have your password.
I think the safest strategy is to not update the user's password, and instead provide a migration strategy that plans for the eventual removal of the ShaPasswordEncoder.
Use the provided example code.
Remove the code that updates the database.
Add a feature like, "Forgot your password" or "Generate a new password" to handle the eventual case of users not having created a new password when the ShaPasswordEncoder is removed. Like either when you upgrade to Spring Security that has it removed, or choose to remove it yourself.
Update your documentation or make it clear that in the next major release version of the software, that users will have had to re-save their passwords or will have to use the before-mentioned password reset feature.
Give the user the grace period of a major version release cycle to transition (they probably won't do it and just get caught in the reset password).
That's an excellent question and am looking forward to reading some answers.
AFAIK it's impossible to do in a single mass update: you just can't retrieve the original string from a hash. You would have to check during a login attempt if the submitted password matches either strategy and convert it to the new strategy if necessary, but that means you would have to live with both encoding strategies until all users have logged in and hence all passwords have been converted. Not very convenient nor necessarily intuitive for new developers coming on board.
I move to implement class PasswordEncoder
org.springframework.security.crypto.password.PasswordEncoder
This solution help me to fixed deprecated PasswordEncoder.
Code:
public class LegacySupportPasswordEncoder implements PasswordEncoder {
private final BCryptPasswordEncoder bcryptEncoder;
private final JdbcTemplate jdbcTemplate;
#Autowired
public LegacySupportPasswordEncoder(#Qualifier("passwordEncoder") final BCryptPasswordEncoder bcryptEncoder,
final RoutingDataSource dataSource) {
this.bcryptEncoder = bcryptEncoder;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
#Override
public String encode(CharSequence rawPassword) {
return this.bcryptEncoder.encode(rawPassword);
}
#Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
//Your code validate credential in database here
return this.bcryptEncoder.matches(rawPassword, encodedPassword);
}
}