Can anyone explain how this string has likely been encrypted at all?
AES256:29://(Hex://5B18C3AD8CFR4D38)
I've never seen an encryption has like this before in my life. Would it be possible to replicate with PHP? (Providing I can get what salts etc may have been used etc).
This is for a migration of data from one website to another - currently this data is stored in a MSSQL DB but will be used in MySQL if PHP can handle the encryption.
It appears to be part of a 256bit hash with some metadata around it. I'm not familiar with the php libraries for encryption but know that you can create a 256bit sha with php and there should be a toHex() method.
To check a password, encrypt the users entry with sha256 and check its hex value against the one stored. Have you checked to see if its the first 1/4 of a sha? Maybe they just truncate for lack of security?
If I had the guess, the 29 is probably userid, but could be a salt or something.
Related
I am working to migrate an existing online store from Miva Merchant to Prestashop. One issue I'm having is customers' passwords. When I export customers from Miva Merchant, an example password field looks like this:
PBKDF1:sha1:1000:W86eGcNGtpk=:ZZNLmbF5f8dcR2j70FkCYpFX90U=
Obviously, I'll need to modify prestashop's password verification code, but what am I supposed to modify it to? Currently, the passwords are being checked with (roughly):
md5(_COOKIE_KEY_.$passwd)
If the encrypted value matches the one stored in the database, the authentication succeeds. what encryption do I need to deal with?
It seems that I'm dealing with pbkdf1 byte derivation using sha1 algorithm, likely with 1000 iterations. However what are the other two fields? One of them probably represents salt, the other - the actual password hash, but which is which? The pbkdf1 algorithm produces bytes, so they need to somehow be converted to a printable string - but how? And what is the length being used?
Ok, a lot more digging and creative googling - and I found my answer: this great Miva_Password PHP class by Brandon0 on GitHub. I created a simple test - and managed to match the password hash. Unfortunately, to do this properly, I'd have to make quite a few changes to classes/Customer.php class in Prestashop to replace the current md5 hashing with the Miva algorithm.
I'll try to convince the client to just import the customers without passwords - so that they would need to reset their passwords on the next visit. Hopefully, they'll agree. If not, then I'll have to make all the changes.
I wrote a "Password Locker" C# app a while ago as an exercise in encryption. I'd like to move the data to the web so that I can access it anywhere without compromising my password data. I'd just like to run my ideas by the community to ensure I'm not making a mistake as I'm not an encryption expert.
Here's what I envision:
In the C# app all the password data is encrypted as a single chunk of text using a user supplied password. I'm using Rijndael (symmetric encryption) in CBC mode. The password is salted using a hard coded value.
Encrypted data gets sent to my database
I go to a web page on my server and download the encrypted text. Using client side javascript I input my password. The javascript will decrypt everything (still client side)
Here are my assumptions:
I assume that all transmissions can be intercepted
I assume that the javascript (which contains the decryption algo, and hard coded salt) can be intercepted (since it's really just on the web)
The password cannot be intercepted (since it's only input client side)
The result is that someone snooping could have everything except the password.
So, based on those assumptions: Is my data safe? I realize that my data is only as safe as the strength of my password... Is there something I can do to improve that? Is Rijndael decryption slow enough to prevent brute force attacks?
I thought about using a random salt value, but that would still need to be transmitted and because of that, it doesn't seem like it would be any safer. My preference is to not store the password in any form (hashed or otherwise) on the web.
Edit:
I am considering using SSL, so my "interception" assumptions may not be valid in that case.
Edit 2:
Based on comments from Joachim Isaksson, I will be running with SSL. Please continue breaking apart my assumptions!
Edit 3:
Based on comments from Nemo I will use salt on a per user basis. Also, I'm using PBKDF2 to derive a key based on passwords, so this is where I'll get my "slowness" to resist brute force attacks.
Without even going into the crypto analysis in any way, if you're assuming all your information can be intercepted (ie you're running without SSL), you're not secure.
Since anyone can intercept the Javascript, they can also change the Javascript to make the browser pass the clear text elsewhere once decrypted.
Also, anyone hacking into the site (or the site owner) can maliciously change the Javascript to do the same thing even if SSL is on.
By "password data", I assume you mean "password-protected data"?
The salt does need to be random. It is fine that is transmitted in the clear. The purpose of a salt is protection against dictionary attacks. That is, should someone manage to obtain your entire encrypted database, they could quickly try a large dictionary of passwords against all of your users. With random salts, they need to try the dictionary against each user.
Or, alternatively, even without compromising the database, they could generate a huge collection of pre-encrypted data for lots of dictionary words, and immediately be able to recognize any known plaintext encrypted by any of those keys.
Even with a salt, dictionary attacks can be faster than you would like, so deriving key data from a password is a lot more subtle than most people realize.
Bottom line: As always, never invent your own cryptography, not even your own modes of operation. To derive an encryption key from a password, use a well-known standard like PBKDF2 (aka. PKCS#5).
Well, as this is an open question:
Issue #1
What are you going to do if the password that is supplied is incorrect, or if the salt/ciphertext is altered? You will get an incorrect decryption result, but how are you going to test that? What happens if just the last part of the ciphertext is altered? Or removed altogether?
Solution: Provide integrity protection against such attacks. Add a HMAC using a different key or use a mode like GCM mode.
Issue #2
What happens if you change or add a few bytes to the password (compare the encrypted store in time)?
Solution: Encrypt your key store with a different IV each time.
That's already 4 issues found :) Cryptography is hard.
I need to encrypt the password the user enters in a text box on the UI, save it, and then decrypt it when the getPassword() method is called.
What is the correct JDK 1.4 API I should use?
Thanks in advance.
If you want to secure you passwords, you'll may want to use a Hash algorithm like MD5 or SHA1. You don't want to decrypt the stored password to compare it with the one provided on a login but rather hash the provided password and compare the Hashs
here some documentation on the methods you can use to hash :
https://www.owasp.org/index.php/Hashing_Java
There's an example here using Java 1.4 Crypto interface for MD5 encryption:
http://download.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#HmacEx
Blowfish:
http://download.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#BlowKeyEx
Just use Cipher with the "AES/CBC/PKCS5Padding" mechanism (in getInstance()). You can use a 128 bit (16 byte) AES key created using SecretKeySpec (this is already a key!). Higher bitrates will require unlimited encryption policy files to be installed. As I noted as remark, please note that this is only obscuring the data, since the key will need to be stored with the application - so people that know what to do can retrieve both the password and key and decrypt the information outside of the application.
If you store multiple passwords with the same key, make sure you generate and store a separate random IV per password. The advise in this last paragraph is more to let you know how to encrypt stuff correctly since it is easier to obtain the key than to decrypt the data without it anyway.
A few years ago, when first being introduced to ASP.net and the .NET Framework, I built a very simple online file storage system.
This system used Rijndael encryption for storing the files encrypted on the server's hard drive, and an HttpHandler to decrypt and send those files to the client.
Being one of my first project with ASP.net and databases, not understanding much about how the whole thing works (as well as falling to the same trap described by Jeff Atwood on this subject), I decided to store freshly generated keys and IVs together with each file entry in the database.
To make things a bit clearer, encryption was only to protect files from direct access to the server, and keys were not generated by user-entered passwords.
My question is, assuming I don't want to keep one key for all files, how should I store encryption keys for best security? What is considered best practice? (i.e: On a different server, on a plain-text file, encrypted).
Also, what is the initialization vector used for in this type of encryption algorithm? Should it be constant in a system?
Keys should be protected and kept secret, simple as that. The implementation is not. Key Management Systems get sold for large amounts of money by trusted vendors because solving the problem is hard.
You certainly don't want to use the same key for each user, the more a key is used the "easier" it comes to break it, or at least have some information leaks. AES is a block cipher, it splits the data into blocks and feeds the results of the last block encryption into the next block. An initialization vector is the initial feed into the algorithm, because at the starting point there is nothing to start with. Using random IVs with the same key lowers the risk of information leaks - it should be different for every single piece of data encrypted.
How you store the keys depends on how your system is architected. I've just finished a KMS where the keys are kept away from the main system and functions to encrypt and decrypt are exposed via WCF. You send in plain text and get a reference to a key and the ciphered text back - that way the KMS is responsible for all cryptography in the system. This may be overkill in your case. If the user enters a password into your system then you could use that to generate a key pair. This keypair could then be used to encrypt a key store for that user - XML, SQL, whatever, and used to decrypt each key which is used to protect data.
Without knowing more about how your system is configured, or it's purpose it's hard to recommend anything other than "Keys must be protected, keys and IVs must not be reused."
There's a very good article on this one at http://web.archive.org/web/20121017062956/http://www.di-mgt.com.au/cryptoCreditcard.html which covers the both the IV and salting issues and the problems with ECB referred to above.
It still doesn't quite cover "where do I store the key", admittedly, but after reading and digesting it, it won't be a huge leap to a solution hopefully....
As a pretty good soltution, you could store your Key/IV pair in a table:
ID Key IV
skjsh-38798-1298-hjj FHDJK398720== HFkjdf87923==
When you save an encrypted value, save the ID and a random Salt value along with it.
Then, when you need to decrypt the value, lookup the key/iv pair using the id and the salt stored with the data.
You'd want to make sure you have a good security model around the key storage. If you went with SQL server, don't grant SELECT rights to the user that accesses the database from the application. You wouldn't want to give someone access to the whole table.
What if, you simply just generated a key for each user, then encrypted it with a "master key"? Then, make sure to have random ivs and as long as you keep the master key secret, no one should be able to make much use of any amount of keys. Of course, the encryption and decryption functions would have to be server-side, as well as the master key not being exposed at all, not even to the rest of the server. This would be a decent way to go about it, but obviously, there are some issues, namely, if you have stored your master key unsafely, well there goes your security. Of course, you could encrypt the master key, but then your just kicking the can down the road. Maybe, you could have an AES key, encrypted with a RSA key, and the RSA key is then secured by a secret passprase. This would mitigate the problem, as if you have a decent sized RSA key, you should be good, and then you could expose the encryption functions to the client (though still probably shouldn't) and since the key encryption uses a public key, you can have that taken. For added security, you could cycle the RSA key every few months or even weeks if need be. These are just a few ideas, and I know that it isn't bulletproof, but is more secure than just stuffing it in a sql database.
I'm writing a little desktop app that should be able to encrypt a data file and protect it with a password (i.e. one must enter the correct password to decrypt). I want the encrypted data file to be self-contained and portable, so the authentication has to be embedded in the file (or so I assume).
I have a strategy that appears workable and seems logical based on what I know (which is probably just enough to be dangerous), but I have no idea if it's actually a good design or not. So tell me: is this crazy? Is there a better/best way to do it?
Step 1: User enters plain-text password, e.g. "MyDifficultPassword"
Step 2: App hashes the user-password and uses that value as the symmetric key to encrypt/decrypt the data file. e.g. "MyDifficultPassword" --> "HashedUserPwdAndKey".
Step 3: App hashes the hashed value from step 2 and saves the new value in the data file header (i.e. the unencrypted part of the data file) and uses that value to validate the user's password. e.g. "HashedUserPwdAndKey" --> "HashedValueForAuthentication"
Basically I'm extrapolating from the common way to implement web-site passwords (when you're not using OpenID, that is), which is to store the (salted) hash of the user's password in your DB and never save the actual password. But since I use the hashed user password for the symmetric encryption key, I can't use the same value for authentication. So I hash it again, basically treating it just like another password, and save the doubly-hashed value in the data file. That way, I can take the file to another PC and decrypt it by simply entering my password.
So is this design reasonably secure, or hopelessly naive, or somewhere in between? Thanks!
EDIT: clarification and follow-up question re: Salt.
I thought the salt had to be kept secret to be useful, but your answers and links imply this is not the case. For example, this spec linked by erickson (below) says:
Thus, password-based key derivation as defined here is a function of a password, a salt, and an iteration count, where the latter two quantities need not be kept secret.
Does this mean that I could store the salt value in the same place/file as the hashed key and still be more secure than if I used no salt at all when hashing? How does that work?
A little more context: the encrypted file isn't meant to be shared with or decrypted by others, it's really single-user data. But I'd like to deploy it in a shared environment on computers I don't fully control (e.g. at work) and be able to migrate/move the data by simply copying the file (so I can use it at home, on different workstations, etc.).
Key Generation
I would recommend using a recognized algorithm such as PBKDF2 defined in PKCS #5 version 2.0 to generate a key from your password. It's similar to the algorithm you outline, but is capable of generating longer symmetric keys for use with AES. You should be able to find an open-source library that implements PBE key generators for different algorithms.
File Format
You might also consider using the Cryptographic Message Syntax as a format for your file. This will require some study on your part, but again there are existing libraries to use, and it opens up the possibility of inter-operating more smoothly with other software, like S/MIME-enabled mail clients.
Password Validation
Regarding your desire to store a hash of the password, if you use PBKDF2 to generate the key, you could use a standard password hashing algorithm (big salt, a thousand rounds of hashing) for that, and get different values.
Alternatively, you could compute a MAC on the content. A hash collision on a password is more likely to be useful to an attacker; a hash collision on the content is likely to be worthless. But it would serve to let a legitimate recipient know that the wrong password was used for decryption.
Cryptographic Salt
Salt helps to thwart pre-computed dictionary attacks.
Suppose an attacker has a list of likely passwords. He can hash each and compare it to the hash of his victim's password, and see if it matches. If the list is large, this could take a long time. He doesn't want spend that much time on his next target, so he records the result in a "dictionary" where a hash points to its corresponding input. If the list of passwords is very, very long, he can use techniques like a Rainbow Table to save some space.
However, suppose his next target salted their password. Even if the attacker knows what the salt is, his precomputed table is worthless—the salt changes the hash resulting from each password. He has to re-hash all of the passwords in his list, affixing the target's salt to the input. Every different salt requires a different dictionary, and if enough salts are used, the attacker won't have room to store dictionaries for them all. Trading space to save time is no longer an option; the attacker must fall back to hashing each password in his list for each target he wants to attack.
So, it's not necessary to keep the salt secret. Ensuring that the attacker doesn't have a pre-computed dictionary corresponding to that particular salt is sufficient.
As Niyaz said, the approach sounds reasonable if you use a quality implementation of strong algorithms, like SHA-265 and AES for hashing and encryption. Additionally I would recommend using a Salt to reduce the possibility to create a dictionary of all password hashes.
Of course, reading Bruce Schneier's Applied Cryptography is never wrong either.
If you are using a strong hash algorithm (SHA-2) and a strong Encryption algorithm (AES), you will do fine with this approach.
Why not use a compression library that supports password-protected files? I've used a password-protected zip file containing XML content in the past :}
Is there really need to save the hashed password into the file. Can't you just use the password (or hashed password) with some salt and then encrypt the file with it. When decrypting just try to decrypt the file with the password + salt. If user gives wrong password the decrypted file isn't correct.
Only drawbacks I can think is if the user accidentally enters wrong password and the decryption is slow, he has to wait to try again. And of course if password is forgotten there's no way to decrypt the file.