This week's book giveaways are in the Angular and TypeScript and Web Services forums.
We're giving away four copies each of Programming with Types and The Design of Web APIs and have the authors on-line!
See this thread and this one for details.
Win a copy of Programming with Types this week in the Angular and TypeScript forum
or The Design of Web APIs in the Web Services forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Paul Clapham
  • Jeanne Boyarsky
Sheriffs:
  • Junilu Lacar
  • Knute Snortum
  • Henry Wong
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Joe Ess
  • salvin francis

How to achieve deterministic encryption with given seed?

 
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am looking for a way to encrypt a string given a key, deterministically. Something like: Where "key" is a user input so it isn't stored anywhere, and given the same key the result will always be the same for the same string. How could I achieve something like that?
 
Saloon Keeper
Posts: 11010
243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let me first ask you: why?

Encryption should return a different ciphertext every time. If you circumvent this you will make your ciphertexts easier to decrypt and you may even compromise your secret key.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Let me first ask you: why?

Encryption should return a different ciphertext every time. If you circumvent this you will make your ciphertexts easier to decrypt and you may even compromise your secret key.


Indeed. What I am actually doing is using to encrypt the string where "hashedUserKey" is a SecretKeySpec created by a user input and to decrypt the strings.
So the program first asks the user for the key and then it uses that key to encrypt and decrypt the strings. The problem is that if another key is given that the one that was used to encrypt the string, then if i try to decrypt it, I am getting a BadPaddingException so what I am trying to do in that case is actually return something that looks like a legitimate decrypted string that it's value changes with different values of the key but always stays the same if the same key is provided. If you have a better idea, I would like to hear it of course. Thanks
 
Stephan van Hulst
Saloon Keeper
Posts: 11010
243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If decryption fails, you could convert the key to an index (in the same way a hash table works) and use it to get a word or phrase from a large predetermined dictionary.

This is going to hurt your legitimate users badly though, because they won't be able to tell when they've forgotten their password.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:If decryption fails, you could convert the key to an index (in the same way a hash table works) and use it to get a word or phrase from a large predetermined dictionary.

This is going to hurt your legitimate users badly though, because they won't be able to tell when they've forgotten their password.

Well I would have to store the dictionary in the source files so I guess it would be easy for someone to just search it.
I am pretty sure I will be the only user of the program, I don't think anybody will bother to try it from my github lol. All of this is unnecessary tbh, no hacker will have access to my computer and bother to try and crack my passwords, but I just want to build something robust for myself. I also don't have a database so he could just delete the file with the data haha. So all of this is in theory, but I am trying to find a way to do this without resorting to something stupid, like using the key for a Ceasar cipher.
 
Stephan van Hulst
Saloon Keeper
Posts: 11010
243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The best way to do this without doing something stupid is to not do it. Just display a message that the password is wrong when you get a BadPaddingException.

[edit]

After rereading my post it seems my tone could appear harsh. I assure you it's not meant that way; I've just found that in cryptography the simplest ways are often the most secure ways. Use existing solutions. Don't build anything smart on top.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah don't worry about it, thanks for the opinion. Of course I wasn't trying to invent a cryptographic algorithm or something like that, but I might as well not bother at all.
 
Bartender
Posts: 1046
19
Mac OS X IntelliJ IDE Oracle Spring VI Editor Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not really sure as to what you want to achieve but maybe cryptographic hashing would help?  You should note that this is not encryption followed by decryption, as hashing is a one way function meaning its easy to encrypt but then very difficult to find the original string (decrypt).    

I'll take a wild guess that you maybe want to store passwords that are secure?  If so then you can create a hash of the password string which can be stored safely without any fear that the actual password will ever be found (hacked).  Its just a simple process to compare the hash of a user provided string (at user login authentication) with the stored hash.  If correct they will match exactly.  
However what you cannot do is discover the original password from the hashed value, since then you are trying to break the one way function.

Java Password Hashing
 
Stephan van Hulst
Saloon Keeper
Posts: 11010
243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
While you're correct that hashing is the way to go to store passwords (although you really should be using a dedicated algorithm like PBKDF2 or bcrypt, as the article rightly points out), that's not what Petros wants.

He's looking to encrypt secret messages (not passwords), and when a malicious user attempts to decrypt the message using a false key, it will spit out a fake message rather than displaying an error.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes Peter I know a thing or two about the details of encryption and hashing and I am indeed using bcrypt and pbkdf2 as the article suggests but for different reasons. What I wanted to do there was a bit more specific.
 
Ranch Foreman
Posts: 91
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe this is already done (if so don't bother to read on), but I still didn't got the question. So let me ask some instead:
- What is your goal to achieve? Do you want to store something like access credentials then salted hashing should they way to go. Or do you want to store arbitrary data securely but you still need access later on? Then encryption is what you want to use.
- Why do you want (or maybe need?) a pre-deterministic output for a given input? This defeats one of the basic principals why good and secure crypto always also needs good randomness: Each output should differ from any others! In hashing this achieved by salting, in crypto by some like the initialization vector. Yes, it's possible to build weak crypto where a given combination of a key and a message would result in a known/wanted output - but the second the same messages is encrypted by a different key or the same key is used to encrypt a different message without additional randomness the key can be calculated.
- If it's only for you then what is it you want yourself to protect against? I once had an encrypted harddrive using TrueCrypt - and as this needs some random data I stored it on a thumbdrive. As I got unlucky and fried the stick (long story) I lost all data. So, unless you have some opposite to protect against don't do it - or at least not unless you have a backup you can recover from. I learned that the hard way.
- There's some well known advise in cryptography: Don't do your own! Sure, Java, as many other languages, brings all that crypto stuff - but unless you know what you do use one of the tested libs available. They proven to work securely.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok let me go over this again. Firstly, I am not trying to invent anything by myself. I am using the built in "AES/CBC/PKCS5Padding" algorithm of Java to encrypt/decrypt and store the passwords. The way this works is that you provide a key(user input in my case) to the algorithm and the plain-text password gets encrypted and stored. Later, if the user wants to retrieve a password, he needs to provide a key again, but if that particular key is different than the key that was used to encrypt the password, then the program ends with a BadPaddingException. This is obviously a not wanted behavior as it makes bruteforcing the key very easy. What I want to do instead is actually return a password that is wrong on purpose but seems like something that could be correct. If I just return random characters, then a supposed malicious user could try to decrypt the same password with the same key again and he would get a different result, which is obviously an unwanted behavior. That's way I am looking for a way to encrypt/hash a string using a key with a deterministic result.
 
Stephan van Hulst
Saloon Keeper
Posts: 11010
243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So you ARE trying to store passwords. Why? Are you trying to create a password manager?

Petros Papatheodoru wrote:Later, if the user wants to retrieve a password, he needs to provide a key again, but if that particular key is different than the key that was used to encrypt the password, then the program ends with a BadPaddingException. This is obviously a not wanted behavior as it makes bruteforcing the key very easy.


How did you make this leap of logic? The entire point of AES is that there's no way to brute force it, provided you use it properly. With a key length of 256 bits, you would need all the computers on the planet to work at it in parallel for longer than the expected lifetime of the universe.

That's way I am looking for a way to encrypt/hash a string using a key with a deterministic result.


Again, for what purpose? What are the stored passwords used for, and why aren't you using an existing credential manager?
 
Marshal
Posts: 24844
60
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Petros Papatheodoru wrote:This is obviously a not wanted behavior as it makes bruteforcing the key very easy.



I don't understand why telling the person that the key is not correct makes bruteforcing the key any easier. How many possible keys are there which are supported by your encryption algorithm? There should be a very large number.

But anyway it seems like what you want is a one-to-one function which maps possible keys to possible passwords, and also maps the correct key to the correct password. Then you're going to apply this function to the offered key and return the resulting "password". I don't understand what the purpose of that is, either. Most security systems store hashed passwords and not encrypted passwords, they never return a decrypted password to anybody. So I don't understand your system where the user is allowed to retrieve a password. I'm familiar with systems where the user provides a password and the system provides an encryption key. Systems where the user provides an encryption key... I don't understand why they would exist.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No leap of logic here, if you provide a key and the program suddenly crashes because of the exception then obviously the key you provided is not the correct key. Then the process of rejecting possible keys is very easy. On the contrary if you actually have to test the outputed password while trying to log in the account, the process of declining a possible key is much harder. Yes I am trying to build a password manager using Java's existing secure libraries. No reason why I am not using an existing one, I just find it fun as a project and a way to learn a thing or two. My question was very specific nevertheless and all the details are unnecessary. Thanks for your time though.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:Most security systems store hashed passwords and not encrypted passwords, they never return a decrypted password to anybody. So I don't understand your system where the user is allowed to retrieve a password.

I completely understand but what I am building is a password manager for myself so I need a way to retrieve the passwords. I know that there is not point really for all this hustle since I will be the only one that uses it, I just like the process and I want to build something robust. And yes, it seems that you understand what I am asking.
 
Paul Clapham
Marshal
Posts: 24844
60
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Petros Papatheodoru wrote:No leap of logic here, if you provide a key and the program suddenly crashes because of the exception then obviously the key you provided is not the correct key.



It's possible to catch exceptions in Java, you know. And in this case clearly you should, although the reason you gave there isn't the reason to catch the exception. The reason to catch the exception is that programs which suddenly crash when given reasonable inputs are just bad.
 
Petros Papatheodoru
Ranch Hand
Posts: 46
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Petros Papatheodoru wrote:No leap of logic here, if you provide a key and the program suddenly crashes because of the exception then obviously the key you provided is not the correct key.



It's possible to catch exceptions in Java, you know. And in this case clearly you should, although the reason you gave there isn't the reason to catch the exception. The reason to catch the exception is that programs which suddenly crash when given reasonable inputs are just bad.

Of course I am catching the exception but still I have to provide an output and instead of writing "wrong key" what I am trying to do is display a wrong but believable "password" , which will always be the same for the same value of the key.
 
Stephan van Hulst
Saloon Keeper
Posts: 11010
243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Petros Papatheodoru wrote:No leap of logic here, if you provide a key and the program suddenly crashes because of the exception then obviously the key you provided is not the correct key. Then the process of rejecting possible keys is very easy.


The leap of logic I'm referring to is that knowing that the key is wrong implies that brute forcing is easy. It's not and as I stated earlier, that's the entire point of all cryptographic primitives in the first place. You simply can not brute force AES. Period.

Note that using the user input to encrypt your credentials with is WRONG. You will want to derive a random key from the user password and use that to encrypt and decrypt your credentials. This serves two purposes:

  • The key derivation function introduces an additional latency.
  • If the encryption key DOES get compromised, you can generate a new one from the same password. (but you really should change the password)


  • So here is what you'll want to do: Generate a secret using PBKDF2 to protect your credentials. Then use that secret to encrypt your credentials using an AEAD algorithm, such as AES/GCM. Using GCM mode ensures that the encrypted data hasn't been tampered with. GCM is normally used for ephemeral data and not stored data, but it's better than not using authenticated encryption. Your storage format then roughly looks like:

    (PBKDF2 iteration count) + (PBKDF2 IV) + (AES/GCM IV) + (encrypted credentials)

    Getting the passwords happens like this: Use the stored PBKDF2 parameters to derive the encryption key from the entered master password. Then use the encryption key together with the stored AES/GCM parameters to decrypt the data.

    Whenever you update the encrypted data, generate a new AES/GCM IV. Whenever you update the password, generate a new PBKDF2 IV and you obviously also have to decrypt and re-encrypt everything.
     
    Petros Papatheodoru
    Ranch Hand
    Posts: 46
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks for these tips!
     
    My, my, aren't you a big fella. Here, have a tiny ad:
    Sauce Labs - World's Largest Continuous Testing Cloud for Websites and Mobile Apps
    https://coderanch.com/t/722574/Sauce-Labs-World-Largest-Continuous
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!