Imagine a NIS user database /var/yp/input-files/passwd consisting of old crypt DES hashes. The aim is to migrate this database to md5 or sha hashes. When changing a password using yppasswd, it is generated using the same algorithm as for the existing entry (probably for legacy reasons), i.e. crypt stays crypt, md5 stays md5.
Our current plan is to write a special password change script wrapping yppasswd. Is there a more elegant way to tell yppasswd to generate changed passwords in md5 format by default?
I figured it out by now:
Download the nis-package of your distribution e.g. apt-get source nis under Debian.
Edit corresponding yp-tools-2.9/src/yppasswd.c
Replace int has_md5_passwd = 0; by int has_md5_passwd = 1; in the beginning of int main (int argc, char **argv)
yppasswd then always creates md5 hashes.
Recent Linux distributions support NIS password updates through PAM, which means you can use the local passwd program instead of yppasswd. This also means that you can configure the hash algorithm, which is still (as of yp-tools 2.12) not possible with yppasswd.
Your system should have an /etc/pam.d/passwd file, which will either contain or, more likely, refer to another file that contains a line of the form:
password sufficient pam_unix.so md5 nis
The second field might differ, and there might be other parameters at the end, but you want the password line that loads pam_unix.so and it should have at least the nis parameter as well as a hash function appropriate to your NIS server (md5, sha256, etc.)
Your distribution might have a better way of configuring this, though, so make sure your changes aren't going to be overwritten by an automated process later.
On RedHat-derived systems (including at least RHEL, CentOS, Scientific Linux, and Fedora), you need to use the authconfig program with at least the --enablenis parameter. For the above scenario with MD5 hashes, the following command line would be sufficient:
authconfig --enablenis --usemd5 --update
On Debian systems (and possibly Debian derivatives, but I can't check at the moment), the proper way to do this appears to be to copy /usr/share/pam-configs/unix to something else (say, /usr/share/pam-configs/nis), edit the new file to give it appropriate settings and a new profile name, then run pam-auth-update, disable the "Unix authentication" profile and enable your new profile.
Related
i have stored md5 password with salt (for ftp server) on an old server.
The oldest passwords have illegal chars in the salt (like '=').
example not working password:$1$y8qs4=ZJ$pjAIhiNiCazGVPVOo1EQH. on Ubu20.04 with pure ftp but works on strech with proftp
example working password:$1$eHvgbggs$A/UaFfYsmAr7yPcmpMxEK. works on both systems.
Think its because the illegal '=' in the salt.
Is there a way to tell pureftp/ubuntu to ignore illegal salts?
thanks
I need to program a code that generate a unique password such that every time the machine (beaglebone black) runs the output be always the same.
In addition, if someone compiles his own linux in the beagle and runs the program, the output be different.
In summary, the password will be unique for each machine and operating system.
I thought to do that using as argument the ethernet MAC address, but I need something else that identifies the OS.
Drawing on Sami Laine's suggestion and taking into account that you will want to automate it, you need two more functions: (1) one to get the OS (+release number) and (2) one to get the first mac address.
(1) is easy enough. (Get Kernel and kernel release number:)
uname -sr
(2) is more tricky as the device will have different names depending on what linux you have, what kind of network devices you have on the machine etc etc (eth0, wlan0, ath0, eth6, enp3s0, wlp5s0, ...). To keep it simple, let's just use the first one. The network devices are all listed (as directories) in
/sys/class/net/
in each of which (directories) you will find the mac address of the respective device in a file named "address". We list all of them and only use the first one:
cat /sys/class/net/*/address|head -1
Now, we just integrate this into the command proposed by Sami Laine (which has echo repeat a line with a unique secret, e.g. a phrase borrowed from your favorite novel, the kernel/version and the mac address and pipes it into openssl to digest and encode it into a password that is unique for the string piped into it by echo but does not allow to easily guess the string from which it is generated.)
echo "Your favorite quote from your favorite novel:$(uname -sr):$(cat /sys/class/net/*/address|head -1)"|openssl ripemd160 -binary|openssl base64
Note that you can include commands into echo's argument-string in brackets and preceded by $; echo will then include the output of these commands in the position in the string.
Here, I assumed that you only want the passwords to differ between OS's and machines (i.e. to be the same if you recompile/reinstall the same OS on the same machine) ... otherwise you could perhaps include the inode (that will likely be unique depending on filesystem, installation procedure etc etc) of a file that will likely not change over the course of an OS's existence, say /etc/hostname. Like so
ls -i /etc/hostname
... and included into the command above:
echo "Your favorite quote from your favorite novel:$(uname -sr):$(cat /sys/class/net/*/address|head -1):$(ls -i /etc/hostname)"|openssl ripemd160 -binary|openssl base64
I am migrating a system from the old server (Slackware) to the new one (Redhat). The system includes some .gdbm files. I find out that on my new server, when running
WEB_SERVICES = file.gdbm
tie( %webservices, 'GDBM_File', $WEB_SERVICES, O_RDONLY, 0 )
the %webservices turns out to be empty. But this was working fine on my old server.
So my question is, are .gdbm files able to be simply transferred (using scp command) from one server to another (different operating system and different version of gdbm)?
Also I read the documents http://www.gnu.org.ua/software/gdbm/manual/gdbm.html#SEC12, which says .gdbm files need to be converted into flat format before sending over the network. But still I'm not sure how to do it.
Please help, thanks in advance!
On the old system, GDBM-tie to the hash, dump the hash. Move the dump to the new system. Read the dump into a hash, tie to GDBM to write it.
For dumping, use a platform independent serialisation format (Sereal is best), or if the dump needs to be human readable, Data::Dumper or similar for writing and Data::Undump for reading.
I'm producing a Perl module that provides an OO interface for a 3rd party API. I want to capture and store the user's password in an encrypted format before it is transmitted to the 3rd party API. The module is intended to be run on UNIX-based systems only.
I've produced the following script that performs the capture function - is this correct in the sense that it only stores the password variable in an encrypted format? I'm concerned that the password may be available in memory elsewhere (e.g. under $_ although $_ is undef).
NB. I'm using STDIN rather than #ARGV with the assumption that the OS will not log the entry or include the password in the process name. I'm using a substitute regex rather than chomp so that the input would not have to be stored in a temporary non-encrypted variable. I'm also assuming that it is not possible to be completely secure in the sense that input capture software could still capture the user's input.
Thanks in advance
use strict;
use warnings;
use Crypt::CBC;
use 5.14.0;
print 'Please enter your password: ';
system('tty -echo');
my $key = Crypt::CBC->random_bytes(56);
my $iv = Crypt::CBC->random_bytes(8);
my $cipher = Crypt::CBC->new(-key => $key,
-cipher => 'Blowfish',
-salt => 1,
);
my $ciphertext = $cipher->encrypt(<STDIN> =~ s/\n$//r);
system('tty echo');
$ strace perl -E '<STDIN>'
.... scroll, scroll, scroll ....
read(0,
... type, type, type ....
"secret\n", 4096) = 7
exit_group(0) = ?
I don't think that you can prevent someone with sufficient access rights from peeking inside your system calls or memory.
That's tough.
Run your encrypting code as a separate process, child of the main code, which process reads from STDIN and returns the encrypted password (and perhaps key). In that way, the code using your module will itself never hold the plaintext in memory.
Sure, tracing and memory inspection (and system memory inspection after process death) of the child helper will reveal the plaintext. The same techniques will reveal key and ciphertext read from a child helper, too. However, if the scenario against which you wish to defend is accidental retention of the plaintext in your process — in a complex object or a closure or I-didn't-know-a-temp-var-was-allocated-there — then do the work in a dedicated, short-lived process.
Sounds like you're implementing the Password Anti-pattern. That's a terrible idea - it teaches users to be phished. Please don't do that. You should look at using OAuth instead.
I need to hash some passwords with salt on postgresql, and I haven't been able to find any relevant documentation on how to get that done.
So how can I hash passwords (with some salts) in postgresql?
It's been a while since I asked this question, and I'm much more familiar with the cryptographic theory now, so here is the more modern approach:
Reasoning
Don't use md5. Don't use a single cycle of sha-family quick hashes. Quick hashes help attackers, so you don't want that.
Use a resource-intensive hash, like bcrypt, instead. Bcrypt is time tested and scales up to be future-proof-able.
Don't bother rolling your own salt, you might screw up your own security or portability, rely on gen_salt() to generate it's awesome unique-to-each-use salts on it's own.
In general, don't be an idiot, don't try to write your own homegrown crypto, just use what smart people have provided.
Debian/Ubuntu install packages
sudo apt-get install postgresql // (of course)
sudo apt-get install postgresql-contrib libpq-dev // (gets bcrypt, crypt() and gen_salt())
sudo apt-get install php5-pgsql // (optional if you're using postgresql with php)
Activate crypt() and bcrypt in postgresql in your database
// Create your database first, then:
cd `pg_config --sharedir` // Move to the postgres directory that holds these scripts.
echo "create extension pgcrypto" | psql -d yOuRdATaBaSeNaMe // enable the pgcrypo extension
Use crypt() and gen_salt() in queries
Compare :pass to existing hash with:
select * from accounts where password_hash = crypt(:pass, password_hash);
//(note how the existing hash is used as its own individualized salt)
Create a hash of :password with a great random salt:
insert into accounts (password) values crypt(:password, gen_salt('bf', 8));
//(the 8 is the work factor)
From-in-Php bcrypt hashing is slightly preferrable
There are password_* functions in php 5.5 and above that allow trivially simple password hashing with bcrypt (about time!), and there is a backward compatibility library for versions below that. Generally that hashing falls back to wrapping a linux system call for lower CPU usage anyway, though you may want to ensure it's installed on your server. See: https://github.com/ircmaxell/password_compat (requires php 5.3.7+)
Be careful of logging
Note that with pg_crypto, the passwords are in plaintext all during the transmission from the browser, to php, to the database. This means they can be logged in plaintext from queries if you're not careful with your database logs. e.g. having a postgresql slow query log could catch and log the password from a login query in progress.
In Summary
Use php bcrypt if you can, it'll lessen the time that the password remains unhashed. Try to ensure your linux system has bcrypt installed in it's crypt() so that is performant. Upgrade to at least php 5.3.7+ is highly recommended as php's implementation is slightly buggy from php 5.3.0 to 5.3.6.9, and inappropriately falls back to the broken DES without warning in php 5.2.9 and lower.
If you want/need in-postgres hashing, installing bcrypt is the way to go, as the default installed hashes are old and broken (md5, etc).
Here are references for more reading on the topic:
http://codahale.com/how-to-safely-store-a-password/
http://www.postgresql.org/docs/9.2/static/pgcrypto.html
https://github.com/ircmaxell/password_compat
An application should hash its passwords using key derivation function like bcrypt or pbkdf2. Here is more information on secure password storage.
... but sometimes you still need cryptogrpahic functions in a database.
You can use pgcrypto to get access to sha256 which is a member of the sha2 family. Keep in mind sha0,sha1 md4, and md5 are very broken and should never be used for password hashes.
The following is an alright method of hashing passwords:
digest("salt"||"password"||primary_key, "sha256")
The salt should be a large randomly generated value. This salt should be protected, because the hashes cannot be broken until the salt is recovered. If you are storing the salt in the database then it can be obtained along with the password hash using sql injection. Concatenating the primary key is used to prevent 2 people from having the same password hash even if they have the same password. Of course this system could be improved, but this is much better than most systems I have seen.
Generally it is best to do hashing in your application before it hits the database. This is because querys can show up in logs, and if the database server was owned then they could enable logging to get clear text passwords.
Examples and documentation on: http://www.postgresql.org/docs/8.3/static/pgcrypto.html
UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
SELECT pswhash = crypt('entered password', pswhash) FROM ... ;