I was trying to decrypt this hash but with no success. The hash is Y_ZUP7l05osR3kg7T5jTYORC7CNeWA-- and it's BASE64
'=' is replaced with '-'
'+' is replaced with '.'
'/' is replaced with '_'
So it's actually Y/ZUP7l05osR3kg7T5jTYORC7CNeWA== It prints out something strange cöT?¹tæÞH;OÓ`äBì#^X but the length of the strange output string coincide with the length of the input string.
As commenters have said, if it is a hash, you can't "decrypt" it, because it's not really encrypted, but hashed. Hashes are meant to be irreversible "one way" functions. If it's encrypted, you could decrypt it, but you need to know what algorithm it was encrypted with, as well as what key was used. If it really is a hash, you also need to know what hash function was used. You can't decrypt hashes but you can try to brute force guess which string produces the target hash. Base64 is just a character encoding used to more reliably transmit and manipulate the characters produced by the hashing or encryption algorithm.
Your algorithm should be like,
Encode:
$EncodedString = base64_encode( 'Your string' . 'Your hash');
Decode:
$decodedString = base64_decode($EncodedString);
Removal of hash - $decodedString
Related
I'm trying to encrypt some of my passwords using the XOR encryption algorithm. I tested it on CyberChef but I don't know how to convert it from PHP. I look forward to helping. Thanks a lot.
XOR HEX string 32
It helps to start with the basic data structures involved.
Your objective is to use a secret key to transform your plain text -- the message you wish to keep secret -- into encrypted text. By definition your plain text is easy for an adversary to understand, and your encrypted text is not.
Then, the rest of your objective is to use the key to transform the encrypted text back into plain text. XOR is a symmetric cipher: it uses exactly the same key to encrypt and to decrypt.
Basic data structures
You have text strings like ATTACK for example.
You have arrays like
array( 65, 84, 84, 65, 67, 75)
And you have base 64 encoded strings like
base64_encode( "ATTACK" ); //QVRUQUNL
Your data structures
Let's say your message is ATTACK. (This kind of crypto started with military applications, of course.) That's an array of numbers. Your php example converts your message into an array of ASCII character values. This little bit of code does that. It uses the ord() function to convert a letter into a number, called a codepoint. Run it.
$plaintext = 'ATTACK';
$plaintextASCII = [];
foreach( str_split( $plaintext ) as $letter) {
$plaintextAscii[] = ord( $letter );
}
print_r( $plaintextAscii );
It does the same thing as this line of code from your example, but using an explicit loop rather than the array_map() shortcut.
return array_map('ord', str_split($text));
Then you can mangle that array of character values. The XOR cipher is a way to do that.
Finally you convert it back to a string using the chr() function.
$encryptedString = '';
foreach ( $plaintextAscii as $codepoint ) {
$encryptedString .= chr( $codepoint );
}
But, because you mangled your codepoints to encrypt them, this $encryptedString contains non-printable characters. So you cannot just paste the string into an email or something like that. Instead, you must encode the string using only printable characters.
base64_encode( $encryptedString );
That's the encrypted message. To decrypt it you reverse the process.
That should get you started understanding this example code.
Pro tip when trying to understand an algorithm, don't try to use open-source packages. Instead, look at their code and copy the interesting lines into your own sample code.
Pro tip get a decent debugger program so you can step through your code.
Online security tip do not, repeat not, use this kind of encryption to store peoples' passwords online. It's not secure enough to slow down cybercreeps. php has a really good set of password-hashing functions. Read about them here.
I'm trying to implement the Google Safebrowsing update API v4 in PHP.
But I can't figure how to correctly decode the rawHashes.
(The rawHashes are 4-bytes-truncated sha256 hashes and then concatenated).
I am trying the native base64_decode of PHP but I can't fully decode the string, and I don't know what the next step is.
According to the API documentation here's how the rawhashes are encoded :
string (bytes format)
The hashes, in binary format, concatenated into one long string. Hashes are sorted in lexicographic order. For JSON API users, hashes are base64-encoded.
A base64-encoded string.
I an very simply decoding the string like so:
$decoded = base64_decode($rawHashes);
The base64 encoded string look like this:
"AAAIYAAAC90AABOxAAAjDgAALZIAAEbKAABIHwAA..."
And the base64 decoded string look like this:
b"\x00\x00\x08`\x00\x00\vÝ\x00\x00\x13±\x00\x00#\x0E\x00\x00-’\x00\x00FÊ\x00\x00H\x1F\x00\x00^\x06\x00\x00bF\x00\x00h²"
As you can see something is not right and I must have missed a step but I can't figure which one.
As Mjh said in the discussion nothing is wrong about base64_decode and nothing else is needed.
Nothing's wrong. You just aren't reading carefully. Here, read what it says: The hashes, in binary format. It says binary format. After decoding, you got binary representation of the data. Using bin2hex should return a human-readable hash. $hash = bin2hex(base64_decode($your_encoded_hash)); - Mjh
The decoded string was looking weird as it is binary data (Raw SHA256 hash) although it is totally correct. To get the hashes in a more convenient encoding it's possible to convert the binary represented data to hex represented data with the php function bin2hex
$hash = bin2hex(base64_decode($your_encoded_hash));
From what I know of base64_decode, it just works. Something must be wrong in your $rawHashes string. If you have line breaks in your string, you need to get rid of them by replacing them with an empty string. The hash that base64_decode needs should be one long line of base64 encoded string. It is not uncommon to receive a hash that is broken into multiple lines.
Try this ...
$decoded = base64_decode(str_replace(PHP_EOL, "", $rawHashes));
I want a string to sha1 encoding, then to hex, with a length of 40 characters. This is a Java webservice and the client side is to be done with PHP.
Original code is Java (I don't have the source, only the documentation) and it hashes the following string:
chNFe=43120910585504000174650010000000541123456781&nVersao=100&tpAmb=2&
dhEmi=323031322d30392d32375431363a32303a33342d30333a3030&vNF=1000.00&vICMS=180.00&digVal=37327151612b623074616f514f3966414a7766646c5875715176383d&cIdToken=0000011058550420130001
To the following hex:
3FACB55248244D98C658FC8A826413BCEF10A4AE
The example above is from the webservice documentation and it says string was encoded with sha1, then the result was encoded to hex.
I tried sha1 then dechex and many other ways, but cannot get the same result. Has anyone an idea of what type of encoding PHP have to do to get this hash?
Thank you.
The NFE manual is wrong. The example String has a white space at the end of string..
where appears
5176383d&cIdToken=000001105855042013000 is really
5176383d &cIdToken=000001105855042013000
Convencional functions the cript this using sha1 resolves the problem ;)
in mysql you can do :
sha1(yourExampleString)...
in php could have the something like...
The following code returns the same encrypted password whichever way round. Why and how do we stop this.
$pwd = 'shits8888';
$salt = '50153fc193af9';
echo crypt($pwd,$salt)
Obviously something is missing as this is returning the same thing
$pwd = 'shits8888hjhfgnsdkjf8744884';
$salt = '50153fc193af9';
echo crypt($pwd,$salt)
The standard DES-based crypt() returns the salt as the first two characters of the output. It also only uses the first eight characters of str, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).
http://php.net/manual/en/function.crypt.php
If you want more control over the algorithm used for hash, I suggest you take a look at mcrypt.
Note also that crypt() (despite the name) does not actually encrypt a string, it just generates a hash. If you are specifying the salt, which you are presumably also storing somewhere, you might do better with something like this:
function my_crypt ($string, $salt) {
return sha1($string.$salt); // ...or your hashing function of choice
}
Referenced from the manual:
The standard DES-based crypt() returns the salt as the first two characters of the output. It also only uses the first eight characters of str, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).
Both entries have got the same first 8 characters and the same salt. so it must return the same result.
For example:
echo crypt('12345678xxxxx','50153fc193af9');
echo crypt('12345678yyyyyy','50153fc193af9');
will both return 50gyRGMzn6mi6
because they share the same salt and the same first 8 characters
Every encryption algorithm has got a limit, even md5 gets repeated at some point.
What is the best way of generating a hash for the purpose of storing a session? I am looking for a lightweight, portable solution.
bin2hex(mcrypt_create_iv(22, MCRYPT_DEV_URANDOM));
mcrypt_create_iv will give you a random sequence of bytes.
bin2hex will convert it to ASCII text
Example output:
d2c63a605ae27c13e43e26fe2c97a36c4556846dd3ef
Bare in mind that "best" is a relative term. You have a tradeoff to make between security, uniqueness and speed. The above example is good for 99% of the cases, though if you are dealing with a particularly sensitive data, you might want to read about the difference between MCRYPT_DEV_URANDOM and MCRYPT_DEV_RANDOM.
Finally, there is a RandomLib "for generating random numbers and strings of various strengths".
Notice that so far I have assumed that you are looking to generate a random string, which is not the same as deriving a hash from a value. For the latter, refer to password_hash.
random_bytes() is available as of PHP 7.0 (or use this polyfill for 5.2 through 5.6). It is cryptographically secure (compared to rand() which is not) and can be used in conjunction with bin2hex(), base64_encode(), or any other function that converts binary to a string that's safe for your use case.
As a hexadecimal string
bin2hex() will result in a hexadecimal string that's twice as many characters as the number of random bytes (each hex character represents 4 bits while there are 8 bits in a byte). It will only include characters from abcdef0123456789 and the length will always be an increment of 2 (regex: /^([a-f0-9]{2})*$/).
$random_hex = bin2hex(random_bytes(18));
echo serialize($random_hex);
s:36:"ee438d1d108bd818aa0d525602340e5d7036";
As a base64 string
base64_encode() will result in a string that's about 33% longer than the number of random bytes (each base64 character represents 6 bits while there are 8 bits in a byte). It's length will always be an increment of 4, with = used to pad the end of the string and characters from the following list used to encode the data (excluding whitespace that I added for readability):
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
/+
To take full advantage of the space available, it's best to provide an increment of 3 to random_bytes(). The resulting string will match /^([a-zA-Z\/+=]{4})*$/, although = can only appear at the end as = or == and only when a number that is not an increment of 3 is provided to random_bytes().
$random_base64 = base64_encode(random_bytes(18));
echo serialize($random_base64);
s:24:"ttYDDiGPV5K0MXbcfeqAGniH";
You can use PHP's built-in hashing functions, sha1 and md5. Choose one, not both.
One may think that using both, sha1(md5($pass)) would be a solution. Using both does not make your password more secure, its causes redundant data and does not make much sense.
Take a look at PHP Security Consortium: Password Hashing they give a good article with weaknesses and improving security with hashing.
Nonce stands for "numbers used once". They are used on requests to prevent unauthorized access, they send a secret key and check the key each time your code is used.
You can check out more at PHP NONCE Library from FullThrottle Development
Maybe uniqid() is what you need?
uniqid — Generate a unique ID
You can use openssl_random_pseudo_bytes since php 5.3.0 to generate a pseudo random string of bytes. You can use this function and convert it in some way to string using one of these methods:
$bytes = openssl_random_pseudo_bytes(32);
$hash = base64_encode($bytes);
or
$bytes = openssl_random_pseudo_bytes(32);
$hash = bin2hex($bytes);
The first one will generate the shortest string, with numbers, lowercase, uppercase and some special characters (=, +, /). The second alternative will generate hexadecimal numbers (0-9, a-f)
Use random_bytes() if it's available!
$length = 32;
if (function_exists("random_bytes")) {
$bytes = random_bytes(ceil($length / 2));
$token = substr(bin2hex($bytes), 0, $length)
}
Check it on php.net
I personally use apache's mod_unique_id to generate a random unique number to store my sessions. It's really easy to use (if you use apache).
For nonce take a look here http://en.wikipedia.org/wiki/Cryptographic_nonce there's even a link to a PHP library.
I generally dont manually manage session ids. Ive seen something along these lines recommended for mixing things up a bit before, ive never used myself so i cant attest to it being any better or worse than the default (Note this is for use with autogen not with manual management).
//md5 "emulation" using sha1
ini_set('session.hash_function', 1);
ini_set('session.hash_bits_per_character', 5);
Different people will have different best ways. But this is my way:
Download this rand-hash.php file :
http://bit.ly/random-string-generator
include() it in the php script that you are working with. Then, simply call
cc_rand() function. By default it will return a 6 characters long
random string that may include a-z, A-Z, and 0-9. You can pass
length to specify how many characters cc_rand() should return.
Example:
cc_rand() will return something like: 4M8iro
cc_rand(15) will return something similar to this: S4cDK0L34hRIqAS
Cheers!