• 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
  • Liutauras Vilda
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Peter Rooke
  • Himai Minh
Bartenders:
  • Piet Souris
  • Mikalai Zaikin

Database encryption using self-defined key

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am new to encryption, and have a big puzzle: I want to encrypt a password into a database using a self-defined key (so I can avoid storing it in a file for later decryption use). I can't seem to find an example of a class that doesn't create a key for me (remember, I already have my own key). I know that this isn't the most secure way to do things, but it's a short-term solution until I have more time to do the job right.
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to JavaRanch.

A key is just a byte[]; you can hardcode the array values in the Java code. See this for an example (the code is about web services encryption; it's just to show how to hardcode a byte[]).
 
Rancher
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Ulf is correct.

You will need to store the key somewhere. To use it in a Java program, you have to get it into the program. This can be from a file, hardcoded in the program source, in a property, etc. but you must have the key.

You could, in theory, ask the user for the key, but that really is bad from a human usage point of view.
 
Jeff Barnard
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I fully agree with Ulf and have already created a hardcoded key using byte[]. Per Pat, I don't plan to ask the user for a key, and neither do I plan to store a key (since it's hardcoded).

So what am I trying to do? Below is an implementation similar to the one I'm attempting... the critical question is how to use the SAME key (i.e., keyBytes or something else) to call in m_cipher.init()? Note that the TODO label is the location where the key is newly GENERATED everytime- something I do NOT want to do. This is because the data encrypted in the database may have used a different GENERATED key (I want a hardcoded key, not a GENERATED key). Any help would be appreciated:

=====================================================

private static Cipher m_cipher = null;
private static SecretKeySpec m_keySpec = null;

private static void initEncryption() throws Exception {
final byte[] keyBytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
//TODO: how can I use a hardcoded (not GENERATED) key each time?
m_keySpec = new SecretKeySpec(keyBytes, "AES");
System.out.println("Key: " + asHex(m_keySpec.getEncoded()));
m_cipher = Cipher.getInstance(m_keySpec.getAlgorithm());
}

public static String decryptString(String encrypted) throws Exception {
System.out.println("decryptString- input text: " + encrypted);
byte[] input = encrypted.getBytes();
String decryptedText = null;
byte[] decryptedByte = null;

m_cipher.init(Cipher.DECRYPT_MODE, m_keySpec);
decryptedByte = m_cipher.doFinal(input);

decryptedText = new String(decryptedByte);
System.out.println("decrypted text: " + decryptedText);

return decryptedText;
}

public static String encryptString(String decrypted) throws Exception {
System.out.println("encryptString- input text: " + decrypted);
byte[] input = decrypted.getBytes();
String encryptedText = null;
byte[] encryptedByte = null;

m_cipher.init(Cipher.ENCRYPT_MODE, m_keySpec);
encryptedByte = m_cipher.doFinal(input);

encryptedText = new String(encryptedByte);
System.out.println("encrypted text: " + encryptedText);

return encryptedText;
}
 
Pat Farrell
Rancher
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


where you fill in your bytes into the array. Its easy.
 
Ranch Hand
Posts: 781
Netbeans IDE Ubuntu Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


This will lead to tears. String should not be used as containers for binary data as for many character encodings it is not reversible. If you have to have a String version, and most of the time one does not, then you should Base64 or Hex encode the bytes of the ciphertext.
 
Jeff Barnard
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I guess I'm not being clear...



The "key material of the secret key" printed out from m_keySpec.getEncoded() is different each time I startup this application. Is this because each time the SecretKeySpec() constructor is called, it generates new key material? This secret key is used via the m_cipher.init(<whatever mode>, m_keySpec) call, and the subsequent encrypt-into-database/decrypt-from-database results differ each time I start up this application (defeating the whole purpose behind encrypting).

So... do I need to save somewhere the SecretKeySpec data instead of using a hardcoded (or generated) key?
 
Ranch Hand
Posts: 225
Eclipse IDE Debian Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
SecretKeySpec doesn't change the bytes you give it, and even clones the byte array to ensure that it isn't modified externally; see SecretKeySpec.java. I'm afraid I don't see how that code snippet could return different bytes each time.

The code below works for me, with a new SecretKeySpec each time:
 
Jeff Barnard
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by James Sabre:


This will lead to tears. String should not be used as containers for binary data as for many character encodings it is not reversible. If you have to have a String version, and most of the time one does not, then you should Base64 or Hex encode the bytes of the ciphertext.



Whoops! Didn't see this entry until now... and I think this is my problem. Thanks for the heads up!
reply
    Bookmark Topic Watch Topic
  • New Topic