• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

AES secure key creation

 
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am following the code I found here: AES, and did some changes to make it fit my needs.

Now it was pointed out to me that the way the key is created is not safe as it is using SHA-1 and that I should change it using a better algorithm but as this is my first time using and learning about AES, I don't really understand a bunch of this terms and how to proceed with them thus I would like your help in understanding some this.

My Code for setting the key "Note that I can set my key and it is not randomly generated":



The proper algorithm according to stack:




Now what I don't really understand here are the generation of the salt and the password, and their declaration.
Why does the password needs to be char[] and the salt byte[]?
I would be using a string for my password would it still be possible if I change it to char[]?



 
Rancher
Posts: 1093
29
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is my way of thinking looking at package--and having not looked at the internal implementation:

password needs to be char because every character of your password is going to analyzed and it will keep the package from having to convert it, and in doing so, loosing a String that is free for collection. It is also something that you have to be able to type in from the keyboard, so char makes sense.

salt as byte--this is not something that has to come from the keyboard, so same size as char, but not expected to be from the keyboard.

Your password can easily be changed by String.toCharArray();
 
Saloon Keeper
Posts: 15533
364
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
NEVER USE STRINGS FOR SENSITIVE DATA.

Strings are immutable, and objects in Java may remain in memory for a long time. That's why char[] is used. After you use the password, zero out the array, and any copies of the array, or it will linger in memory where it can be analyzed.

That means String.toCharArray() is also not allowed, because your sensitive data is already in String form, which you need to avoid. Read sensitive data using char buffers, or one char at a time.

Don't use digests/hashes to derive key material. Hash functions are primitives that you shouldn't use directly. Use a Key Derivation Function, such as PBKDF2. Key derivation algorithms need salts and iterations. Salts are binary data, so that's why they're stored as a byte array.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:NEVER USE STRINGS FOR SENSITIVE DATA.

Strings are immutable, and objects in Java may remain in memory for a long time. That's why char[] is used. After you use the password, zero out the array, and any copies of the array, or it will linger in memory where it can be analyzed.

That means String.toCharArray() is also not allowed, because your sensitive data is already in String form, which you need to avoid. Read sensitive data using char buffers, or one char at a time.

Don't use digests/hashes to derive key material. Hash functions are primitives that you shouldn't use directly. Use a Key Derivation Function, such as PBKDF2. Key derivation algorithms need salts and iterations. Salts are binary data, so that's why they're stored as a byte array.



Here is the complete code:




Also from what I understand on what you said, is that the password should be declared then emptied after it was used to prevent anyone from ever knowing what it is, but then in my case I kinda need to always keep the password around as I need to decrypt the encryption, though I am adding some extra variables in my password to make sure that each data will have a different password or key.

Correct me if I'm wrong in understanding what you've said. This is literally my first time using AES, Also would you mind guiding me on which part of the key process should I modify and how do I proceed with it?

Les Morgan wrote:This is my way of thinking looking at package--and having not looked at the internal implementation:

password needs to be char because every character of your password is going to analyzed and it will keep the package from having to convert it, and in doing so, loosing a String that is free for collection. It is also something that you have to be able to type in from the keyboard, so char makes sense.

salt as byte--this is not something that has to come from the keyboard, so same size as char, but not expected to be from the keyboard.

Your password can easily be changed by String.toCharArray();



I have posted the full code for better reference though I am not that sure if that is the best implementation of AES as I've only followed the example.
 
Stephan van Hulst
Saloon Keeper
Posts: 15533
364
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

rodolfo tuble wrote:Also from what I understand on what you said, is that the password should be declared then emptied after it was used to prevent anyone from ever knowing what it is, but then in my case I kinda need to always keep the password around as I need to decrypt the encryption, though I am adding some extra variables in my password to make sure that each data will have a different password or key.


Key derivation functions require you to add these 'extra variables' in the form of a salt. They also do other stuff that makes them much safer than just using a hash function. Seriously, don't use hash functions to derive keys!

You should also never hard-code passwords. Require the application to prompt for a master password at startup and then derive a key using a hard-coded salt and iteration count, or get a key from a key store.

Correct me if I'm wrong in understanding what you've said. This is literally my first time using AES, Also would you mind guiding me on which part of the key process should I modify and how do I proceed with it?


This hasn't as much to do with AES specifically as it does with good general coding and encryption practices.

First of all, get rid of all the static data. This code is very brittle. Create instances of classes that you need, and keep data in instance fields.

As I mentioned, don't use SHA-1 directly as a key derivation function. Instead, use bcrypt or PBKDF2. Generate and store a salt for each key you derive.

Similarly, don't use AES directly to encrypt data. Encryption should be done in one step with authentication. For this, use an AEAD algorithm such as AES in Gaulois Counter Mode. Java includes the AES/GCM/NoPadding transformation.

Generate and store an IV for each message you encrypt, and store it with the message. NEVER HARDCODE INITIALIZATION VECTORS!!!

I've written some examples: https://coderanch.com/t/658304/Security/Password-Based-Authenticated-Encryption
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:

Generate and store an IV for each message you encrypt, and store it with the message. NEVER HARDCODE INITIALIZATION VECTORS!!!

I've written some examples: https://coderanch.com/t/658304/Security/Password-Based-Authenticated-Encryption



Sorry for the late response I am still working on the other part of my system, Also my post was moved from the Java in General section thus it confused me for a bit.

Regarding your example, Thank you, also in your thread post 2 and 3 are related, but both of them aren't related to post 1, am I right? since they didn't have any connection. I would base my changes on your 2 and 3 since I need to specify my KEY, though regarding IV, I still don't fully understand the principle of storing the IV in the message, how will then I know the IV if I were to decrypt the message? is it not needed so that the message can be decrypted?

Hope you can help clear some of this questions of mine, Thank you
 
Stephan van Hulst
Saloon Keeper
Posts: 15533
364
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't know what you mean by how the posts are related. My first code example models a password based key. The second one models a message that was encrypted with such a password. The last post is a code example of how these two classes are used together.

The IV is part of the message, but not part of the cipher text. When you decrypt the cipher text, you can use the IV that is stored with the same message. It's not secret information. All of this is already done for you by the EncryptedMessage class.

You can generate a Password for a certain pass phrase, and then store() it in a key store. When you want to encrypt messages, load() the password from the store, encrypt() a message with it, and write() the encrypted message somewhere. Later, you can read() the message again, load() the password, and use the use that password to decrypt() the message.

You can authenticate users before using a password to encrypt/decrypt, by requiring them to enter a pass phrase, and seeing if the Password can match() it.
 
Been there. Done that. Went back for more. But this time, I took this tiny ad with me:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic