Generate password reset token through UUID - java

I am looking for mechanism to generate random unique alpha numeric key for resetting user password.
I've goggled a lot in this direction, but looks like this thing is not obvious thing.
I've tried something like that:
new String(encodeBase64URLSafe(UUID.randomUUID()));
But after reading the following article: Is UUID.randomUUID() suitable for use as a one-time password? looks like that this way is not fully correct.
It would be really appreciate if you answer on the following questions:
Which is secure way to generate such token using UUID?
Do we need to convert UUID string to base64 in order to have safe URLs or it would be enough to remove dashes from generated string?
Would be it correct to use mechanism from this link in such purpouses How to generate a random alpha-numeric string?, why?

Using an UUID is safe and secure. The linked article just says that an UUID is maybe a little too much for this kind of security. But well ... if you are "too" secure, no one will blame you.
An UUID is just alpha numeric characters and dashes. So if you need to put it in a query string or an URL, you have nothing to escape. You can remove the dashes to save some space if you want. But it is not required.
This mechanism is secure too. Both (UUID and this one) will works.
For this kind of security, all you have to do is to ensure that your token is randomly generated (even partially).

Related

Convert string to specific int

I am creating foreground notification with ID like so:
startForeground(1, notification)
When initialising the service I am sending to it some string (ex: Hello). I wish that the service and notification will be bind to this string so I wish to use it as my id. So, how can I convert string to unique ID? For example the word "Hello" will always generate 123 And the word Bye will always generate 456.
That sounds like you want a "Hash Code"; a value derived from some other information that is (hopefully, but not always) unique.
There are a lot of different algorithms available to do this and if you search for "hash code" you will find lots of them (especially in the security domain; sha, md5 etc)
However,
It sounds like you may not really need to get that complex (some of the more secure and "unique" hash code algorithms can be slow to calculate).
Is there any reason why you can't use the string itself?
String comparison may be slow, but maybe not as slow as a good hash. Also you might be able to use a Hash Table if you need a faster "lookup".. hashmap
Anyway, if you really do need a hash code from a string, a quick search found this (which looks reasonable) Sam Clarke; Kotlin Hash Strings

Appengine ID/Name vs WebSafeKey

When writing the endpoints in java, for finding items by their keys, should I use the Id or the webSafeString of the key? In what situations does this matter?
It's up to you.
Do the entities have parents? Then you probably want to use the urlsafe representation as a single string will contain the full path to the entity. If you used an ID instead - you would somehow need to manually include the IDs of all parents up to the root.
No parents & IDs are numeric / alphanumeric? Then just use the IDs as they look cleaner (again, this is not a rule and is completely up to you).
No parents but IDs have special characters in them? Use the urlsafe representation as you might have issues with not being able to use some special characters without encoding them in HTTP.
Note #1: the urlsafe representation have the entity names encoded that can be easily decoded, this is unlikely a privacy issue but you still should be aware of it. The actual data (IDs) are also simply encoded and can be easily decoded, so be careful when you use personal information such as emails as IDs, they are not safe with urlsafe.
Note #2: if you decide to change the structure of your data in the future (parents <-> children), you might get stuck with some urlsafe data you issued to your users who are not aware of the changes you might have done.

Alternatives for #formula annotation or sql decrypt function

I have an issue with the #Formula annotation in Hibernate when I'm trying to decrypt a password column (PWD_COL) using a key (which is retrieved from a properties file)
The code:
#Formula("decrypt(PWD_COL, '" + MyKeys.DECRYPT_KEY + "')")
private String myPwd;
I am trying to get the DECRYPT_KEY from another property file.
I am getting an error:
The value for annotation attribute Formula.value must be a constant
expression
Alternately, is there a way to mimic the SQL decrypt function in Java?
Note: Please read the password field as just another value. The eventual purpose of this exercise is for something far less important but nevertheless needs to be encrypted.
I know that this is not what you are looking for but let me give you a advice about store password on database, maybe you should change your mindset about how to work with passwords.
You should not decrypt passwords on database because security reasons, so if someone lost password they should create a new one.
To validate login and related tasks you should take the password from the form, encrypt it and compare with the encrypted on in database.
If you really want to keep doing in this way use #formula with valid sql values.
The value of a #Formula annotation has to be valid SQL since it is passed more or less directly to the underlying DB.
This also explains why your idea won't work - the DB will have no notion of the MyKeys class.
You could insert the key in a DB table and select it from there in the #Formula but security-wise that might not be a particularly sane idea...
What you really should be doing (or actually not doing) is to avoid storing passwords, but rather store hashes of passwords and then compare those hashes with the hash of whatever credentials your user presents. That moves encryption/hashing to Java/memory and avoids the embarassment when somebody steals your database, guesses the weak password or bruteforces the encryption and posts it all on pastebin!
Cheers,

Different hashCode for the same string?

I have made a log-in screen and want to check the password that a client enters with passwords in a server's database. If their HashCodes match, the password is accepted. However, the HashCode I get when I write a password on the client screen is different to the HashCode of the received string (password) on the server side.
Does anybody know why? Thanks in advance for any insight.
You've misunderstood.
You should be using a secure hash, not thehashCode() method.
You must not store the plaintext password in the database. You must store the hash.
You should be getting the database to do the hashing and comparison:
SELECT COUNT(*) FROM USERS WHERE USERNAME = ? AND PASSWORD = MD5(?)
If this query returns 1, the user and password exist. If it returns zero, they don't. Note also that you don't want to distinguish between wrong username and wrong password, as this is an information leak to the attacker. Test them both together as above.
#EJP has pointed out (correctly) that you should be using a secure hash function not Java hashCode for this.
However, the HashCode I get when I write a password on the client screen is different to the HashCode of the received string (password) on the server side.
That is a puzzle. If you are using String.hashCode() the only possible explanation is that you are hashing different strings; e.g. there could be leading / trailing white-space in one and not the other, or maybe one was hashed with a "seed" added to it. I guess, another possible explanation could be that you are hashing a StringBuffer, StringBuilder, char[] or something else.

How to create a 7 characters of alphanumeric unique id? [duplicate]

This question already has answers here:
Creating a unique alphanumeric 10-character string
(7 answers)
Closed 8 years ago.
I need to create alphanumeric unique IDs of length 7 or 10. Similar to the shorter version of Git commit IDs (7a471b2).
I tried UUID, but the generated unique ID is longer than I need.
Is there a built-in method / code snippet in Java that can help here?
If you want to generate random values you should use SecureRandom
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[15];
random.nextBytes(bytes);
To get the proper key length you may want to convert that into your expected from. The characters are also number, so you can generate longer random value and afterward just encode it. You may want to use Base64 or hext for that. In Java you use DatatypeConverter
String key = DatatypeConverter.printBase64Binary(random);
our use Apache
org.apache.commons.codec.binary.Base64
String key = new String(Base64.encodeBase64(random));
There is not Java class that support generation of random values in that form.
You did not mention whether you need the number to be generated in a state-less manner. You only need this if you have many sources generating IDs whereas each source is independent and does not know of any state of any other sources. For such a case UUID allows to generate ID's that yre still very unlikely to collide.
If you are the only source generating ID's, then you can make use of state. As an example, in a database you often simply use a sequence to generate IDs (the state being the nextval of the sequence). These numbers are perfectly unique too. If you need it to "look" random, there are algorithms to shuffle the number space by mapping each sequential number onto a random-looking number.
A second example of "state" is the set of all IDs already in use. You can use this by generating a "random" number in an arbitrarily primitive way and then matching it against all your existing numbers. If it collides, generate another one.
Try Apache lang RandomStringUtils class
This is not as simple as it looks like. First of all UUID is not 100% unique.
It can only produce 2^128 unique numbers (I might be wrong about the 128 number. But you get the idea).
Making it shorter will only increase the probability of repetition.
The best way I could think of right now is to take the UUID and use some base64 encoder over it.
[EDIT] Alternatively, use Random.nextInt and increment by one each time you need a new ID.

Categories