hash file location on Mac? - macos

If I encrypt a file as file1 using openssl, where is the hash of that password stored?
No matter what I Google, the closest I get are instructions to enable root and navigate to /var/db/dslocal/nodes/Default/users directory. Unless I'm just not recognizing it, I am unable to find anything that looks like what I want in there.

If I understand the question correctly (i.e. that it's about encrypting a file with openssl enc -ciphername or the shorthand openssl ciphername), then the answer is: the hash is not stored anywhere.
What happens is that the password (and salt) are run through a hash function to derive an encryption key, and that key is used to encrypt the contents of the file. The key (i.e. the hash) is then discarded.
When you go to decrypt the file, it runs the password you entered and the salt (stored in the file) through the same hash function, and attempts to use that to decrypt the file's contents. If the password is the same as that used to encrypt, you get your original file back. If the password is different, you get back gibberish. openssl might be able to tell it's gibberish if the padding doesn't make sense, but it might not. As the man page says:
All the block ciphers normally use PKCS#5 padding also known as
standard block padding: this allows a rudimentary integrity or
password check to be performed. However since the chance of random
data passing the test is better than 1 in 256 it isn't a very good
test.

Related

Algorithm to encrypt local file such way, that can be decrypted to lots of real-looking results (symmetrical)

I have a local file passwords.txt where I store all logins and passwords from lots of web-services I personally use
There are some symbols and shortcuts in really critical entries, so it already has some level of security
But I also want to encrypt it from potential remote or physical access, but be able to easily decrypt it when I need to read it or add some
So, I need some script that will take passwords.txt and some its own password, that will create encrypted_passwords file with bytecode inside, that can be easily decrypted by password, like:
>>> encrypt passwords.txt password
>>> decrypt encrypted_passwords password
Encryption algorithm should produce such encrypted_passwords, decryption of which with wrong passwords, potentially can produce contents, that can be treated as something real, and then has to be checked only manually
For example, Me:
>>> cat passwords.txt
example1.com mylogin1 mypassword1
example2.com mylogin2 mypassword2
>>> encrypt passwords.txt password
Here comes Attacker, that found my encrypt and decrypt scripts, and:
>>> decrypt encrypted_passwords one-of-the-wrong-passwords
>>> cat passwords.txt
example3.com#mylogin3:mypassword3
example4.com#mylogin4:mypassword4
example5.com#mylogin5:mypassword5
So the attacker can get something probably even in different length and format, but treat it like: "Hmm, looks real, make sense", when, actually, it has nothing to do with reality
So, which algorithm can be used for such purposes and how strong its password should be?
I am ready, that password can weight even 100+ megabytes and has to be stored in some other file or multiple files, but will be glad to be able to keep it in mind
P.S. I'll also be glad if there are also some reliable bash or python tools/scripts/libraries
I'm sure this is a lot more trouble than it's worth, but just for the record, this is what you do:
Acquire a list of real passwords that you can use to build a statistical model of what real passwords look like;
Use that model to build a compressor, like a PPM compressor that can compress your password list (https://en.wikipedia.org/wiki/Prediction_by_partial_matching). Compressing your password list with this model will remove all the redundancy and give you a much shorter string of random-looking data. The compressor and the model will be built into your program.
Your encryption program will then compress and encrypt your password list.
Now when you decrypt with any password, you'll get a string of random-looking data. Be sure there are no headers or padding in your encrypted format that would give away whether the data is correct or not.
When you decompress any string of random-looking data, the model will generate a plausible list of passwords. The plausibility of this list depends on how good your statistical model is. Also be sure that your compressed format doesn't include any headers or markers that would indicate whether the decompression is correct or not.
As I said, this is a lot more trouble than it's worth. Making a good model and a good compressor for this task is quite difficult.

Is there a way to decrypt an encoded string without a key in Ruby?

Here's the problem, a string has been passed through three separate encryptions in the following order: Original -> Base64 -> AES-256 -> Blowfish (Keyless) -> Final. Write a method that takes this triple encoded string mystery_string = "OXbVgH7UriGqmRZcqOXUOvJt8Q4JKn5MwD1XP8bg9yHwhssYAKfWE+AMpr25HruA" and fully unencrypts it to its original state.
I looked into different libraries/documentation for aes256 and blowfish but all of them required a key. The only one that did not require a key was Base64 (i.e. Base64.encode64('some string') ). Not really sure where to go from here.
Firstly, the only way to crack AES-256 and Blowfish without the key is by brute force enumeration of every possibly 32-byte combination that could be used as the key. In theory, this means it's not crackable in our lifetime. There may be some vulnerabilities you could exploit as you also have the plain text, but I doubt you would have that in a real-life situation.
Second, and most importantly, just going by that site, encode-decode.comhttps://encode-decode.com/, you don't actually have enough information to decode the string even if you did know the password.
The various modes of operation for the AES256 cipher function requires either a 32-byte (or sometimes a 64-byte) key. The secret that you used (you may have just left it blank) needs to be converted into a 32-byte encryption key. This is done using a hashing algorithm, but we don't know which one is used. Hopefully, the site used a key derivation function, which provides several security benefits. However, key derivation functions require multiple parameters, and we would need to know what parameters to enter along with our secret to get the right encryption key.
Finally, we don't know if the secret is being concatenated with a salt before being hashed. Without knowing if a salt is used and what the salt is, we cannot determine the correct 32-byte key used to encrypt the plain text.
In summary, the answer to your question is: No, there is not a quick way to decrypt that string without knowing the key.
However, encryption is an awesome topic to learn.
I'd encourage you to look over the ruby docs for the OpenSSL library. They're actually quite good (besides the don'ts I mention below).
The PBKDF2 Password-based Encryption function is one of the key derivation functions I was referring to.
When encrypting with AES, you will most likely want to use AES-256-GCM which is authenticated encryption.
A couple of don'ts:
Don't use ciphers at random... understand their strengths and weaknesses
Don't use AES-128-EBC - explination
Another good encryption library is rb-NaCl.

Blowfish encrypted string becomes gibberish

I need to communicate with an API that requires the request to be encoded in Blowfish and Base64.
In my custom library I start off with:
# encoding: utf-8
require "base64"
require 'crypt/blowfish'
I create an instance:
#blowfish_key = '1234567887654321'
#blowfish = Crypt::Blowfish.new(#blowfish_key)
And further down I create the encrypted string (or 'ticket' as the API calls it)
#string_to_encrypt = "#{#partnerid},#{user.id},#{exam_id},#{return_url},#{time_stamp}"
#enc = #blowfish.encrypt_string(#string_to_encrypt)
In the Rails console I can decrypt with #blowfish.decrypt_string(#enc) without any problems. But the API gives me gibberish:
Invalid ticket:
Decrypted String :)IŠkó}*Ogû…xÃË-ÖÐHé%q‹×ÎmªÇjEê !©†xRðá=Ͳ [À}=»ïN)'sïƒJJ=:›õ)¦$ô1X¢
Also, when I encrypt something simple in the console, like "Hello", and feed the encrypted string to an online Blowfish decoder, like http://webnet77.com/cgi-bin/helpers/blowfish.pl, I get the same gibberish mess back.
It's like the Ruby blowfish encryption is a format that is not used anywhere else.
Note:
In my actual application I send the encrypted string via a form field to the Webservice. The encrypted string is Base64 encoded and prefixed with an 'a'.
#enc = Base64.encode64(#enc)
#enc = 'a' + CGI::escape(#enc)
This is explained in their documentation:
Format of the ticket:
t=’a’ + URL_Encode (
Base64_Encode (
Blowfish_Encrypt ( ‘partnerid,user_id,test_id,URL_Encode(return_URL),ticket_timestamp’, ‘blowfish_key’)
)
)
Note above that the Blowfish_Encrypt function accepts two parameters-
1)the string to encrypt and 2)a hex key. Also note that the ticket has
been prefixed with a lower case ‘a’ (ASCII 97).
Example of what the HTML form will look like:
<form method=”POST” action=”http://www.expertrating.com/partner_site_name/”>
<input type=”hidden” name=”t” value=”adfinoidfhdfnsdfnoihoweirhqwdnd2394yuhealsnkxc234rwef45324fvsdf2” />
<input type=”submit” name=”submit” value=”Proceed to take the Test” />
</form>
I am lost, where do I go wrong?
There's a couple of things:
1) As was said in the comments, if you print the encrypted strings, then this is almost always causing trouble because the encrypted strings are very likely to contain non-ASCII characters that will either be unprintable or in a representation that is not understood by others. The best way to achieve a representation that is widely understood is to encode the result using Base64 or Hex encoding, so the Base64 encoding you apply in your application is fine for that.
2) The Perl app you linked to uses for example hex encoding. As a consequence, it will also only accept encrypted strings in hex encoding. That's why it wouldn't accept any of your inputs at all. You get hex encoding suitable for the application as follows:
hex = encrypted.unpack("H*")[0].upcase
3) But still no luck with the Perl app. One reason is this (taken from Crypt sources):
def encrypt_stream(plainStream, cryptStream)
initVector = generate_initialization_vector(block_size() / 4)
chain = encrypt_block(initVector)
cryptStream.write(chain)
What this means is that Crypt writes the IV as the first block of the encrypted message. This is totally fine, but most modern crypto libraries I know won't prepend the IV but rather assume it is exchanged as out-of-band information between the two communicating parties.
4) But even knowing this, you will still have no luck with the Perl app. The reason is that the Perl app uses ECB mode encryption where the Crypt gem uses CBC mode. CBC mode uses an IV, so even one-block messages won't match except if you are using an all-zero IV. But using an all-zero IV (or any other deterministic IV) is bad practice (and Crypt doesn't do it anyway). Doing so allows distinguishing the first block from random and opens you up to attacks like BEAST. Using ECB is bad practice as well except for totally rare edge cases. So let's forget about that Perl app and concentrate on the things at hand.
5) I'm naturally in favor of using Ruby OpenSSL, but in this case I think I'm not being subjective if I tell you it's better for overall security to use it instead of the Crypt gem. Just telling you so would be lame, so here's two reasons why:
Crypt generates its IVs using a predictable random generator (a combination of srand and rand), but that's not good enough. It has to be a cryptographically secure random generator.
Crypt seems to be no longer maintained and there have been some things going on in the meantime that either were unknown at the time or that were never in the scope of that project. For example, OpenSSL starts to deal with leakage-resilient cryptography to prevent side-channel attacks that target timing, cache misses etc. That has probably never been the intention of Crypt, but such attacks pose a real threat in real life.
6) If my preaching has convinced you to make the change, then I could continue and ask you whether it really has to be Blowfish. The algorithm itself is outstanding, no doubt, but there are better, even more secure options available now, such as AES for example. If it absolutely has to be Blowfish, it's supported by Ruby OpenSSL as well:
cipher = OpenSSL::Cipher.new('bf-cbc')
7) If your production key looks like the one in the example, then there's another weak spot. There's not enough entropy in such strings. What you should do is again use a cryptographically secure random generator to generate your key, which is quite easy in Ruby OpenSSL:
key = cipher.random_key
The nice thing is it will automatically choose an appropriate key length depending on the cipher algorithm to be used.
8) Finally, am I right in assuming that you use that encrypted result as some form of authentication token? As in you append it to the HTML being rendered, wait to receive it back in some POST request and compare the received token with the original in order to authenticate some action? If this is the case, then this would again be bad practice. This time even more so. You are not using authenticated encryption here, which means that your ciphertext is malleable. This implies that an attacker can relatively easily forge the contents of that token without actually knowing your encryption key. This leads to all sorts of attacks, even leading to total compromise involving key recovery.
You must either use authenticated encryption modes (GCM, CCM, EAX...) or use a message authentication code to detect if the ciphertexts had been tampered with. Even better, don't use encryption at all and generate your tickets by using a secure hash function. The key here is to compute the hash of a securely randomized value, otherwise it is again possible to predict the outcome. A timestamp, as used in your example, is not enough. It has to be a cryptographically secure nonce, probably generated by SecureRandom.
But then you still have to consider replay of such tokens, token hijacking, ... you see, it's not that easy.

How to store salt and IV in file cocoa?

So I have implemented salts and IVs, but the decryption is now a bit buggy. Of course, I need both the salt and IV for decryption as well, but the user can't enter that... I need to be able to store both the salt and IV in the encrypted file, then retrieve the salt and IV when the user is decrypting the file. How would I go about doing this? How would I go about storing and retrieving that data?
As Peter said, the initialization vector and the salt for key derivation should be stored together with the encrypted file, in a header or such.
Instead of creating your own ad-hoc file format for encrypted storage, have a look at the OpenPGP message format (as used by both PGP and GnuPG, and maybe other programs). It is specified in RFC 4880. You will likely not have to implement all of it, but grab the portions that you need for your application.
As an added bonus, the user can then use PGP/GPG (with the right options and the password/key) to decrypt the data, if your program should somehow cease to work.
Store them along with the ciphertext. You'll need to come up with a suitable file format in which to do it; a keyed archiver will make it easy.

Encryption puzzle / How to create a PassStub for a Remote Assistance ticket

I am trying to create a ticket for Remote Assistance. Part of that requires creating a PassStub parameter. As of the documentation:
http://msdn.microsoft.com/en-us/library/cc240115(PROT.10).aspx
PassStub: The encrypted novice computer's password string. When the Remote
Assistance Connection String is sent as a file over e-mail, to provide additional security, a
password is used.<16>
In part 16 they detail how to create as PassStub.
In Windows XP and Windows Server 2003, when a password is used, it is encrypted using
PROV_RSA_FULL predefined Cryptographic provider with MD5 hashing and CALG_RC4, the RC4
stream encryption algorithm.
As PassStub looks like this in the file:
PassStub="LK#6Lh*gCmNDpj"
If you want to generate one yourself run msra.exe in Vista or run the Remote Assistance tool in WinXP.
The documentation says this stub is the result of the function CryptEncrypt with the key derived from the password and encrypted with the session id (Those are also in the ticket file).
The problem is that CryptEncrypt produces a binary output way larger than the 15 byte PassStub. Also the PassStub isn't encoding in any way I've seen before.
Some interesting things about the PassStub encoding. After doing statistical analysis the 3rd char is always a one of: !#$&()+-=#^. Only symbols seen everywhere are: *_ . Otherwise the valid characters are 0-9 a-z A-Z. There are a total of 75 valid characters and they are always 15 bytes.
Running msra.exe with the same password always generates a different PassStub, indicating that it is not a direct hash but includes the rasessionid as they say.
Another idea I've had is that it is not the direct result of CryptEncrypt, but a result of the rasessionid in the MD5 hash. In MS-RA (http://msdn.microsoft.com/en-us/library/cc240013(PROT.10).aspx). The "PassStub Novice" is simply hex encoded, and looks to be the right length. The problem is I have no idea how to go from any hash to way the PassStub looks like.
I am curious, have you already:
considered using ISAFEncrypt::EncryptString(bstrEncryptionkey, bstrInputString) as a higher-level alternative to doing all the dirty work directly with CryptEncrypt? (the tlb is in hlpsvc.exe)
looked inside c:\WINDOWS\pchealth\helpctr\Vendors\CN=Microsoft Corporation,L=Redmond,S=Washington,C=US\Remote Assistance\Escalation\Email\rcscreen9.htm (WinXP) to see what is going on when you pick the Save invitation as a file (Advanced) option and provide a password? (feel free to add alert() calls inside OnSave())

Resources