Win a copy of Java Persistence with Spring Data and Hibernate this week in the Spring 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Tim Cooke
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • Junilu Lacar
  • Rob Spoor
  • Jeanne Boyarsky
Saloon Keepers:
  • Stephan van Hulst
  • Carey Brown
  • Tim Holloway
  • Piet Souris
Bartenders:

Writing Encrypted Strings

 
Ranch Hand
Posts: 92
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I'm hoping someone can let me know if I'm on the right track here... I have a properties file that is loaded into memory. Under certain circumstances, I wish to encrypt the values for some properties in the Properties object now in memory and subsequently write the data back out to the properties file from whence it came. This worked great if I simply called store() on the Properties object. I could encrypt and decrypt to my heart's content. Of course, calling "store()" doesn't preserve any of the comments in my properties file so I set about writing some code (see below) that would

A.) preserve comments
B.) write the encrypted data for properties that have been encrypted.

Here's that code...


So before a line is written out, that line is checked to see if it is the key/value pair corresponding to a property that is now encrypted in memory. If it is, that value is gotten from the Properties object and concatenated on to the property and returned to be written out. Here's the result...



The leading $b122r73w$ is just a flag to determine if the property has been encrypted. The actual "encrypted" value follows that String and is, as you can see, garbage.

So my question here is threefold...

A.) Why does the store() method of the Properties object write encrypted data properly and my code doesn't?
B.) What is actually being written out through my code? I see the same garbage in a println or logger.debug statement so I can only assume that the OutputStream I am using isn't cutting it... but what is it doing to the encrypted value?
C.) Should I be using a CipherOutputStream to write my encrypted value?

If I do use a CipherOutputStream... will it allow me to write unencrypted Strings?

Thanks in advance for any guidance.

--BW
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

A Writer expects to output Unicode characters in a particular encoding and is probably changing your encrypted bytes. You should use a FileOutputStream.
Bill
 
Brian R. Wainwright
Ranch Hand
Posts: 92
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the reply Bill. You're of course correct - I should be dealing with the raw bytes and writing them out. I modified my code to use a FileOutputStream instead as you suggested, but to no avail... I get the same garbage on output. So, thinking that perhaps there was some issue with properties.getProperty("myEncryptedProperty"), I decided instead to:

A.)Read a line of text in from the FileReader and parse it it into
the property name and the current unencrypted property value
B.) Write out the property name as bytes
C.) Write the result of encrypting the property value.

So essentially I'm doing the encryption twice - once to set the property value in memory and the second to just write it out to the file. I was confident that this would work and I could go back and refactor the code later. It didn't! I get the same garbage... BUT if I just call properties.store() it works great. There's got to be something else more insidious at work here... It may have to do with this - from the Properties class javadoc...

Then every entry in this Properties table is written out, one per line. For each entry the key string is written, then an ASCII =, then the associated element string. Each character of the key and element strings is examined to see whether it should be rendered as an escape sequence. The ASCII characters \, tab, form feed, newline, and carriage return are written as \\, \t, \f \n, and \r, respectively. Characters less than \u0020 and characters greater than \u007E are written as \uxxxx for the appropriate hexadecimal value xxxx. For the key, all space characters are written with a preceding \ character. For the element, leading space characters, but not embedded or trailing space characters, are written with a preceding \ character. The key and element characters #, !, =, and : are written with a preceding backslash to ensure that they are properly loaded.



The result of the store call (which just uses a regular FileOutputStream:
e.g new BufferedOutputStream(new FileOutputStream(new File(path+".store"))) is a bunch of hexadecimal values, which CAN be decrypted properly



The result of the new code is still garbage e.g.


And here's the new code...


Thanks for continued help - I'm really confused about what the problem could with JUST writing out bytes...

--BW
 
Brian R. Wainwright
Ranch Hand
Posts: 92
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just a little more info on this... if code the following...

I get the following output...


Looks good right? The output to the file is still junk however - it seems that some of these encrypted characters aren't recognized by the filesystem (Windows 2000)? What it appears the store method is doing is converting these characters to their respective unicode escaped values? I'm gonna try doing the same thing, but if anyone has some ideas let me know...
 
William Brogden
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

A FileReader interprets the input stream as characters in a particular encoding so it has the same problem as FileWriter.
Note that the Properties class load and store methods all use Reader and Writer with the built in assumption of character conversion.
Why not encode your encrypted bytes using base64 - that way you end up with plain ASCII code - There are base64 tools in the Apache Commons project.
Bill
 
Brian R. Wainwright
Ranch Hand
Posts: 92
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Bill,

Good Idea. I wish I had thought of it. :-) -


A FileReader interprets the input stream as characters in a particular encoding so it has the same problem as FileWriter.



Certainly... but if my property value has been properly written as an ASCII String then I don't need to worry about the encoding. I simply need to read it in line by line. Nes pas? Anyway, here's the completed and functioning code for anyone who's looking...



And without revealing too much... Here's the appropriate code from the encryption and decryption methods... using the Base64 encoding



The new output to my properties file looks as I want it to...


Hope this helps anyone looking to do the same. Thanks again Bill for all the great suggestions!

--bw
 
Opportunity is missed by most people because it is dressed in overalls and looks like work - Edison. Tiny ad:
The Low Tech Laboratory Movie Kickstarter is LIVE NOW!
https://www.kickstarter.com/projects/paulwheaton/low-tech
reply
    Bookmark Topic Watch Topic
  • New Topic