I'm coding a java program, using the JDMK 5.1 toolkit, to send SNMPv3 traps and the jdmk security file (jdmk.security.file) I seem to need to create, and have in place, to do so currently has the authorization and privacy keys in the clear.
How can I cause those values, which I consider to be passwords, be secured and still be usable by the toolkit when it reads that data from the file?
The documentation says you may specify "Any text password or any hexadecimal key starting with 0x" for those values but does not elaborate.
Related
This question already has an answer here:
Where to store keysytore password?
(1 answer)
Closed 4 years ago.
So, I am planning on making a bit of java code to encrypt and decrypt strings I throw at it. The issue is trying to save the encryption key: It is clearly visible in the Java code and I haven’t found a way around putting it into code. I have also checked several threads here, but I haven’t found the answer to my specific question.
tl;dr
I want to know how to securely store a password in Java code.
tl;dr I want to know how to securely store a password in Java code.
TL;DR - There isn't a way to securely store a password in Java code.
Any password that is embedded in your code in a usable form can be reverse engineered with a modest amount of effort and skill.
The solution depends on the problem you are trying to solve:
If you are trying to hide and use the secret (e.g. password, key, whatever), AND the user you are trying to hide the secret from controls the execution platform then there isn't a solution.
If you (or trusted admins) control the platform1, AND it is properly secured, then there are a few approaches, of varying degrees of security. These range from Store the secret in a file that the user can't access through to using an HSM (Hardware Security Module) to hold the secret.
Refactor the application so that the secret ... and the things protected by the secret are physically separated from the part of the software that the untrusted user runs; e.g. do the "special stuff" on a server.
Give each user their own personal secret (key, password, etc) ... that can be revoked.
1 - Given that "root escalation" flaws are fairly common, you would be well advised to not allow untrusted users to get access to the platform at all. However, I doubt that this is an option for what you are trying to do.
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.
Our security department wants us to use 256-bit encryption to encrypt SSN, Names of Users etc, so we decided to go with JASYPT with the sample code below:
encryptor = new StandardPBEStringEncryptor();
encryptor.setProvider(new BouncyCastleProvider());
encryptor.setAlgorithm("PBEWITHSHA256AND256BITAES-CBC-BC");
encryptor.setPassword(OUR_KEY)
encryptor.encrypt("TEXT TO ECNCRYPT")
The problem we noticed is when our application creates an encrypted record from our local machine, the application on the app-dev server cannot decrypt it and vice versa even though the key is same. It seems like JASYPT is adding some machine specific information in the salt (Mac address etc).
Even using FixedStringSaltGenerator or ZeroSaltGenerator does not help. This creates a problem for us because if we ever migrated our production server to another machine, or refreshed pre-prod data with the prod data, we may need a couple of million years to recover the information.
The security department wants us to use a well know library and not brew an in-house solution. Can someone please throw some light on this issue on how we can generate encrypted string that can be decrypted across different machines using jasypt 256 bit encryption, or when we refresh pre-prod database with prod data, how we would be able to recover names etc that were encrypted through a different server?
Any useful insights will be greatly appreciated.
your key might be containing some special characters which shell substitute with something else.
do a echo "yourkey" > file
and check the content of this file.
then use this content as a key to decrypt; it should be able to decrypt the encrypted string.
I know this is a pretty old question but I recently experienced this issue and the resolution for me had nothing to do with the differences in machine operating system endianness.
It had to do with a character in the password itself, the dollar sign character ($), that was somehow considered to be a special character in Linux vs not being considered special in Windows. So everything worked fine encrypting the values in Windows, but when I swapped over to Linux and tried to decrypt the values with the same password using the jasypt command line decrypt.sh script, I got the error message "Operation not possible (Bad input or parameters)" and noticed that the password in the jasypt decrypt output arguments list was different than the one I had typed in (the script apparently chopped off the part of the password from the special character until the end of the password string).
Anyway, my solution was to change the password to not use a special character and then it worked. Hope this helps some poor soul who happens to run across this same issue in future, because I wasted 2 days on it.
use single quotes instead of double quotes to wrap your input string. This solution worked when i had a issue with encryption and decryption of string with $.
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 am trying to make a multi user login system for my java program, at the moment i am compairing the username and password to md5 hashes stored in a text file. I would like to be able to geive different users different access wrights to the program, using the system i am using at the moment the accesablility would be easy to change if the text file was opend. Is there a way I could encrypt the text in the file and then unencrypt it when the user loggs in??? Thanks
You can take a look at this comprehensive Java Cryptography guide. However, I think that you would be better off with a database to store the username and password since a text file could be easily deleted or modified. Encrypting it only makes it tougher to read.
Please take a look here and here to learn about JDBC. If you want a more robust framework, you can use and ORM like hibernate. The links I have posted refer to MySQL. It is a very popular Database server and integrates well with Java. You shouldn't have any problems finding tutorials or any kind of help with MySQL.
Also have a look at JAAS to restrict access to your services (e.g. based on roles).
Md5 is a one way hash algorithmic you cant decrypt it back , best way is to compare the encrypted string to validate things
Does this help:
Java - encrypt / decrypt user name and password from a configuration file