How to encrypt a password using MD5-DES? - security

I'm looking for any available tool/shell command which can encrypt passwords using as algorithm "masked-MD5-DES". The masked password must be then converted into base64, but that should be the easy part.
In the only working example I have found, the string "password" is encrypted as "j37uUs8kG9t2QSWjoxxtDg=="
<credentials>
<masked-password iteration-count="12" salt="12345678" masked-password="j37uUs8kG9t2QSWjoxxtDg=="/>
</credentials>
Can you help me to generate that masked password from the clear text "password" ?
I have tried with:
echo "password" | md5sum | base64
However the result does not match with "j37uUs8kG9t2QSWjoxxtDg==".
Any help is greatly appreciated.
EDIT: As requested by comment, I've added a reference to the document which contains the algorithm to be used in the application: https://github.com/wildfly/wildfly-proposals/blob/master/elytron/ELY-816-masked-password.adoc
Thanks

Related

How to understand the difference between these encoded strings?

Test Text: username
Encryption Result:
uname1 = b'\x01\x02\x02\x00x]n\xe8\xe6\xae\xae\xdf\xb7F\x87^!\xc1l8\x0eC\xb0\xcc\xf5\x00\xe7%j\xa2S\xc7\x84\xb4\xf2\xea]\x01K\xf9\xf9\xe7c\xa7\xc8A\xec\xf3\xd1\x9f\xd9\x9f\x86\xb7\x00\x00\x00f0d\x06\t*\x86H\x86\xf7\r\x01\x07\x06\xa0W0U\x02\x01\x000P\x06\t*\x86H\x86\xf7\r\x01\x07\x010\x1e\x06\t`\x86H\x01e\x03\x04\x01.0\x11\x04\x0c;\xaa\xe9\x03\x84\x00Z\x96"\t/\x18\x02\x01\x10\x80#\xdd\xf1C\xafy\x1e\xf07Z\x0fI_\ncr\x80\xdc\xf5>o\xb9`\x1a\xf8\x0c\xec\x0f\xc3\xd1\x8f\xdd\xe6~\xca\x16'
Supposedly the following is also the result of username being encrypted by KMS and I have to decrypt it:
uname2 = "AQICAHiRhVOkDetQTv51rimwyQpfSKJYi6zefQF+Wz32zFAYKwEyMctEfb/Oos0Mq48uPt2AAAAAZjBkBgkqhkiG9w0BBwagVzBVAgEAMFAGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM7vxxEHGmH5vHJX1zAgEQgCM2Uee6e6zM0mQgli9kXQVJ3pNid+waG6nrDnB9P3VjVquaCA=="
Decrypting uname1 works just fine but uname2 does not work and results in the following error:botocore.errorfactory.InvalidCiphertextException: An error occurred (InvalidCiphertextException) when calling the Decrypt operation:
Documentation I was following: https://docs.aws.amazon.com/kms/latest/developerguide/programming-encryption.html
I am trying to decryptuname2, uname1 was just a local test I did.
Is this a character encoding issue? Why do the strings look so different?
You simply need to decode the uname2 string, as it is Base64 encoded after being encrypted. You will then be able to decipher it.

How can I import a .pfx file that was created without a password?

I have created a PFX PDU using the java bouncycastle library. Inside the PFX PDU, there are two certificates and two encrypted private keys. All the contents are used as PKCS#7 data content (i.e. no encryption, stored as octet strings).I organised the elements according to the guidelines of PKCS#12 (RFC 7292 Section 5). Then I wrote the DER encoded byte array to a file.
I opened the file in a hex editor and saw that the object structure is OK. I have also read the file contents and built a bouncycastle PFX object from it. But when I try to open the .pfx file from my file system, the Certificate Import Wizard asks for the password for the private key. I did not use any password to create the PFX object. I have tried to use empty string and the password used for encrypting the private keys, but they didn't work. It shows "The password you entered is incorrect.".
Is there something I missed here? How can I get the password required to import certificates?
In RFC 7292, section 4.1, page 41, details of AuthenticatedSafe is described. AutthenticatedSafe is sequence OF ContentInfo which could one of three types.
AuthenticatedSafe ::= SEQUENCE OF ContentInfo
-- Data if unencrypted
-- EncryptedData if password-encrypted
-- EnvelopedData if public key-encrypted
Make your authenticatedSafe data as EncryptedData where you needs to encrypt the BERencoded value of AuthenticatedSafe with the SecretKey generated from password you will give using SecretKeyFactory and PBEParameterSpec.
Hope that, this will help you. Cheers !!!

What value of salt should I give to crypt to create a new user on Linux?

I am writing a Perl script which will create a new user (on Ubuntu).
It will need a step along the lines of
$encrypted_password = crypt ($password, $salt);
system ("useradd -d $home -s /bin/bash -g $group -p $encrypted_password $name");
What should the value of $salt be? Examples on the Internet seem to use arbitrary values, but if the encrypted password is going to be tested against what the user enters, then the kernel needs to hash the input with the same salt in order to pass the comparison.
This website claims the salt is encoded in the output of crypt, but that is apparently not true.
In Perl the output of
print crypt("foo", "aa");
print crypt("foo", "aabbcc");
print crypt("foo", "aa1kjhg23gh43jhgk32kh325423g");
print crypt("foo", "abbbcc");
is
aaKNIEDOaueR6
aaKNIEDOaueR6
aaKNIEDOaueR6
abQ9KY.KfrYrc
Aside from there being identical hashes from different salts, which is suspicious, it seems only the first two characters of the salt are used. This does not make sense from a security point of view. Also the output is not in the format as claimed in the link above.
So what value of salt should I use when encrypting a password for useradd?
All the information about crypt is in perldoc -f crypt.
Here is the part that answers your question:
When choosing a new salt create a random two character string whose characters come from the set [./0-9A-Za-z] (like join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64] ). This set of characters is just a recommendation; the characters allowed in the salt depend solely on your system's crypt library, and Perl can't restrict what salts crypt() accepts.
I hope this helps.

Safely storing encrypted sensitive data 'publicly' online?

How can I safely store sensitive data online?
I want to store some extremely sensitive information online in a public folder, and I'm not sure how to go about it.
Specifically, I want to store bitcoin private keys in a .json file named "walletData.json" in a public folder. The file contains the wallet address and public key in plain text, along with an encrypted version of the private key.
Assuming anyone can access the file and attempt to crack the encryption password with their "super computers", what's the best way to safely encrypt that private key?
I know a longer password would be a good start, but ideally I don't want to need a password longer than 10 characters.
I was thinking of maybe hashing the password 1000 times, then using that hash+password as an AES encryption key. But, as everyone can see the key generation method, i'm not sure that will help? I was also thinking of padding out the encrypted private key with some other random data, but again, I don't know if it'll really help??
Is there a safe way to do this?
EDIT - after Reid's answer:
I'm trying to do this 100% in Javascript/jQuery.
When I export a CoinPrism.com wallet, I get this:
{"keys":[{"addr":"1PNLiLgW2fBokCB2wmfhZTtbmioitkqtMm","priv":"172655af193edeb54467a52fc6eb94c67eeeff8cd03555767e5cf12df694bb88f9c8b25c4019147d9e4993405274c96a","encryptionMode":"PKBDF2-SHA256","iterations":2000}],"salt":"2222b67fc7255aaf0b4027bfcabffb5e62f39e9e0aa13e8ad70f2dc75a484f26"}
The "priv" value is an encrypted private key. I don't know exactly how it's encrypted, but i'm sure that there's a way to decrypt it using just my 10 character password.
Does anyone know how they're doing this?
Is it safe to store this information online?
Well, I will just say outright that you don't need to be the one who writes the code to do this — it is far too easy to mess up, and your post makes suggestions that are concerning. (For instance, you describe something of an ad-hoc key derivation scheme, but one that is insufficient in protection.)
So, you need a library of some kind to handle this business for you.
My suggestion: Use GPG with the ASCII armor option. For example:
gpg --symmetric --armor --cipher-algo AES file.txt
This will symmetrically encrypt (--symmetric) a file (file.txt here) using the AES cipher (--cipher-algo AES) and store the resulting encrypted file in an ASCII armored format (--armor). Note: the resulting encrypted file will be stored in the filename plus the extension .asc; e.g., here, it puts the result in file.txt.asc. You can change this with the --output option.
Now, the above command will prompt you for a passphrase — this passphrase needs to be very strong, far more than 10 characters I'm afraid. This is the burden of passphrase-based encryption: you need passphrases that are strong. Ideally, you want a passphrase that is long and complicated, hard-to-guess and hard-to-bruteforce.
Since we are on StackOverflow, you may be looking to automate the passphrase entry (using scripting). To do that, there are several --passphrase related options for GPG. For example,
gpg --batch --passphrase "test" --symmetric --armor --cipher-algo AES file.txt
will use the passphrase test instead of prompting the user. Command line arguments are not safe, however, on a system, so it would be better to use the --passphrase-from-file option, which takes a single file as an argument. The first line of that file is the passphrase to be used.

Node.js MD5 generates different result than htpasswd -m

when generating a password file using htpasswd -m -c file admin with the password admin the result looks like this:
cat file
admin:$apr1$V.aqW878$JCj8ivmSnFp3BnTCtLAuN.
When I try to authenticate against that using node.js the results are rather different:
Digest Hex: 21232f297a57a5a743894a0e4a801fc3
I've tried following this existing StackOverflow solution:
new Buffer('21232f297a57a5a743894a0e4a801fc3').toString('base64');
MjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzM=
So the result was still wrong.
When I change the digest to base64 the result would be:
ISMvKXpXpadDiUoOSoAfww==
Bottom line of my problem is that I don't get the same hashes and need help. Any advice would be greatly appreciated.
Thank you
Roman
Alright, I found the answer. htpasswd uses a "salt" which is stored in the middle bit of the password string:
$apr1$V.aqW878$JCj8ivmSnFp3BnTCtLAuN.
Salt: V.aqW878
The node-pass module gave me the right clues. See validate_md5. It uses the native openssl command to generate a salted MD5 hash.
In retrospect this makes sense since MD5 isn't safe anymore. That's the reason I didn't use it for years now and got a bit off track here. In essence, anything marked with $apr1$ is to be treated like this.

Resources