Genexus Authentication without using Genexus Access manager - genexus

I want to implement authentication in Genexus customly. Is there any way to implement authentication in component without enabling Genexus Access Manager(GAM)?

Of course you can manage by yourself and saving the encrypted passwords in your DB manually.

I suggest you store the passwords hashed and not encrypted for security according to OWASP Password Storage Cheat Sheet
Here is an example of how to hash with SHA512, but you can choose from all options in CryptoHash:
Parm(in:&PassWord, out:&HashSHA512);
&CryptoHash.Algorithm = CryptoHashAlgorithm.SHA512
&Digerido = &PassWord.Trim() // you can add salt here
for &i = 1 to 10 //number of iterations in hashing
&Digerido = &CryptoHash.Compute(&Digerido)
endfor
&HashSHA512 = &Digerido.ToUpper()
So basically you use this proc to hash your password and store it in the database, and when the user logs in, you use the proc to get the hash and you compare the hash with the one stored in the database.

Related

Is it possible to encrypt data in Laravel with APP_KEY which differ per user?

I'm using the Laravel framework to encrypt almost all data in a MySQL database. This is a requirement, due to privacy concerns.
Laravel uses an application specific APP_KEY as the main key to handle encryption and decryption (OpenSSL / AES-256-CBC cipher).
I wonder: Is it easy (or is there a package) to generate an APP_KEY on a user base? So each user get's an APP_KEY (f.e. USER_APP_KEY) to handle all user specific data?
I think this adds an extra security layer. So even if the data is stolen and one user is somehow decrypted, the rest of the data remains useless to the attacker.
Or am i overcomplicating things and is a single APP_KEY safe enough?
Already tried:
Search for existing packages for Laravel framework.
Generic Google search for examples.
Yes you can generate the key for every user and store it into the users table.
Following code sample is to generate a key.
'key' => encrypt($this->generateRandomString(16))
private function generateRandomString($n) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for ($i = 0; $i < $n; $i++) {
$index = rand(0, strlen($characters) - 1);
$randomString .= $characters[$index];
}
return $randomString;
}
When you need to decrypt the content, you can do it as follows.
$encrypter = new \Illuminate\Encryption\Encrypter($key);
$decrypted = $encrypter->decrypt($encryptedContent);
For additional security, I suggest you to encrypt the user based key using APP_KEY.
Then store encrypted key in the database.
When decrypt, you need to decrypt the key first. After you can decrypt the content using user based key.
Then some one need to get the content need to know both two keys which are user key and app key.
Hope this helps.
Decided to go with a single APP_KEY. There's is no package that i'm aware of that handles this. And based on the comments, it doesn't do any good in terms of security.

What is the difference between the key and hash key parameters used in a Redis put() statement?

I have a Java Spring Boot app that uses Redis for storage. I have done a fair amount of web searching but I can't find an easy to digest text that explains in detail the ramifications of what values to use/choose for the key parameter vs. the hash key parameter in a Redis put(key, hash key, object) statement. I am using the Redis store to store a short-lived session management objects that are particular to a specific user ID, and that user ID is guaranteed to be unique. The object value is a JSON encoded string for a particular class object:
// String format template for storing objects of this class.
public static final String STORE_MULTI_SELECT_CHOICES = "%s:store:multi_select_choices"
// Store it in Redis for access during the next interaction with the user.
// The key is the hash key prefix for the MultiSelectChoices class, followed
// by the user ID.
String key = String.format(MultiSelectChoices.STORE_MULTI_SELECT_CHOICES, userId)
// The hash key is just the user ID for now.
String hashKey = userId
// Serialize the multi-select session management object to a JSON string.
Gson gson = new Gson();
String jsonRedisValue = gson.toJson(multiSelect);
redisTemplate.opsForHash().put(key, hashKey, jsonRedisValue)
What is the difference between these two parameters and do you know of a document that explains the performance and value collision ramifications of different choices? Also, given the nature of my storage operation, do I need to worry about Redis shards or other expert level details or can I reasonably ignore them for now? The app once put in production, will face a high traffic load.
basically in your scenario:
your key is: userid:store:multi_select_choices
your hashkey is: userid
and your options objects serialized into jsonRedisValue
in this case, you don't need to use:
redisTemplate.opsForHash().put(key, hashKey, jsonRedisValue)
instead you should use:
redisTemplate.opsForValue().put(key, jsonRedisValue)
here is a very good example for you to understand the scenario where opsForHash making sense:
first you must understand that hashes in redis is perfect representation for objects, so you don't need to serialize the object, but just store the object in the format of multiple key-value pairs, like for a userid=1000, the object has properties: username/password/age, you can simply store it on redis like this:
redisTemplate.opsForHash().put("userid:1000", "username", "Liu Yue")
redisTemplate.opsForHash().put("userid:1000", "password", "123456")
redisTemplate.opsForHash().put("userid:1000", "age", "32")
later on if you want to change the password, just do this:
redisTemplate.opsForHash().put("userid:1000", "password", "654321")
and the corresponding cmd using redis-cli:
HMSET userid:1000 username 'Liu Yue' password '123456' age 32
HGETALL userid:1000
1) "username"
2) "Liu Yue"
3) "password"
4) "123456"
5) "age"
6) "32"
HSET userid:1000 password '654321'
HGETALL userid:1000
1) "username"
2) "Liu Yue"
3) "password"
4) "654321"
5) "age"
6) "32"
I haven't explore too much the fundamental of how it implement hashes operation, but I think the difference between key and hashkey is quite obvious based on the documentation, key is just like the other redis key, normal string, hashkey is for the purpose of optimize the storage of the mutliple key-value pairs, so I guess there must be some kind of hash algorithm behind to ensure optimal memory storage and faster query and update.
and it's well documented here:
https://redis.io/topics/data-types
https://redis.io/topics/data-types-intro
You are basically talking about two different redis operations, I don't know the specific answer for spring boot, but talking about redis, the hashkey is needed for a HMSET operation, that basically is a two-keyed key-value store, while the regular SET operation is the singl-eyed key-value.
Check the operations in REDIS commands

Laravel & Meteor password hashing

I have two applications, one in Laravel 5.2 and one in Meteor. I want to collect hashes for passwords which are compatible with both platforms.
The database stores the hashes separately
password for Laravel.
meteor_password for Meteor.
Both platforms use bcrypt with 10 rounds by default, but Meteor appears to sha256 the plain password before bcrypt.
If Meteor creates password hash abc, I can sha256 the plain password, and compare it with abc using Laravel's internals, i.e. Auth::attempt()
$sha256 = hash('sha256', $request->get('password'), false);
This works. Laravel successfully authenticates the user.
However, if I register a new user in Laravel, and store the hash meteor_password, when authenticating against that hash in Meteor, it fails with the error message "Login Forbidden". This error appears to be mean incorrect credentials.
I'm creating the hash in the same way as I did when I verified it in Laravel.
$meteor_password = bcrypt(hash('sha256', $plain, false));
It seems strange that it'd work one way and not the other so I assume I'm missing something.
In 2011, a bug was discovered in PHP's BCrypt implementation, so they changed the original 2a version indicator to 2x and 2y, which is used today, to indicate that the password was hashed by the fixed version.
Therefore, the hash generated by PHP's 2y should be identical to the one generated by node's 2a.
The prefix should be changed in order to be correctly processed by the NPM module (used by Meteor), as it does not acknowledge 2y.
$meteor_password = bcrypt(hash('sha256', $plain, false));
// replace it useing something like:
$meteor_password = str_replace('$2y', '$2a', $meteor_password);
// or
$meteor_password[2] = 'a';

Password history to prevent user to keep same passwords again and again

I am developing an application in PHP Laravel. It uses bcrypt encryption to store passwords. I want to keep the history of hashes whenever the user changes the password. By doing this I want to stop user entering the previous passwords in some scenarios. Is it safe to keep the history of hashes?
I am using built in functions. I do not know much about this encryption. According to my observation, if a user changes his password and keep the same as a previous one, the hash values come different. How can I stop him to keep the same password from the previous history? Is it possible while using bcrypt encryption?
Yes that's totally safe. You can compare the new password with your older hashes using Hash::check(). For example like this ($hashes being an array of old hashes)
$newPassword = 'secret';
foreach($hashes as $hash){
if(Hash::check($newPassword, $hash)){
exit('Sorry can\'t use the same password twice');
}
}
there is a laravel package for it called laravel-password-history
which you can install and enjoy.
it provides you with event listeners, migrations, validation rules, etc. it is also configurable to check for a certain depth in the history.

How to store a RijndaelManaged generated KEY and IV in the database for later use?

Let me start by saying....yes I have read tons of posts on here in the last two days. No, I don't know anything about encryption, so don't bother...with the you shouldn't playing with fire comments..
I have a asp.net MVC3 application and want to encrypt the photos that users upload using a key for each user. I want to save this key and use it for any further uploads by the same user and for the decryption. (Although, I suppose I could store a key for each photo instead, not really relevant to this problem but...)
I started with the code from here:
http://www.codeproject.com/Articles/33344/Photo-Video-Viewer-with-Encryption-Capability
It works fine. It encrypts the photos and decrypts them to a new file and all is well. The "on the fly version" also works and returns a MemoryStream that I can use for my WebImage. However, as you can see the example is encrypting and decrypting in one pass and the key is a global variable (I don't know what it was, I just used the autogenerated key when I tested.
So, I need someone to tell me how to store the generated key (and IV I guess??? Told you I know nothing about enc...) in the database for each user and then pull that (those) value(s) back out to use for on the fly decryption. I am not going to bother to post all my code yet, as it is almost identical to what is on the above site.
I read another post on here and it said to use:
string x = Convert.ToBase64String(RMCrypto.Key);
Then when I wanted to decrypt I used:
RMCrypto.Key = Convert.FromBase64String(x);
I stored both the key and IV in this manner in my SQL DB, but when I pull the values and try to decrypt I get an error that the data is not the expected length.
Maybe I'm totally off base or maybe it's three lines of code... Please let me know if more information is needed.
Thanks!
You can store them as binary columns values. That being said the protection of encrypted data is only as safe as the key protecting it. In other words storing the key with the data your protecting is sorta fox guarding the hen house kind of thing. But if your not worried about it for things like PCI compliance then it's probably not too bad a deal.
How you might convert it to binary
private void UpdateDb(byte[] key, byte[] iv)
{
using (SqlConnection db = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("insert into (key, iv) values (#key, #iv)", db))
{
db.Open();
cmd.Parameters.AddWithValue("#key", key);
cmd.Parameters.AddWithValue("#iv", iv);
cmd.ExecuteNonQuery();
}
}
To make it a little harder you could generate a new key and IV for each record (image) your protecting and then store that so that if someone we're to get one key at least they wouldn't have all your data wide open. Good luck!
You should store the actual byte arrays (yes; both key and IV) in the database.
You don't need strings at all.

Resources