What's the most secure way to embed a password

2019-04-29 03:54发布

问题:

This question already has an answer here:

  • Handling passwords used for auth in source code 5 answers

I have to preface this question by saying that I'm aware that hard-coding a password in the client application is bad practice, for many reasons. There are other questions dealing with that issue. The scope of this question is narrower and assumes that authenticating credentials HAVE to reside on the client application's code for some set of reasons that are out of your control.

If some ways are better than others (for instance: JPasswordField stores the password in a char array instead of a String) and if you had to hard code it in the Java application, what measures could you take to make it harder to be fetched?

Update:

One instance of the application runs on a remote pc, where the end user has admin rights. The credentials are used to access a database in the same network, so the actual password is already predetermined and must be entered manually in the actual code.

回答1:

.... if you had to hard code it in the Java application, what measures could you take to make it harder to be fetched?

For a start, I would make damn sure that the person with management responsibility for making this bad decision is fully aware that this is fundamentally and irredeemably insecure1.

Then I'd probably think up some naff algorithm that assembles the password in an obscure way; e.g. by building two byte arrays and XORing them together ... and distributing obfuscated bytecodes. The best you can hope to do is to make it difficult for folks with limited skills to reverse engineer the password from your code.

(Encrypting the password with a strong algorithm won't help much, because the choice of algorithm and the decryption key both have to be embedded in your code. Indeed, any scheme you can dream of can be defeated by using a debugger to set a breakpoint at the point where the password needs to be in the clear.)

1 ... and that even Jon Skeet wouldn't be able to make it secure.


If some ways are better than others (for instance: JPasswordField stores the password in a char array instead of a String) ...

I just want to note that the normal reasoning for using a char array to hold passwords in JPasswordField and the like is to protect against bad guys reading passwords out of core dumps or swap files. It won't really help in this case because we have to assume that the bad guy you should be worried about is simeone with system admin access. He or she will have sufficient control to attach a debugger to the JVM and capture the bytes from the char array.



回答2:

As a general guideline you should never store the password (of course).

If you need to have a password available in runtime the best practice (as advocated in the Continous Delivery book by Jez Humble for example) is to provide the password at deploy/startup time. This way the password can reside only in peoples' heads instead of in an insecure file somewhere.

I do not know if this is feasible in your case, but you should aim towards that.



回答3:

I guess the least un-ideal solution is, if you can have challenge-based authentication protocol with random element in it.

That way it is not just the password, it is also the code which uses the password to generate correct responses, which needs to be reverse-engineered.

Then it can also be two-way authentication, that is your end can verify that the other side also uses same protocol/algorithm and also has same password.

And most importantly, then the password is never sent over network, so it can't be sniffed.

Diffie-Helman key exchange is one widely used protocol for such a thing, but you could always roll your own simple implementation, if you only want obscurity, not real security. Well, real security is obviously out of your reach if everything can be decompiled and reverse-engineered from bytecode, but anyway... :)



回答4:

It's extremely unsafe to store sensitive data on the client side, espicially for password, because the .class files can be easily decompiled. Do you ever think about get some asymmetric encryption stuff involved ? Like public/private key pair or something like that?



回答5:

I like Stephen's answer, but I would add...

Security of the source code is important too. No matter what method you use to obfuscate the password, anyone with access to the source can easily put a System.out.println(password) and capture the password where it's used, or run the code in debug and halt the code to inspect variables.

Even without compiling, anyone with access to the jar can start the java program in debug mode and halt the program where the password is used and inspect the variable, trivial with the source code, but still doable with just the jar and some tools.

You might consider having the program get the password from a secure server when it needs it (via a web service call or whatever) and have that server use a firewall to allow only certain IPs from accessing it (if the IP of the client machines is known). It still isn't secure, but at least it's something.



回答6:

you can hash the password and even encrypt it if you wish. take a look at this post it might come useful. Java - encrypt / decrypt user name and password from a configuration file