------------------------------------------------------------------------------- Passwords stored in programs While I cannot condone the storing of passwords in programs be it in scripts (shell, perl, etc) or hardcoded in C-Programs. Really it is very difficult problem to not store the password in the program or script. Program must be able to get access to and make use of a password, and asking the user for one all the time is not very convenient. Especially for 'offline' or 'overnight' programs, backup utilities, and converters. The typical solution is the use of keyring daemons and agents which has already been given a password to decrpt the 'keys' (passwords and other info) that programs need to do their task. Well known examples of such programs is... * "ssh-agent" program for handling and passing ssh public keys. * Gnome Keyring, which typically encrypts its data using the users password on login, OR requests it on first use, OR is unencrypted. Both of these however are generally while a user is logged in, and typically uses the users login password, or asks for that password one time. However daemon services such as web servers, and web clients which must run when the machine boots, without a user presence. This makes it much more difficult. If you still use a keyring daemon, then how do they open up there access to the other password data. Use a password? The problem has just been pushed to another program. That is not fixing the problem only creating a new one. For such cases the password is typically saved to disk in a permission restricted file, which may or may not be encrypted. Basically the only real way to protect a secure password is with... Another password that is used solely for that purpose! And that still needs to come from somewhere. ------------------------------------------------------------------------------- Use another host that is already running. There is one solution where you use another machine that has already been booted and has the password available to authorised daemons. (reference?) ------------------------------------------------------------------------------- Use something intrinsic to the host for example; hostname, hostid, Ethernet MAC address Of course you don't use that directly but hash, or obfuscate it further. Note however that this method means that the program cannot get the real password if the program and its configuration moves to another machine. At least not without letting this linkage become public knowledge to system programmers which needs to install and migrate the code. Some form of this is often used in software licence managers. Though rather that passwords, the licence is a public key encryption based on the hostid of the machine software was licenced for, so that only the company can encrypt the key the software needs to run. ------------------------------------------------------------------------------- Obfuscation by lookup If you have a large file that you can guarantee will never change the you can use that file to generate the a hash to decrypt the real password. For example... * Use a cryptographic hash of a well known external file. For example a copy of the bible! * Lookup and concatenate the lines X,Y,Z from /usr/share/dict/words lines or a downloadable file, or some other online static database. * Use a cryptographic hash of the executable or script itself. If the program changes the generated password will no longer work! The key to this is that the source for the hash is static, and provides the initial password to decrypt all the other password(s) the program or key ring agent needs. If that source changes... Unless the source is available or easilly readable by anyone then this method of password obfuscation can be difficult to figure out. The code can look like it is just doing some type of integrity check, or resource assurance rather than generating a password to decrypt the real password it needs. BUT it must not change, or if it does the administrator, will need to know enough to be able to reset the encrypting password for the key store. And that does not work well in the real world. -- A variation of this is to have a block of the code itself be used as the source. This way the decryption password is also a part of the program itself and a verification that the program has not changed. But means that you must never change that part of the code, unless you again, know what is happening. Many PC games used this as a verification method. Example Shell Code some_function() { : "This function must never be modified or changed in any way!" } type some_function | md5sum | ... decryption_routine WARNING: using "type" in a shell script may be different for different shells and even version of the shell. That is an upgrade could break the starting password. Similarly in C programs, different recomplies and machines may have different defaults. ------------------------------------------------------------------------------- Use a reversible algorithmic hashing. It is probably the best of a bad situation with the least drawbacks. And is thus often the most common. These are methods of encrypting a small text passwords so its 'string' is not reconisable as being a password in a compiled program. The program algorimically decrypts the password to actual use. Common method is to store it in a differnet format... uuencode base64 # see ~/info/misc/mime_base64.hints openssl enc # full text encryption (password to protect password!) WARNING: de-compiling and intensive study of the program code will reveal a password stored in this way, it just makes it impossible to see password in casual password scans, or brief reviews of the program code, unless specifically pointed out by commands and variable naming. Examples... echo 1468369091346906859060166438166794P | dc # => Hello, World! Or the really simple base64 encoding. The '=' at the end tends to give the obfuscation away. secret="cGFzc3dkCg==" perl -e 'use MIME::Base64; print decode_base64("'"$secret"'");' # => passwd Though many base64 implemtations does not require them to be present if the end of the string is well defined. secret="cGFzc3dkCg" perl -e 'use MIME::Base64; print decode_base64("'"$secret"'");' # => passwd You can even make use of some very obscuated perl... s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/ The above converts 3 sets of 4 characters in "(q.S:$/9=(T1" into a 3 x 3 (9) character sequence "liverpole" -------------------------------------------------------------------------------