opessl sha-512 string charset - linux

The utility openssl can be used to generate a sha512 based hash from a given string.
What is the possible range of characters it can produce in output. I mean that what all characters can the result produce. I am not able to find any documentation for the same.
openssl passwd -6
Password:
Verifying - Password:
$6$qJV2Hr9qSOw4/Zxx$pVe4wDNy1mDRIAcPrIWEr0dCzpZQDS2Zb83Ix2pktuCd5jEwvQjO8EiDMFtlAQ/TfYXucKO8qWf9NtLQPbdgi1
The above is an example of sha-512 hashed string using 'openssl'.

What is the possible range of characters SHA-512 can produce?
All 256 possible byte values, like with every other relevant hashing function. However, because the output is effectively random, binary data, hash values are almost always encoded to represent them as plain (ASCII) text. base16 (hex) and base64 are popular. Each encoding has its own alphabet.
$6$qJV2Hr9qSOw4/Zxx$pVe4wDNy1mDRIAcPrIWEr0dCzpZQDS2Zb83Ix2pktuCd5jEwvQjO8EiDMFtlAQ/TfYXucKO8qWf9NtLQPbdgi1
The above is an example of SHA-512 hashed string using 'openssl'
No, not really. It's a password hash in crypt format. The selected mode is based on SHA-512, but the output encodes much more information than just a SHA-512 hash value. To the best of my knowledge there is no formal specification of the crypt format.
Assuming that no parameter pairs are included (which openssl doesn't output as far as I know), the alphabet is that of base64 plus '$' and '.' which serve as separators.
To fully support all possible values in Modular Crypt Format, including those with key-value parameters (as in $md5,rounds=5000$GUBv0xjJ$$mSwgIswdjlTY0YxV7HBVm0) you should probably expect all printable ASCII characters, but at least '=' in addition to those mentioned above.

Related

SHA512 to UTF8 to byte encryption

a question:
A parcel service provider requests that the password is encoded in a specific way:
KEY -> UTF8 Encoding -> SHA512
They KEY should be in byte form, not string
currently I have this in Node.js with CryptoJS:
password = CryptoJS.SHA512(CryptoJS.enc.Utf8.parse(key))
or
password = CryptoJS.SHA512(CryptoJS.enc.Utf8.stringify(key))
Don't know which one is the right one.
I need to convert the key to bytes, how do I do that?
Keys are arbitrary sequences of bytes, and SHA-512 works on arbitrary sequences of bytes. However, UTF-8 can't encode arbitrary sequences of bytes. It can only encode Unicode code points. What you're asking for isn't possible. (I suggest posting precisely what the requirement is. It's possible you're misreading it.)
You need another encoding, such as Base64 or Hex. The output of either of those is compatible with UTF-8 (they both output subsets of UTF-8).
That said, this is a very strange request, since you already have exactly the correct input for SHA-512. Converting it to a string and then converting that string back to (likely different) bytes seems a pointless step, but if you need it, you'll need a byte encoding like Base64 or Hex.

hashing passwords with pbkdf2 crypto does not work correctly

Password security is not my strong suit. Please help me out.
I use node.js 4.2.3 express 4.13.3. I found some examples to hash and salt passwords with crypto's pbkdf2.
Here is my code.
var salt = crypto.randomBytes(10).toString('base64');
console.log("salt > "+salt);
crypto.pbkdf2(pass, salt , 10000, 150, 'sha512',function(err, derivedKey) {
pass = derivedKey.toString('hex');
});
The final derivedKey does not include the salt. What am I missing? Should I join the two strings manually before saving?
Why some examples use base64 and others hex? To get different string lenghts? What is the default, so I can use it?
Why not to use basic64 in both salt and hashed password?
Is the final derivedKey string UTF8? Or this has to do only with the database it gets saved? My database is in UTF8.
Thanks
Yes, store the salt yourself, separately, unencrypted. Make sure it's randomly generated.
More importantly, you're crippling your PBKDF2 encryption by asking for 150 bytes (bytes per nodejs.org) of key length - SHA512 is a fantastic choice, but it only provides 64 bytes of native output. To get 10,000 iterations of 150 bytes of output, PBKDF2/RFC2898 is going to execute 30,000 times, while an offline attacker will only need to run 10,000 iterations and match the first 64 bytes (if the first 64 match, then the rest will too); you gave them a 3:1 advantage for free!
Instead, if you're happy with the work factor, you should use 30,000 iterations of 64 bytes of output - you'll spend the same amount of time, no difference, but the attacker now has to do 30,000 iterations too, so you took away their 3:1 advantage!
When you pass the salt to the PBKDF2 function, if you can, just pass in the pure binary. Also, the node.js docs say - reasonably "It is recommended that the salts are random and their lengths are greater than 16 bytes." This means binary 16 bytes, before the base64 or hex or whatever conversion if you want one.
You can save both salt and derivedkey as BINARY of the correct length for the most efficient storage (then you don't have to worry about UTF-x vs. ASCII), or you can convert one or both to BASE64 or hexadecimal, and then convert back to binary as required. Base64 vs hex vs binary is irrelevant as long as the conversions are reconverted as needed.
I'd also make the number of iterations a stored field, so you can easily increase it in the years to come, and include a field for the "version" of password hashing used, so you can easily change your algorithm in the years to come if need be as well.
Encryption works with data, not strings, this includes the encryption key. PBKDF2 produces a data key, which can be easily converted to a string, this conversion is necessary because many data bytes have no corresponding print character or unicode code point. Many scripting languages do not handle data well so the data is many times converted to Base64 or hexadecimal (hex).
You can use Base64 or hexadecimal for the salt and hashed password, just be consistent on all uses.
The salt and iteration count need to be the same for creating an checking, you will need to combine them or save them separately.
Your code is converting the derived key to hexadecimal, that is fine and base64 would also be fine. Again this is necessary because not all data bytes are UTF-8.

Determining Hash used to encrypt strings

I am trying to determine the hash used to encrypt the following strings. From the length of the strings I gather it is a 32 bit hash however Adler32 and CRC32 do not give me the same values.
The original string and hashed value are as follows:
0145 : 68333235
0231 : F538CBE5
0343 : E16BE4A9
Any help would be appreciated.
NO, it's not a encrypted string that you will decrypt and find out. Rather it's a hashed string value of the original string and the best way to match is to generate hash value again using the same (or available's) hashing technique and compare the generated hash value to confirm it.

Which encryption method would produce this result

I am doing a security review on a system.
From one part of the system to another, information is sent using an encrypted string.
This string is over 400 characters long, but within it are 4 sets of 10 identical characters. I am assuming that the data that was encrypted also has this pattern, for example the word "parameters".
I have tested encrypting a string containing several identical strings with DES, but do not get the same pattern.
Question is: Is there an encryption method that would produce this result. Or have the parts been encrypted seperatly and conncatinated?
An encryption system with short key length and no correlation between blocks (e.g. ECB mode) would encrypt short runs of identical plain text identically. It could also just be coincidence, of course.
If what you're seeing is real, it's mostly about encryption mode, not the cipher. Likely culprits are a block cipher in ECB mode (which is usually a bad idea), or the pseudo-"stream" cipher of XORing the plaintext with a short password string repeated over and over (in which case the odds of two copies of the same plaintext at random positions encoding to the same thing are 1 in passwordlength) this one is a really bad idea.
By the way, it's best to be clear what format you're looking at the data in. If it's hex, okay. If it's base64, you should decode it before you look at it -- identical strings won't always look identical after base64 encoding depending on their alignment to a 3-byte boundary.
And just for illustration, here's a discussion of ECB mode on Wikipedia including pictures of the entropy problem with ECB -- scroll down to the pictures of Tux.
What do you mean with "4 sets of 10 identical characters"?
If you mean 4 identical substrings with length 10, it may be the Caesar cipher, which is totally unsecure, as it can be deciphered by a human in no time. Another possibility is the use of an XOR cipher with a bad chosen key.

How should I create my DES key? Why is an 7-character string not enough?

I'm having a bit of difficulty getting an understand of key length requirements in cryptography. I'm currently using DES which I believe is 56 bits... now, by converting an 8 character password to a byte[] my cryptography works. If I use a 7 digit password, it doesn't.
Now, forgive me if I'm wrong, but is that because ASCII characters are 7 bits, therefor 8 * 7 = 56bits?
That just doesn't seem right to me. If I want to use a key, why can I not just pass in a salted hash of my secret key, i.e. an MD5 hash?
I'm sure this is very simple, but I can't get a clear understanding of what's going on.
DES uses a 56-bit key: 8 bytes where one bit in each byte is a parity bit.
In general, however, it is recommended to use an accepted, well-known key derivation algorithm to convert a text password to a symmetric cipher key, regardless of the algorithm.
The PBKDF2 algorithm described in PKCS #5 (RFC 2898) is a widely-used key derivation function that can generate a key of any length. At its heart, PBKDF2 is combining salt and the password through via a hash function to produce the actual key. The hash is repeated many times so that it will be expensive and slow for an attacker to try each entry in her "dictionary" of most common passwords.
The older version, PBKDF1, can generate keys for DES encryption, but DES and PBKDF1 aren't recommended for new applications.
Most platforms with cryptographic support include PKCS #5 key-derivation algorithms in their API.
Each algorithm is designed to accept a certain key length. The key is used as part of the algorithm, and as such, can't be whatever your heart desires.
Common key sizes are:
DES: 56bit key
AES: 128-256bit key (commonly used values are 128, 192 and 256)
RSA (assymetric cryptography): 1024, 2048, 4096 bit key
A number, such as 1234567 is only a 4-byte variable. The key is expected to be a byte array, such as "1234567" (implicitly convertible to one in C) or `{ '1', '2', '3', '4', '5', '6', '7' }.
If you wish to pass the MD5 hash of your salted key to DES, you should use some key compression technique. For instance, you could take the top 7 bytes (somewhat undesirable), or perform DES encryption on the MD5 hash (with a known constant key), and take all but the last byte as the key for DES operation.
edit: The DES I'm talking about here is the implementation per the standard released by NIST. It could so be (as noted above), that your specific API expects different requirements on the length of the key, and derives the final 7-byte key from it.
The key must have size 64-bits but only 56-bits are used from the key. The other 8-bits are parity bits (internal use).
ASCII chars have 8-bit size.
You shouldn't pass you passwords straight into the algorithm. Use for instance the Rfc2898DeriveBytes class that will salt your passwords, too. It will work with any length.
Have a look here for an example.
EDIT: D'Oh - your question is not C# or .Net tagged :/
According to MSDN DES supports a key length of 64 bits.
To avoid this issue and increase the overall security of one's implementation, typically we'll pass some hashed variant of the key to crypto functions, rather than the key itself.
Also, it's good practice to 'salt' the hash with a value which is particular to the operation you are doing and won't change (e.g., internal userid). This assures you that for any two instances of the key, the resulting has will be different.
Once you have your derived key, you can pull off the first n-bites of it as required by your particular crypto function.
DES requires a 64 bit key. 56 bits for data and 8 bits for parity.
Each byte contains a parity bit at the last index. This bit is used to check for errors that may have occurred.
If the sum of the 7 data bits add up to an even number the correct parity bit is 0, for an odd number it's 1.
ASCII chars contain 8 bits, 8 chars can be used as a key if error correction is not necessary. If EC is necessary, use 7 chars and insert parity bits at indices (0 based) 7,15,23,31,39,47,55,63.
sources:
Wikipedia: https://en.m.wikipedia.org/wiki/Data_Encryption_Standard
“The key ostensibly consists of 64 bits; however, only 56 of these are actually used by the algorithm. Eight bits are used solely for checking parity, and are thereafter discarded. Hence the effective key length is 56 bits.”
“The key is nominally stored or transmitted as 8 bytes, each with odd parity. According to ANSI X3.92-1981 (Now, known as ANSI INCITS 92-1981), section 3.5:
One bit in each 8-bit byte of the KEY may be utilized for error detection in key generation, distribution, and storage. Bits 8, 16,..., 64 are for use in ensuring that each byte is of odd parity.”

Resources