I am trying to implement a simple text file encryption technique and I am using the following code to do so. The code is not written by me, I just googled and got it. The encryption technique seems to be pretty simple, concise and easy to implement. I see that it has only one function that can do the encryption and the decryption on the fly. Just pass the key it will do the trick. However, I just wanted to know, is it possible for me to check if the key is passed by the user is correct or not. Currently it will just encrypt / decrypt the text file based on the passed key. But there is no mechanism to check if we are decrypting with correct key or not. Whatever the key we pass, it will get decrypted, but it will not be readable. Any idea how to tackle this problem..?
procedure TEnDeCrypt.EnDecryptFile(pathin, pathout: string; Chave: Word);
var
InMS, OutMS: TMemoryStream;
cnt: Integer;
C: byte;
begin
InMS := TMemoryStream.Create;
OutMS := TMemoryStream.Create;
try
InMS.LoadFromFile(pathin);
InMS.Position := 0;
for cnt := 0 to InMS.Size - 1 DO
begin
InMS.Read(C, 1);
C := (C xor not (ord(chave shr cnt)));
OutMS.Write(C, 1);
end;
OutMS.SaveToFile(pathout);
finally
InMS.Free;
OutMS.Free;
end;
end;
Generate a checksum on the plain text using a hashing algorithm and store it at the beginning of the encrypted file.
You can verify the key by hashing the decrypted text and ensure that the checksum matches.
If you use a strong hashing algorithm such as SHA256 to generate the checksum, it will be difficult for the user to automate a brute force attack because it will be computationally expensive.
To ensure that the file is intact, you may also wish to store a checksum on the encrypted file and store it in the file header as well. Otherwise, there will be no way to differentiate an invalid password from a truncated file.
I typically use the Blowfish encryption algorithm, which is available for Delphi from multiple sources. Blowfish has no known weaknesses and is fairly compact and fast.
If you are aware of the kind of content your file will have (whether it is a binary file / text file etc), then you can sample the text and see if there are any non-ASCII or characters that are not expected in the file after decryption.
Another thing you can do is to add a watermark text at the end of the file. After decryption, you can check if your watermark is containing data that is outside the expected data-type (if you are expecting only characters and you see a non-char data in it, then there is possibly an issue). This though is not fool-proof, just a sort of a buffer for you.
That said, I will ask you this question - what is the intent behind this? The key the user is passing is to encrypt; so if the user is passing an invalid key, then they get invalid output. Why do you need to steer the user towards the right key? And if there is some business use-case for something like that, then you also need to understand that this is going to make your encryption very easy to break. I will suggest that you pick up a standard encryption algorithm and use that to encrypt your file.
The correct way to do what you are asking for is to Encrypt-then-Authenticate the data. There is some relevant discussion here: Should we MAC-then-encrypt or encrypt-then-MAC?
The conventional way is to first use a standard cipher in a standard mode, such as AES in CBC mode, and then calculate a HMAC (such as HMAC-SHA256) over the cipher text. There are also some cipher modes, such as CCM, EAX, GCM, that will perform both encryption and authentication.
Do not use a hash instead of a HMAC for this.
The key you use for encryption must be independent from the key you use for authentication. You could e.g. generate both randomly, but absolutely not using the System.Random function. If you are deploying to Vista SP2 or later, you could use CryptGenRandom from the Windows API, but otherwise you should use a cryptographic library with support for cryptographic random number generation.
If you use password based encryption, use a PBKDF2 implementation for deriving the encryption key and authentication key. There are four common ways to ensure the two keys are independent:
Use two separate Salt values;
Use a single salt but concatenate it with separate "labels", e.g. the strings 'E' and 'A' respectively,
Generate a twice as long derived key and use one half as encryption key and the other half as authentication key, or
Let the derived key be a "key encryption key" you use for encrypting randomly generated encryption keys and authentication keys.
Related
I have a string that was salted, hashed with SHA-256, then base64 encoded. Is there a way to decode this string back to its original value?
SHA-256 is a cryptographic (one-way) hash function, so there is no direct way to decode it. The entire purpose of a cryptographic hash function is that you can't undo it.
One thing you can do is a brute-force strategy, where you guess what was hashed, then hash it with the same function and see if it matches. Unless the hashed data is very easy to guess, it could take a long time though.
You may find the question "Difference between hashing a password and encrypting it" interesting.
It should be noted - Sha256 does not encrypt the data/content of your string, it instead generates a fixed size hash, using your input string as a seed.
This being the case - I could feed in the content of an encyclopedia, which would be easilly 100 mb in size of text, but the resulting string would still be 256 bits in size.
Its impossible for you to reverse the hash, to get that 100mb of data back out of the fixed size hash, the best you can do, is try to guess / compute the seed data, hash, and then see if the hash matches the hash your trying to break.
If you could reverse the hash, you would have the greatest form of compression to date.
SHA* is a hash function. It creates a representation (hash) of the original data. This hash is never intended to be used to recreate the original data. Thus it's not encryption. Rather the same hash function can be used at 2 different locations on the same original data to see if the same hash is produced. This method is commonly used for password verification.
You've done the correct thing by using a salt aka SSHA.
SHA and SHA-2 (or SHA-256) by itself without a salt are NOT considered secure anymore! Salting a SHA hash is called Salted SHA or SSHA.
Below is a simple example on how easily it is to de-hash SHA-1. The same can be done for SHA-2 without much effort as well.
Enter a password into this URL:
http://www.xorbin.com/tools/sha1-hash-calculator
Copy paste the hash into this URL:
https://hashes.com/en/decrypt/hash
Here's a page which de-hashes SHA-2. The way this pages works is somebody must have hashed your password before, otherwise it won't find it:
md5hashing dot net/hashing/sha256
Here's a page that claims to have complete SHA-2 tables available for download for a "donation" (I haven't tried it yet):
crackstation dot net/buy-crackstation-wordlist-password-cracking-dictionary.htm
Here's a good article that explains why you have to use SSHA over SHA:
crackstation dot net/hashing-security.htm
I'm using the DCPcrypt library in Delphi 2007 for encrypting text for an in-house app.
I'm currently using the following code (not my actual key):
Cipher := TDCP_rijndael.Create(nil);
try
Cipher.InitStr('5t#ck0v3rf10w', TDCP_md5);
Result := Cipher.EncryptString('Test string');
finally
Cipher.Burn;
Cipher.Free;
end;
The comment for InitStr is:
Do key setup based on a hash of the key string
Will exchanging the MD5 algorithm for, say, SHA2-256 or SHA2-512 make any theoretical or actual difference to the strength of the encryption?
The direct answer to your question is 'No' - it won't make any appreciable difference to cryptographic strength. Yes, MD5 is broken, but really it's weakness does not make any difference in this particular application. AES has key sizes of 128, 192 and 256 bits. All you are doing here is creating a string pseudonym for a key (being either 16 bytes, 24 bytes or 32 bytes). When cryptographic experts say that a hash function is broken, what they mean by this is that given a known hash output, it is feasible to compute a message different from the original message, which also hashes to the same output. In other words, in order for the cryptographic strength or weakness of the hash function to have any meaning, the binary key must already be known to the malicious party, which means that it is only relevant when your security is already completely defeated.
The strength of the hashing algorithm is COMPLETELY irrelevant to the strength of the asymmetric cipher.
However...
However, of a much more serious concern is the lack of salting in your code. Unless you plan to manually salt your message (unlikely), your communications are very vulnerable to replay attack. This will be infinity worse if you use ECB mode, but without salting, it is a major security issue for any mode. 'Salting' means injecting a sufficiently large non-predictable non-repeating value in either the IV or at the head of the message before encryption.
This highlights a huge problem with DCPCrypt. Most users of DCPcrypt will not know enough about cryptography to appreciate the importance of proper salting, and will use the crypto component in exactly the way you have. When you use DCPcrypt in this way (which is very natural), DCPcrypt does NOT salt. In fact, it sets the IV to zero. And it gets worse... If you have chosen a key-streaming type of chaining mode (which is very popular), and your IV is habitually zero, your security will be completely and utterly broken if a single plaintext message is known or guessed, (OR even just a fragment of the message is guessed). DCPcrypt does offer an alternative way to initialize a binary key (not from string), together with allowing the user to set the IV (you must generate a random IV yourself). The next problem is that the whole IV management gets a bit complicated.
Disclosure
I am the author of TurboPower LockBox 3. Dave Barton's DCPcrypt, an admirable and comprehensive engineering work, was one of my inspirations for writing LockBox 3.
You should specify the type of attack on your encryption; suppose known-plaintext attack is used, and intruder uses precomputed hash values to find key string - then there should be no difference between the hash algorithms used, any hash algorithm will require nearly the same time to find key string.
I'm trying to find a bcrypt implementation I can use in Delphi. About the only useful thing that Googling brings me is this download page, containing translated headers for a winapi unit called bcrypt.h. But when I look at the functionality it provides, bcrypt.h doesn't appear to actually contain any way to use the Blowfish algorithm to hash passwords!
I've found a few bcrypt implementations in C that I could build a DLL from and link to, except they seem to all require *nix or be GCC-specific, so that won't work either!
This is sorta driving me up the wall. I'd think that it would be easy to find an implementation, but that doesn't seem to be the case at all. Does anyone know where I could get one?
Okay, so i wrote it.
Usage:
hash: string;
hash := TBCrypt.HashPassword('mypassword01');
returns something like:
$2a$10$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm
The useful thing about this (OpenBSD) style password hash is:
that it identifies the algorithm (2a = bcrypt)
the salt is automatically created for you, and shipped with the hash (Ro0CUfOqk6cXEKf3dyaM7O)
the cost factor parameter is also carried with the hash (10).
To check a password is correct:
isValidPassword: Boolean;
isValidPassword := TBCrypt.CheckPassword('mypassword1', hash);
BCrypt uses a cost factor, which determines how many iterations the key setup will go though. The higher the cost, the more expensive it is to compute the hash. The constant BCRYPT_COST contains the default cost:
const
BCRYPT_COST = 10; //cost determintes the number of rounds. 10 = 2^10 rounds (1024)
In this case a cost of 10 means the key will be expanded and salted 210=1,024 rounds. This is the commonly used cost factor at this point in time (early 21st century).
It is also interesting to note that, for no known reason, OpenBSD hashed passwords are converted to a Base-64 variant that is different from the Base64 used by everyone else on the planet. So TBCrypt contains a custom base-64 encoder and decoder.
It's also useful to note that the hash algorithm version 2a is used to mean:
bcrypt
include the password's null terminator in the hashed data
unicode strings are UTF-8 encoded
So that is why the HashPassword and CheckPassword functions take a WideString (aka UnicodeString), and internally convert them to UTF-8. If you're running this on a version of Delphi where UnicodeString is a reserved word, then simply define out:
type
UnicodeString = WideString;
i, as David Heffernan knows, don't own Delphi XE 2. i added the UnicodeString alias, but didn't include compilers.inc and define away UnicodeString (since i don't know the define name, nor could i test it). What do you want from free code?
The code comprises of two units:
Bcrypt.pas (which i wrote, with embedded DUnit tests)
Blowfish.pas (which Dave Barton wrote, which i adapted, extended, fixed some bugs and added DUnit tests to).
Where on the intertubes can i put some code where it can live in perpetuity?
Update 1/1/2015: It was placed onto GitHub some time ago: BCrypt for Delphi.
Bonus 4/16/2015: There is now Scrypt for Delphi
I'm implementing RSACryptoToken, that is an interface for RSA cryptographic tokens, according to the documentation.
There are twp methods, called decryptRSA and signRSA - they should be implemented.
In documentation there is an info, that they should perform a raw RSA decryption and raw RSA signing operations.
What means raw RSA operation?
Does it mean, without padding?
Does BlackBerry or Bouncy Castle provides such API?
Basically PKCS#1 v1.5 consists of three parts:
the RSA operations themselves,
the PKCS#1 padding and
an ASN.1 encodign of the hash.
The hash is ASN.1 encoded to include an ASN.1 Object Identifier which uniquely specifies the hash that is used, and the value, like this:
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
This is directly copied from the PKCS#1 specifications (which are pretty readable and publicly available). Note that the encoding is directly specified as bytes as well in the standards.
Blackberry operations only provide 1) and 2), meaning that you have to supply an ASN.1, DER encoded structure containing the hash yourself. No such a structure is defined for the encryption/decryption, only the padding is removed.
Encryption uses random padding (internally) versus non-random padding for signatures. This allows you to encrypt "YES" twice, while an eavesdropper cannot detect if it is YES or NO. The padding is also required to protect the signature against attacks.
I solved the problem, the operations signRSA and decryptRSA should perform the same pure modulus operation
thanks for help
I have a user model on my app, and my password field uses sha1. What i want is to, when i get the sha1 from the DB, to make it a string again. How do i do that?
You can't - SHA1 is a one-way hash. Given the output of SHA1(X), is not possible to retrieve X (at least, not without a brute force search or dictionary/rainbow table scan)
A very simple way of thinking about this is to imagine I give you a set of three-digit numbers to add up, and you tell me the final two digits of that sum. It's not possible from those two digits for me to work out exactly which numbers you started out with.
See also
Is it possible to reverse a sha1?
Decode sha1 string to normal string
Thought relating MD5, these other questions may also enlighten you:
Reversing an MD5 Hash
How can it be impossible to “decrypt” an MD5 hash?
You can't -- that's the point of SHA1, MDB5, etc. Most of those are one-way hashes for security. If it could be reversed, then anyone who gained access to your database could get all of the passwords. That would be bad.
Instead of dehashing your database, instead hash the password attempt and compare that to the hashed value in the database.
If you're talking about this from a practical viewpoint, just give up now and consider it impossible. Finding the original string is impossible (except by accident). Most of the point of a cryptographically secure hash is to ensure you can't find any other string that produces the same hash either.
If you're interested in research into secure hash algorithms: finding a string that will produce a given hash is called a "preimage". If you can manage to do so (with reasonable computational complexity) for SHA-1 you'll probably become reasonably famous among cryptanalysis researchers. The best "break" against SHA-1 that's currently known is a way to find two input strings that produce the same hash, but 1) it's computationally quite expensive (think in terms of a number of machines running 24/7 for months at a time to find one such pair), and does not work for an arbitrary hash value -- it finds one of a special class of input strings for which a matching pair is (relatively) easy to find.
SHA is a hashing algorithm. You can compare the hash of a user-supplied input with the stored hash, but you can't easily reverse the process (rebuild the original string from the stored hash).
Unless you choose to brute-force or use rainbow tables (both extremely slow when provided with a sufficiently long input).
You can't do that with SHA-1. But, given what you need to do, you can try using AES instead. AES allows encryption and decryption.