How to decript salt - passwords

I'm made one register and loggin form and code.
its ok. I encript my passwords like this:
public static function Hash($password) {
$hash = "f6e649b8fc4c9e35eda6969660e36a2e";
$crypt = md5($password . ($hash));
return $crypt;
}
Why i do to decrypt this?
Thankyou;

This is a very unsafe way to hash a password. The salt is static, so it cannot not fullfill its purpose and MD5 is ways too fast for hashing passwords (one can brute-force about 100 Giga MD5 per second with common hardware).
PHP offers an easy and safe method password_hash() to hash passwords, which handles all the tricky parts like generating a safe salt:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

Related

How is it possible to compare hash values without referencing salt or saltRound?

My question is about hashing procedure.
const bcrypt = require('bcrypt');
const saltRounds = 10;
var password = "Fkdj^45ci#Jad"; // Original Password
var password2 = "djlfhjd(456"; // Wrong Password
bcrypt.hash(password, saltRounds, function(err, hash) {
bcrypt.compare(password2, hash, function(err, result) {
...
});
});
This is a code snippet for hashing with salt and comparing.
I can't understand how it is possible to compare hash and password without knowing salt. bcrypt is using Blowfish now, but how is it possible for a having algorithm to compare a password and a hash value without knowing salt?
It isn't. The output of bcrypt.hash includes that information. For example, when I run your code, the value of hash is:
$2b$10$ytoRP21isLcU43jpdiDi4ebR5aKfydE.cHt6VkoH3suODa64JUvEy
This is the "2b" format, with a cost of 10, a salt of ytoRP21isLcU43jpdiDi4e (first 22 characters) and a hash of bR5aKfydE.cHt6VkoH3suODa64JUvEy (last 31 characters). The salt and hash are "radix-64 encoded," which is similar to Base64 encoding, but uses a different table.
When you pass this to .compare, it uses the same cost and salt. This is why you need a special .compare method rather than just computing the hash on both inputs and comparing the outputs.

How do I recompute web2py's password hash?

I am trying to have another application (running on a different stack) authenticate with an existing application of mine that runs of web2py. I am trying to understand how can I validate the entered password with the one that I have in auth_user?
I did see https://groups.google.com/forum/#!topic/web2py/tLAiqRaXG48 but I was unable to get the has from there. Here is what I am doing:
import hashlib
from pbkdf2 import crypt
crypt(hashlib.sha512("MyPassword").hexdigest(),iterations=1000)
My password in the db reads like this :
pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1
(slightly changed the hash itself)
Any help would be much appreciated.
Thanks,
Rajaram
First, note that the value stored in the password field is not just the final hashed value but includes the algorithm, the per-user salt, and the final hashed value (all delimited by the $ symbol). So, assuming we have:
stored_password = 'pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1'
start by doing something like:
_, salt, hashed_password = stored_password.split('$')
Now, because pbkdf2 was used, we must use hashlib.pbkdf2_hmac to compare the hashes:
from hashlib import pbkdf2_hmac
entered_password = 'MyPassword'
is_match = hashed_password == pbkdf2_hmac('sha512', entered_password, salt,
rounds=1000, dklen=20).encode('hex')
Alternatively, if you don't mind copying the web2py validators.py module to the other system, you can simply do:
from validators import CRYPT
is_match = CRYPT()(entered_password)[0] == stored_password
Note, CRYPT() is a callable object (like all the web2py validators). When you call it with the entered password, it returns a tuple, the first element of which is a LazyCrypt object. The LazyCrypt class has implemented its own __eq__ special method, so the == comparison above triggers that method. It automatically extracts the digest algorithm, salt, and hash from stored_password, computes the hash of entered_password, and compares that to the hash extracted from stored_password (i.e., everything that was done manually in the solution above).

storing password in source

I have read several places now which basically advise against storing a password in source code, and I understand the reasons.
I have two apps: one for encryption and one for decryption. Data is encrypted to a file on a server; this file is downloaded and decrypted on a client's machine, and then processed by a proprietary app (not mine). The data is sensitive and, (ideally) is meant to be only accessible to the processing app.
As it stands I am using a symmetric key algorithm since the data is large enough. The password is hardcoded into the source code as a string - I know, bad for several reasons.
What I would like to know is what's the best way to store the password? My thought is to use an asymmetric key algorithm e.g. RSA, just for the password, but can't wrap my head around how to do this and if it even makes sense in my scenario. I'd prefer not introduce another file for distribution. I don't know much about decompiling, but I figured implementing a PBKD into the client app would pose the same problem. Cryptography is new to me as you can tell, and using this great forum.
Please don't use symmetrical keys in source files. You can use RSA without introducing another file. As opposed to symmetrical keys, the public key can be hard-coded in source code without any security issues, iff you can guarantee the integrity of the source file. Then again, if someone manages to change it, decryption won't work or there is a man-in-the-middle (MITM) attack going on (and you wouldn't know about it).
CAVEATS
This approach suffers from susceptibility of a MITM attack. An appropriate countermeasure would be to sign the data, but then you are stuck handling the keys and is really a separate question.
Keys are not forever, the key-pair you generate needs to be rotated from time to time.
Make the keys big enough (at least 2048 bits).
Revocation needs to be done manually by you. If you need a more automated solution, consider looking at PKI and OSCP Responders (with or without stapling).
If the data you are sending is large, RSA operations will be lengthy.
Ok, with that out of the way, let's dig in. The example code is written entirely with JDK 8.
First, generate a key-pair. This needs to be done once or every time you need to rotate:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = kpg.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
byte[] pubEnc = publicKey.getEncoded();
byte[] privKeyEnc = privateKey.getEncoded();
System.out.println(Base64.getEncoder().encodeToString(pubEnc));
System.out.println(Base64.getEncoder().encodeToString(privKeyEnc));
Let's say the public key was (these are actual keys I generated, don't use these):
private static final String PUBLIC_KEY_BASE64 =
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGue
5TCdPJt08w7crbvWjfcSUy/xXjzjjjjPDP7D8PNSnn
CUeNcGWsR/Pd3eoBjmrAy/4Rl8JlHylRry8pX7Zpcz
iQB8wWQdpkSoArjeu4taeFn/45+eg4J5mzmIzFG9F5
wF7N+SeSvtq3E3Q0mtJRRZZJYgNkFmeDuOQjljJVZw
IDAQAB";
and the private key was:
private static final String PRIVATE_KEY_BASE64 =
"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAg
EAAoGBAIa57lMJ08m3TzDtytu9aN9xJTL/FePOOOOM
8M/sPw81KecJR41wZaxH893d6gGOasDL/hGXwmUfKV
GvLylftmlzOJAHzBZB2mRKgCuN67i1p4Wf/jn56Dgn
mbOYjMUb0XnAXs35J5K+2rcTdDSa0lFFlkliA2QWZ4
O45COWMlVnAgMBAAECgYBAWTIRi1ISuHEkh48qoS8j
+eCwmNGVuvvFA55JUSdVVikrZm08iwCk5sD9qW6JS8
KFT2mMcZWxws5za171PffbeHoIFaNI5n5OXJa4meZA
cgl4ae5su89BjvfzDF2gsnBHwLpgsT0aVdIDQ5BGtL
WzRwZCogY6lZhBOQZAaNFYIQJBALr2+kT+pkSlxrrR
tMxK7WL+hNO7qOIl/CTBuAa6/zTtoEjFMFQBY//jH+
6iabHDfKpaFwh6ynZTXZsb7qIKOM8CQQC4eRAH1VEo
iofZNnX3VjiI5mLtV8rc8Jg+wznN+WFnwdNoLK8y9t
EcuKxg3neIJAM70D6l0IhBfza1QAqQh4/pAkA5vyLZ
wJV2SoWxGihvmQztMJOyGho1j2nrqHHAkm1U2bhSAa
XFrJBIbsxkFoHyx+BvdVf75IE4PtOAnwX7wpB9AkBQ
7CKBHS2N+D8hpQdYqcUBIPdyoFmIVC6lEaTw2x3Ekz
027KsqUyVmUQilMdIDsbCNc4uX14N+H90S43X+8sjJ
AkAKsvRbZ0Au9JytSRKSB7vYl37283zHoQ5jyYUE7x
g7C6nWSl1GEa6khZ47hFAj9C2bdLJ6GtjTleFsVCsR
LUoG";
The keys above are line wrapped for formatting reasons.
Let's say args[0] was "attack at dawn!" and you client looks like this:
public static void main(String[] args) throws Exception {
byte[] pubKey = Base64.getDecoder().decode(PUBLIC_KEY_BASE64);
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pubKey));
Cipher cipher = Cipher.getInstance("RSA");
Cipher.init(Cipher.ENCRYPT_MODE, publicKey);
String encryptedData = Base64.getEncoder().encodeToString(cipher.doFinal(args[0].getBytes("UTF-8")));
System.out.println("Encrypted data is: " + encryptedData);
}
Output: Encrypted data is:
cDoPpQYc6qibrBl5jdENcV+g6HslQDlo9potca5rQxecnxR3Bd/e1T0njqUMACl7x7AG3foGxqZyyUIMrOVXcnw/ux7BgQcg+RDZhSVFQAd5kUGI96pw8WtDVo1N1+WEfaaPhK9CpwUKUxtwR0t27n+W0vhFCqNTEGhofLt8u9o=
The server:
public static void main(String[] args) throws Exception {
byte[] privKey = Base64.getDecoder().decode(PRIVATE_KEY_BASE64);
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privKey));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] encryptedData = Base64.getDecoder().decode(args[0]);
byte[] decryptedData = cipher.doFinal(encryptedData);
System.out.println("Decrypted message was: " + new String(decryptedData, "UTF-8"));
}
Output: Decrypted message was: attack at dawn!
One cool thing about the JDK's RSA implementation is that it uses Optimal Asymmetric Encryption Padding (OAEP) from PKCS#1, which has the effect that even identical messages will look different from each encryption.
Like previous commenters have mentioned, without seeing the full picture, there may be other security problems to address. But for what it's worth, I think this approach is better than using symmetrical keys, which still can be used with this encryption scheme. Then you would get what's called a hybrid cryptosystem, but there are APIs that do this for you.
Instead of storing the plaintext password in the source and checking against that you can store the encrypted password in the source (hard coded).
Then the user can enter the password, the code encrypts the password and compare the result of the encryption with the stored encrypted value to see if the password match. The password entered (not the encrypted password) is then used to encrypt/decrypt the data.
The encryption used should make the effort to reverse the encrypted password to the plaintext password hard/impossible.
Example:
You choose the encryption/decryption password to be This is my password1 (the one that is currently in the sources).
You encrypt the password with for instance SHA-256 and hard code it in the source: 9845735b525fa70b2651975022a44be268af1d4defadba9ab2a0301e0579534c.
Encrypt/decrypt app prompt for password.
User enter password.
App calculates the SHA-256 of the entered password and compare the result to 9845735b525fa70b2651975022a44be268af1d4defadba9ab2a0301e0579534c
If it matches the data is encrypted/decrypted with entered password This is my password1 using your code already in place.
If it does not match, give an error.
A hacker gets your sources and have access to the hash 9845735b525fa70b2651975022a44be268af1d4defadba9ab2a0301e0579534c and the algorithm you used. But he needs the This is my password1 password to decrypt the data. He can reverse or brute force the hash but that takes effort and time.
One can use seeds etc, but to keep them secret is then again the same issue.
It is probably not the most secure, I am no expert but it is better than having This is my password1 in the sources.

PBKDF2 with HMAC in Java

I am working on a Java project where I must ensure the confidentiality and integrity of users password saved in a plaintext file.
To do so, I will write only a hash of the password in the file. More specifically, my intention is to write the hash of the password and a random salt, plus the random salt itself, to avoid the use of rainbow and lookup tables. I also want to use key-stretching with PBKDF2, to make the computation of the hash computationally expensive.
Finally, I would like to use a keyed hash algorithm, HMAC, for a final layer of protection.
I am trying to implement my thoughts in a Java code, and I have found some examples of the operations that I have presented above:
private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
throws NoSuchAlgorithmException, InvalidKeySpecException
{
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return skf.generateSecret(spec).getEncoded();
}
The thing that I really cannot understand is how to input my secret key as the key used by the HMAC algorithm, as it doesn't seem an input to the function. I have looked through the Java documentation, but I cannot find a solution to my question.
At this point, I am not really sure if I understood correctly how the different part of the encryption mechanism work, so I would accept any help on the topic.
I think I see the confusion. You're apparently expecting your code to apply PBKDF2 then HMAC-SHA-1. That's not how it works: HMAC-SHA-1 is used inside PBKDF2.
The gist of PBKDF2 is to apply a function repeatedly which has the following properties:
it takes two arguments;
it returns a fixed-size value;
it is practically undistinguishable from a pseudo-random function.
HMAC-SHA-1 is such a function, and a common choice. There are other variants of PBKDF2, using HMAC-MD5, HMAC-SHA-256, or other functions (but these variants aren't in the basic Java library).
PBKDF2 takes two data inputs (plus some configuration inputs): the password, and a salt. If you want to include a secret value in the calculation, PBKDF2's input is the place for it: don't tack on a custom scheme on top of that (doing your own crypto is a recipe for doing it wrong). Append the pepper (secret value common to all accounts) to the salt (public value that varies between accounts).
Note that pepper is of limited usefulness. It's only useful if the hashes and the pepper secret value are stored in different places — for example, if the hashes are in a database and the pepper is in a disk file that is not directly vulnerable to SQL injection attacks.

How safe is my password decrypting class?

I'm a complete beginner to any sort of decrypting. I wrote a class that I think should be quite secure. Can you give me constructive criticism of how could I improve the algorithm.
package main;
import java.util.Random;
public class Main {
public static void main(String[] args) {
//we will be playing around with this string
new Main("1234567890abc");
}
private Random rnd;
private byte[] randoms;
/**
* Starts up RNG
* Prints out a test
*/
public Main(String password) {
//random long generated from the password
long randomLong = randomNumber(password);
//Random class using randomLong as seed
rnd = new Random(randomLong);
randoms = new byte[password.length()];
//Array of random bytes generated with rnd
rnd.nextBytes(randoms);
System.out.println(randomNumber(password));
String cryped = encrypt(password);
String decryped = decrypt(cryped);
System.out.println(cryped);
System.out.println(decryped);
}
/**
* Encrypts the password.
*/
private String encrypt(String password) {
char[] chars = password.toCharArray();
for (int i = 0; i < chars.length; i++) {
chars[i] = (char) (chars[i] + randoms[i]);
}
return String.valueOf(chars);
}
/**
* Decrypts an allready encryped password.
*/
private String decrypt(String crypted) {
char[] chars = crypted.toCharArray();
for (int i = 0; i < chars.length; i++) {
chars[i] = (char) (chars[i] - randoms[i]);
}
return String.valueOf(chars);
}
/**
* Finds a random number BASED ON PASSWORD
*/
private long randomNumber(String password)
{
char[] chars = password.toCharArray();
long number = 0;
for (char c : chars) {
number += c;
}
number *= chars.length;
return number;
}
}
The class is written in Java but should be readable to anyone.
Don't reinvent your own cryptography in real life (is this an excercise?) Even experts make mistakes. Use something that's been publically scrutinized.
The java random number generator is not cryptographically secure. With a long enough text to encrypt, patterns will emerge that can permit various information leaks upto and including revealing the password (but see point three) and the plaintext.
You use the password to seed the random number generator. This is a standard (and fine) idea, but you do so using an algorithm that is invariant to permutation! i.e. Your encryption treats "sinecure" and "insecure" or other passwords that are anagrams as equivalent (and probably others too). For a strong password of up to 16 letters and no codepoints beyond 255, the highest reachable seed is 255*16*16 = 65280; but there are even fewer possibilities since there are seeds lower than this which are not reachable. On my keyboard, bruteforcing shows just 9734 different seeds for passwords consisting solely of keyboard-writable characters excluding newline (I count 95) of up to 16 characters in length; that's less than 1 bit of entropy per letter.
CodeInChaos has a few additional observations in his answer: you're using a stream cipher (even harder to get right!). You're also encrypting the password which suggests you may be looking for a hash not an encryption function, (or is that just an example?).
By the way if you're trying to store passwords; don't - not even encrypted! See the sony fiasco for why; you may get hacked, you may lose your password database, and your encryption keys may be known to the attacker. Instead, use standard, best-practice password hashing (and prefer a standard preexisting component if possible). Such a system should at least use a secure hash such as sha1 or better; passwords should be individually salted (the salt can be stored plaintext), and the process should be made computationally expensive to make brute-force unattractive. See http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html for details.
Horribly broken in more than one way.
Your key is 64 bit, a bit small for today. But that's the least of your worries for now.
I see a non cryptographic PRNG. You need to use a crypto PRNG.
You're reusing a key in a stream cypher. Stream cyphers are notorious for being hard to use correctly. In this mode of operation it basically behaves like a one-time-pad generated by a PRNG. Once you reuse a key in such a mode, your crypto is broken.
Suppose an attacker knows encrypt(p1) and encrypt(p2). Then he can calculate encrypt(p1)-encrypt(p2) which is identical to p1-p2.
Your effective key size is much smaller than 64bit. The sum of chars in a string is <2^16*length. And for most characters it's even <128. So you're key will usually be a number <1000'000. That's trivial to brute force.
Each element in randoms is a byte i.e. 8 bit. A char is 16 bit. So you're not adding modulo 256. Thus you leak information about the encrypted password.
And to improve it, throw out your own algorithm entirely and use a well know, reviewed algorithm. Inventing your own algorithm is a bad idea unless you're a cryptography expert. And even expert make mistakes relatively often.
And do you really need password decryption (i.e. is it a password store), or is password hashing enough?
My suggestion is to put your master password in a key-derivation-function (PKDF2 is a common choice). Then use the key this function returns to encrypt the rest of your data file using AES.