I’m creating an Excel file and it should be read-only. To do this I use:
(sheetName).getSettings().setProtected(true);
for every new sheet added.
Only someone with admin rights can get full access to the file, so after confirming a user has admin rights I do:
(workbookName).getSheet(0).getSettings().setProtected(false);
After someone with admin rights opens the file, it is not read-only anymore, until an ordinary user adds some more content to it – .getSettings().setProtected(true); again. In other words, someone can change the file after admin accesses it and before non-admin does so. I don’t have a clue how to go around it, maybe you could help me out?
--EDIT--
Users are adding data to the excel file, filling cells with information file - read workbook, copy, add some info, write and close workbook. Non-admin users can open it directly to see if what they added is there, or to see what other users added, but they should NOT be able to change anything in the file.
It is a wizard-like app that asks users for data and then adds cells to the file. One of the methods for adding data is here. The file gathers personal information from the users. The app is used only to add data, not to access it. Users can access the file only directly by double-clicking the output, and only to view the data. Admins can change the file, other users should not be able to do so.
If you're willing to pay for commercial software, the latest version of ExtenXLS has full read and write support for all the encryption formats supported by Excel. Just construct an EncryptedWorkBookHandle instead of the normal WorkBookHandle. That will use the strongest possible cipher supported by an unmodified JRE, RC4 for XLS and 128-bit AES for XLSX. If you want to use 256-bit AES with OOXML and you've installed the JCE unlimited policy you can do so with the MSOfficeEncrypter class.
JExcelAPI, a popular open-source Java spreadsheet API, does not appear to support encryption at all. Aspose.Cells, a commercial offering, supports stong encryption. The documentation for Actuate's e.Spreadsheet seems to have disappeared from the 'net, so I can't tell whether it supports encryption or not.
Since none of the freely available Java spreadsheet APIs seems to support writing encrypted spreadsheets, if you're not willing to use commercial software you'll need to come up with a workaround. You could, for example, write the spreadsheet into an encrypted ZIP file. java.util.zip doesn't support encryption, but it looks like Zip4j does.
Here's the thing since you told that users can simply edit it when and administrator removes protection there seem to be no standard alternative. However if this file is in use then no one else can modify it outside right? So simply just protect it again when administer exit the excel file, and remove protection when an administrator logs in. Like Tim said. You can create separate functions to edit the excel file and then do
disable protection
write modifications
enable protection
in all those functions. If this is feasible you can use something like AspectJ to simplify the
disable protection and enable protection
parts;
Related
In my application, users can upload any kind of files.
I would like to store them (or their data, byte[]) encrypted in the file-system, and when the user wants to re-download them, de-crypt them on the fly, transparently for the user.
The files must not be user-private, as they can be shared between groups of users.
Someone with only file-system access should not be able to get the file data.
What would be the best practice to achieve this kind of encryption requirement ?
Security should be the most important consideration.
Edit
As ideal I would see an api which I can pass the file-data as byte[] which takes care of en/decryption. This way the java.io.File would not need to know about the encryption at all.
A salt could maybe be provided from the file's metatada, while the key could e.g. be provided on application startup.
Edit 2
The comment from #Jared points to an article which kind of sovles my requirement:
http://www.codejava.net/coding/file-encryption-and-decryption-simple-example
The application runs under a system account so encrypt a folder for only that account.
Store the uploaded files in that encrypted folder.
Don't give anyone the password for that account.
Windows has this built in and there are many ways to achieve this on *NIX.
This meets all of your requirements.
When you compile a .java file into a .class file, if you had a line like
String s = "This is a String"
If you open up the .class file in a text editor, you will see
This is a String
Somewhere in the file amidst the gobblety gook.
Which is fine and dandy for most stuff, but not when dealing with sensitive information like API keys.
Of course, one alternative is to read the API key in from another file, but that just makes it EASIER to find the key, as now the person can just open "key.txt" when they open the .jar file.
So how do you encrypt a string literal in your .class file?
When you send code to a 3rd party, you loose all control over it. Even if you where to embed the API key as an encrypted string, an attacker could still try, and potentially succeed in breaking it, which would make all your encryption/decryption efforts in vain.
The best solution, in my opinion, would be to not provide any sensitive information within the application, but rather provide it with an ID of some sort. Any sensitive values which it needs would be then pulled through the use of a secure connection.
If you use a key to access a 3rd party API there is no way to protect that key from the end-user IF you ship it with your code / application or you want your application to be able to access the 3rd party API without a middleman.
The end-user could just read all data send from your app to the end-point and know the API key. Regardless of any measures you took to encrypt it you will need to send it atleast once decrypted to the 3rd party.
The safe way to do this is to require your user to log in to a service provided by you, send a request to YOUR service and then YOUR service (which is presumably not located on the machine of your end-user) sends a request to the API with the key. So the end-user never knows of the key.
If you store the information in the class file, the decryption key should come from outside of the class. You can crypt the data, but if you have all the information within the class file, you are lost.
You should store API keys in config files. You have a different API keys for development and for the live, right?
Other possible solution is to use KeyStore, which allows you to store sensitive information in publicly accessible format. Only the holder of the secret key can decrypt the sensitive data.
Even if you keep that information encrypted in your class, a hacker can find the mechanism to decrypt that from your code only. So IMHO it's better to keep that encrypted information in some other file, and read that file. Also, restrict the access to that file using OS security mechanisms.
Till now, i have been creating a file (txt/excel) using buffered Writer for creating a text file and JExcel API for creating a Excel file. These files i have been creating using Java only.
Now i want to make the file password protected in both the cases, that to something like, the file can be accessed by number of people, but only selected may access it using there own login ids/password.
Is it possible to do so?..
Thanks
The answer completely depends on what way you want to open your protected files.
If it is opened by your (java) program or an application, then you can simply simply encrypt it with a password upon saving, and decrypt it with something the user provides,
and use some checksum or header to see if the result is valid - or some garbage due to bad password,
some crypto APIs will do it for you right out of the box.
Second option - if you meant encrypting files with a program (like a notepad file, or something), and you expect windows or notepad to ask you for the password, then it depends on the format of the file you use. Some can be password protected, some can not -like text files usually associated with notepad). In this case password protection works as described in the format's own documentation, and you have to research a bit, I guess it will be too much work
we can do password protection of zip files with the core Java API.
Yes, it is possible to do that, you would have to write your own encryption and decryption tool or write a plugin for excel to do the decryption.
Usually the best approach is to use the security of the OS and specify which users can read or read/write the document. This is transparent to the user and doesn't require a encryption/decryption tool.
yes it is possible. You can use either AES or DES encryption. password is nothing but the key using which the file can be be encrypted or decrypted. you can create your own listener which will prompt you for password. If you enter the password then it will take the password and try to decrypt the file
I'm looking at all possible languages to solve a particular business case problem.
Basically need a way to allow user to browse for an excel file locally, then using Microsoft Excel COM automation, read in the cell contents and from this point on perform some actions.
I have no experience with Java, but I know this type of thing is "almost" possible using Silverlight 4.0. Here is a line of code that demonstates how you begin automation in silverlight using c#:
dynamic objExcel = AutomationFactory.CreateObject("Excel.Application");
Problem is Silverlight only opens files from "My Documents", and it seems there is nothing you can do to allow the app full access to the file system to read in any file. So I'm investigating if Java is capable of this task?
I don't need a big explanation on how to do it, mainly I just need your experience as a Java developer to say - Yes in principle its certainly possible, or not. I need to open this xls file from any location the user specifies.
So 2 things really:
Can you browse and open any file using a trusted java applet? And get access to the files path from the open dialog?
Can you automate MS Word / Excel from a Java applet.
Thanks
..Silverlight only opens files from "My Documents", ..
Java will not be able to break that security restriction.
It is for the benefit of the end user, in that if they truly want to edit the Excel file, they will save or move it to My Documents. If they cannot do that, then perhaps they should not be altering the file.
I'm coding a little library which will handle xml files to store some data, and I need this data to be handled only by the methods I provide in my library.
I know that xml is readable for both human and machine, and that if somebody really wants to modify the xml file he'll probably do it, so... do any of you have an idea that could work?
You can store more information in it, such as a hash of the content (before the hash was inserted of course).
When you will reload this file, you can check the hash. If it doesn't match with the current hash of your file, well it has been modified.
Well, there is no definitive way to block access to that file. But you can use several measures to make it hard on manual overriding of the file.
First thing you can do is lock the file (need to ensure OS compatibility) for as long as your application is running. Anyone can circumvent an OS file lock, but it is not trivial for an average user.
Second, you can consider encrypting the file on application termination. Restoring the key can be done from application code inspection, but again - a non-trivial effort.
As you said above, you have already implented a method that detects file changes, and you want a way how to prevent these modifications.
Usally, that's not possible. I'll explain at the end.
You have a few choices what to do:
If you want to prevent modifications while the program is running, you can lock the file. This will prevent applications from accessing it, but when your program exits, the lock will be released. (Example)
If you want to prevent access while the program is not running, you'll have to change file system permissions to forbid the user to edit the file. This is way more difficult as it is filesystem-related, and some filesystems like FAT haven't got file permissions at all.
You could write a "daemon" script that watches for file changes and revert them.
But all these possibilities have one problem - a program usally has the same permissions as the user, so everything the program does can be undone by the user. If your program has access, the user has too.
If you lock a file, the user could use a tool like Unlocker to release the lock, and edit it anyway. If your program sets file permissions, the user can simply change them back. On some systems, it might be possible to prevent this, but then your program looses access too. Bad. If you write a daemon, the user can kill it.
The only possibility is to have the program running with more rights than the user, and store the data on a place where the user has no access too. As example, on Windows, you can run it as a service. This requries the user to not have Administrator rights (or root, on Unix systems).
If the user is admin or root, you've lost, as he has full access to the system and you can't hide. (on Windows, there is one more level, the SYSTEM user, but an admin user can easily get these rights too).
Append a hash of the file concatenated with a secret key to the end of the file. Like an XML comment
<!-- 0123456789abcdefabcdef0123456789 -->
Upon opening the file you hash it again with the appended secret key and verify it.
Some psuedo code to clarify.
# Read
secret = "Secret key"
file = get_file_contents("file.xml")
content = strip_trailing_comment(file)
hash = get_content_hash(file)
if sha1(content + secret) == hash:
# File is valid
# Write
secret = "Secret key"
content = content_to_xml()
hash = sha1(content + secret)
content_with_hash = append_comment(hash)
write_to_file("file.xml", content_with_hash)
Hope that clears up potential misunderstandings. This way the code is still human readable, if you want that, and hard to tamper with.
As I understand from discussions and your question, you want to store the data as xml, and difficult for user to open/modify it.
In that case you will have to do some additional work:
Create the xml file with hash information as suggested by Colin HEBERT
Zip the file with password protection, the password to which only your app will know
There is a question on stackoverflow on how to password protect your zip file
In this approach, mind you, the xml file does not even become readable.
If you want your files to be readable, then you could probably use a seperate user id for your application (unix user id or windows userid) as owner of the files. and only allow that user to modify the files, but still this won't be a 100% solution.