Hash = Encryption???

If a user-entered string is hashed to display the MD5 / SHA-1 / SHA-256 / SHA-512 equivalent - does that count as encryption?
I am concerned about the legalities of encrypting text using certain algorithms in certain countries - and have no idea if hashing a text string into these formats is labelled as encryption?

I understand they are hashes, but surely if the text string is converted into a non-readable format (SHA-512 for example) - that would be classed as encryption?

Here is my code I am using to display entered text as SHA-512:

Dim SHA512Hash As String = Crypto.Hash(EnteredStringField.text, Crypto.Algorithm.SHA512)

Hope someone here can clarify for me.

Thank you all in advance.

No, hash is a one-way process. There’s no way to get the original content from a hash (except brute-force and hash-matching). This is not encryption. Think of a hash like a checksum. It just validates/invalidates a piece of information.

For example a REALLY simple hash might be “add up all the ascii values in the string presented and return the sum (with roll overs etc)”

So in the string ABC you would get a hash of ASC(“A”) + ASC(“B”) + ASC(“C”)
But if you use something quite this simple you can see that the hash of CBA and BCA could also give the same hash value :slight_smile:
So there’s no way you could know which of the three was originally input to create the hash value.
Therein lies one of the limitations of hashes.
They take a potentially VERY large input space (the list of all possible strings) and return a subset of that (an SHA1, MD5 etc of limited length) So they take a potentially infinite input set & create a smaller set from it so there WILL be collisions - hacker tend to use that knowledge to their advantage.
So there are things people do to the input value to make it harder for hackers - one is known as salting.

But no a hash is not encryption in that sense.
Encryption implies you CAN recover the original given the encrypted version
Hashes don’t do that.

Thanks guys.
I was reading up on it before I posted the question here, and understood that in gereral - a hash is one way and encryption is 2 way (can be decrypted). This is confirmed by both of you :slight_smile:

I am still unsure however, if it is illegal in any countries to hash a string?
I know certain encryption algorithms are illegal in some countries, but have no idea what the situation is regarding hashes?


Is it illegal anywhere to use encryption, or to allow your users to encrypt their own data? I always thought these laws had to do with the latter, but I admit I’ve never researched it.

In any case, a hash is not encryption so making it illegal would make as much sense as making the formula “2+2” illegal. (Not a formal legal opinion.)

I’m also not 100% sure, but I am pretty sure someone knowledgeable said that certain encryption is illegal, so developers need to be aware? Maybe I just dreamt it??

So nobody here has ever heard of getting into legal trouble by displaying a hash? Hope not :slight_smile:


Never heard of hashes being illegal. If hashes were illegal, then git repositories would be problematic since git uses SHA-1 hashes to version commits.

AFAIK encryption is not illegal anywhere ; maybe in North Korea, but I doubt it is of your immediate concern.

Exporting from the United States encryption technology is illegal to embargoed countries such as Cuba and “rogue states”. Export of cryptography from the United States - Wikipedia

But because the US Homeland Security wants to control that nobody exports cryptography, the Mac Apple Store has to ask if an app uses encryption and control nobody is going to run to Cuba with it.

For all intents and purposes, a European citizen should not have to fear using encryption in his apps for domestic use. If it where not for encryption, how would we protect our passwords, and how would the electronic banking systems work ?

I was asking because it is always better to be safe than sorry :slight_smile:

Its usually not the encryption that is illegal but the export of certain encryption algorithms as they may be considered “munitions” (or were at one time)


I’m just glad that no one outside of the USA is smart enough to create their own encryption algorithm. The world is safe.

You have to encrypt certain user data as it is saved into your databases. Assume someone will steal it, but that no one can benefit from the theft.

[quote]create their own encryption algorithm[/quote] That’s basically what I did, using the crypto.pbkdf2 function as the keystream/pad generator (which is perfect, since you can create a hash of a given length, so you create the keystream/pad the same length of the data you’re passing to it). I originally ported of RC4 to RealBasic along time ago (http://permalink.gmane.org/gmane.comp.lang.realbasic.forums/6254) [seems the old realbasic forums are currently down, but accessible through that link]. Anyhow, creating your own encryption is frowned upon in the security sector. There’s so many things that you can do wrong, etc. and the outcomes all look the same which gives the illusion that your method is secure… when it most likely isn’t. For those truly interested in cryptography, Coursera (https://www.coursera.org/course/crypto) offers a FREE class (which I highly recommend). I’m posting the encryption methods below for anybody that want to use them (it’s extremely simple code). I use the SALT as the size of the plainText being passed to it, but you can change it to a fixed constant. I also added an integrity checksum AFTER the encryption process, to better insure the cipherText passed to the decipher function is a legitimate cipher which hasn’t been altered to tampered with. This only HELPS insure the integrity of the cipher, it does not validate whether the cipherPass or cipherIterations passed to it are correct. If you pass the wrong of either of those, it still return data… just not the original plainText.

[code]Function cipher(plainText as memoryBlock, cipherPass as memoryBlock, cipherIterations as uInt32) As memoryBlock

// - :cipher
// -
// - developer(s): eric d. brown
// - definition: decrypts content previously encrypted by using [self.cipher]; validates integerity checksum
// - revision: 2014.10.01
// - platform(s): *

const BYTE_OFFSET = 1

dim checksumContent as memoryBlock
dim cipherContent as memoryBlock
dim cipherPad as memoryBlock
dim contentIndex as uInt32

cipherContent = new memoryBlock(plainText.size) 'reserve buffer size; equals size of [plainText]

// - construct [cipherPad] from a hash variation of [cipherPass]
// - uses the size of [plainText] as the SALT
// - equals the size of and XOR’d against [plainText] to construct [cipherContent]
cipherPad = crypto.pbkdf2(str(plainText.size), cipherPass, cipherIterations, plainText.size, crypto.algorithm.sha512)

// - iterate and XOR contents of [plainText] with [cipherPad] to construct [cipherContent]
for contentIndex = ZERO_VALUE to plainText.size - BYTE_OFFSET
cipherContent.byte(contentIndex) = bitWise.bitXor(plainText.byte(contentIndex), cipherPad.byte(contentIndex))
next contentIndex

// - construct and append an integrity checksum (size set by [self.CHECKSUM_SIZE] constant)
checksumContent = crypto.pbkdf2(crypto.sha1(cipherContent), cipherContent, self.CHECKSUM_ITERATIONS, self.CHECKSUM_SIZE, crypto.algorithm.sha256)

return cipherContent + checksumContent 'return [cipherContent] with appended integrity checksum [checksumContent]
End Function[/code]

[code]Function deCipher(cipherText as memoryBlock, cipherPass as memoryBlock, cipherIterations as uInt32, byRef plainText as memoryBlock) As boolean

// - :deCipher
// -
// - developer(s): eric d. brown
// - definition: decrypts content previously encrypted by using [self.cipher]; validates integerity checksum
// - revision: 2014.10.01
// - platform(s): *

const BYTE_OFFSET = 1

dim checksumContent as memoryBlock
dim deCipherContent as memoryBlock
dim deCipherPad as memoryBlock
dim contentIndex as uInt32

if cipherText.size <= self.CHECKSUM_SIZE then '[cipherText ] is not a valid cipher; too short
return false
end if

// - construct validation checksum from contents of [cipherText], excluding the appended checksum itself
checksumContent = crypto.pbkdf2(crypto.sha1(left(cipherText, (cipherText.size - self.CHECKSUM_SIZE))), left(cipherText, _
(cipherText.size - self.CHECKSUM_SIZE)), self.CHECKSUM_ITERATIONS, self.CHECKSUM_SIZE, crypto.algorithm.sha256)

if right(cipherText, self.CHECKSUM_SIZE) = checksumContent then 'if integrity checksum is valid
// - reserve buffer size; equals size of [cipherText] minus [CHECKSUM_SIZE]
deCipherContent = new memoryBlock(cipherText.size - self.CHECKSUM_SIZE)

// - construct [deCipherPad] from a hash variation of [targetPass]
// - uses the size of [cipherText] minus [CHECKSUM_SIZE] as the SALT
// - equals the size of and XOR'd against [cipherText] to construct [deCipherContent]
deCipherPad = crypto.pbkdf2(str(cipherText.size - self.CHECKSUM_SIZE), cipherPass, cipherIterations, _
(cipherText.size - self.CHECKSUM_SIZE), crypto.algorithm.sha512)

// - iterate and XOR contents of [cipherText] with [deCipherPad] to construct [deCipherContent]
for contentIndex = ZERO_VALUE to ((cipherText.size - self.CHECKSUM_SIZE) - BYTE_OFFSET)
  deCipherContent.byte(contentIndex) = bitWise.bitXor(cipherText.byte(contentIndex), deCipherPad.byte(contentIndex))
next contentIndex

plainText = deCipherContent 'return byRef [plainText]
return true

else 'integrity checksum is invalid
return false
end if
End Function[/code]

Usage example:

[code] dim plainText as memoryBlock
dim cipherText as memoryBlock
dim cipherPass as memoryBlock

plainText = “This is the datat I want to encrypt”
cipherPass = “This” + “is” + “my” + “password”

cipherText = cipher(plainText, cipherPass, 1)

if deCipher(cipherText, cipherPass, 1, plainText) then
print plainText
print “invalid cipher integerity checksum”
end if[/code]

Whatever cipherIterations you give it to cipher must also match what is given to properly decipher. This adds a level of security, and gives the benefits of the pbkdf2 hash itself (which is its slowness, which helps against bruteforce attacks on your cipher; however, it comes at a cost… which is performance, as pbkdf2 at higher iterations becomes linearly more slow).