Reversible Hashed to convert integer ID to alphabets/alphanumeric - algorithm

I need a Delphi reversible Hashed ID function that is quick.
Short, obfuscated and efficient IDs
No collisions (at least up to 32-bit unsigned integer at least)
Reversible
Fast
preferably something that has an input Key, so it can be randomised a bit...
otherwise, a '3' will always be 23zkJ5 on all my software modules.
works cross-platform
Something like Youtube's video identifier.
Encode(3); // => "23zkJ5"
Decode('23zkJ5'); // => 3
PHP seems to have quite a few of these; I can't find one for Delphi.
I look at this but not really what I wanted, plus I need something in Delphi.
Reversible hash function?
$generator->encode(6); // => "43Vht7"
$generator->decode('43Vht7'); // => 6
I need something like what PHP offers:
https://github.com/delight-im/PHP-IDs
I can't use MD5 as it's not reversible; using Lockbox encryption/decryption seems a bit over-kill? (if really no choice, which algorithm in Lockbox would be the best choice for this?)

Use AES and convert the cypher byte array to a hex string or to Base64.
for a code example see here
AES encrypt string in Delphi (10 Seattle) with DCrypt, decrypt with PHP/OpenSSL

Related

Aix: How to generate valid sha1/sha256/sha512 password hash on AIX /etc/security/passwd?

AIX, like other Unix, only store a salted hash of user password.
In the old days, it uses to use DES crypt, and then a (slighty different version of) MD5 Crypt, the same that you will find on Linux.
With more recent version of AIX and the use of /etc/security/passwd, you can use new SHA1/SHA256/SHA512 hashes. They look like that (with example hash string result for the password "secret"):
- salted sha1 : {ssha1}12$tyiOfoE4WXucUfh/$1olYn48enIIKGOOs0ve/GE.k.sF
- salted ssha256: {ssha256}12$tyiOfoE4WXucUfh/$YDkcqbY5oKk4lwQ4pVKPy8o4MqcfVpp1ZxxvSfP0.wS
- salted ssha512: {ssha512}10$tyiOfoE4WXucUfh/$qaLbOhKx3fwIu93Hkh4Z89Vr.otLYEhRGN3b3SAZFD3mtxhqWZmY2iJKf0KB/5fuwlERv14pIN9h4XRAZtWH..
The config file /etc/security/pwdalg.cfg explain the the number after {algo_name} is the "num_cost", and we can get the number of iteration used in the hashing function with 2^num_cost.
I need to generate valid hash from a Scala application that are latter place in /etc/security/passwd.
I tried to adapt commons-codec Sha2Crypt (https://commons.apache.org/proper/commons-codec/apidocs/src-html/org/apache/commons/codec/digest/Sha2Crypt.html) witch implements the official Sha-Crypt algorithm (https://www.akkadia.org/drepper/SHA-crypt.txt), but that give the wrong hash.
Anybody knows what should be done ?
The short answer is that, appart for md5, which is the standard unix implementation and differs only for the prefix ({smd5} in place of "$1", the other implementations differ SIGNIFICANTLY from standard Unix crypt described at https://www.akkadia.org/drepper/SHA-crypt.txt. In fact, they only kept:
the number of bytes (and so chars) for the hash: 20 for ssha1, 32 for ssha256, 64 for ssh512
the base64 encoding table (which is not the standard one but starts with "./012" etc
What changed is:
they use PBKDF2 HMAC-(sha1, sha256, sha512) in place of Sha-Crypt,
they use a different padding table
the number of iterations, named "rounds" in Unix crypt vocabulary, is not the number N found at the begining of the hash string (after the algo name). The number of iteration is actually 2^N, and N is called in /etc/security/pwdalg.cfg the "cost"
A valid Scala implementation can be found in Rudder's AixPasswordHashAlgo.scala here: https://github.com/Normation/rudder/blob/master/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/cfclerk/domain/AixPasswordHashAlgo.scala

Encrypt passwords in human-readable format

I'm looking for one or more encryption algorithms that can encrypt passwords in a way that the encrypted text must be readable by humans.
For example if I give as password:
StackOverflow
The algorithm should gives me:
G0aThiR4i s0ieFer
So I want to get an encrypted password easily readable by humans (not strange strings with special chars or thousand of characters).
There are algorithms that fit this need?
RFC 1751, which defines a "Convention for Human-Readable 128-bit Keys" – basically just a mapping of blocks of bits to strings of English words.
For example, the 128-bit key of:
CCAC 2AED 5910 56BE 4F90 FD44 1C53 4766
would become
RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE
Algorithm is used for fixed-length 128-bit keys, that's a base for data size. Source data can be truncated or expanded to match the base.
Spec & implementation in C # https://www.rfc-editor.org/rfc/rfc1751
It ain't well known. I couldn't find implementation mention apart from one in spec & references to lost python library.
Your question puzzled me in many ways, leading to the hare-brained idea of creating a completely human-readable paragraph from a base 16 hash result. What's more readable than English sentences?
To maintain the security of a hashed password, the algorithm is as follows:
Hash a user's password using any of the basic techniques.
Run the hash through my special HashViewer
Enjoy the Anglicized goodness.
For example, if this Base16 hash is the input:
c0143d440bd61b33a65bfa31ac35fe525f7b625f10cd53b7cac8824d02b61dfc
the output from HashViewer would be this:
Smogs enjoy dogs. Logs unearth backlogs. Logs devour frogs. Grogs decapitate clogs and dogs conceptualize fogs. Fogs greet clogs. Cogs conceptualize warthogs. Bogs unearth dogs despite bogs squeeze fogs. Cogs patronize catalogs. Cogs juggle cogs. Warthogs debilitate grogs; unfortunately, clogs juggle cogs. Warthogs detest frogs; conversely, smogs decapitate cogs. Fogs conceptualize balrogs. Smogs greet smogs whenever polywogs accost eggnogs. Logs decapitate frogs. Eggnogs conceptualize clogs. Dogs decapitate warthogs. (smogs )
(The last words in parenthesis were words that were left over)
In this glorious paragraph form, we can look at two separate hashes and easily compare them to see if they are different.
As an extra feature, there is a function to convert the English text back in to the hash string.
Enjoy!
Step 1) Apply regular encryption algorithm.
Step 2) Base 26-encode it using letters a thru z
Step 3) ???
Step 4) Profit!
Even cooler would be to get a letter-bigraph distribution for the english language. Pick a simple pseudo-random-number algorithm and seed it with the non-human-readable password hash. Then use the algorithm to make up a word according to how likely a letter is to follow the letter before it in the english language. You'll get really english-sounding words, and consistently from the same seed. The chance for collisions might be unseasonably high, though.
EncryptedPassword = Base64(SHA1(UTF8(Password) + Salt))
Password is string
Salt is cryptographically strong random byte[]
UTF8: string -> byte[]
SHA1: byte[] -> byte[]
Base64: byte[] -> string
EncryptedPassword is string
Store (EncryptedPassword, Salt).
Throw in whatever encryption algorithm you want instead of SHA1.
For example, if password is StackOverflow you get the encrypted password LlijGz/xNSRXQXtbgNs+UIdOCwU.

"Recalculate" SHA512+salt string to BLOWFISH+salt - is this possible?

Maybe this is a stupid question, but I wouldn't be shocked if some excellent brains come around with a proper solution or an idea: Is it possible to recalculate/transcode a salted sha512 string into a salted blowfish string ?
The (imo quite interesting) background is: I have a big database of SHA512+salt strings like that $6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKREY4... (118 chars) and want to move to another hash/salt algorithm, generating strings like $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi (60 chars).
I'm intentionally NOT asking this on security.stackexchange.com as this is not a security question. It's about transcoding/recalculation.
Is it possible to recalculate/transcode a salted sha512 string into a salted blowfish string ?
Nope.
SHA2-512 is a cryptographic hash. Data goes in, but there's no way to get it back out. Do note that the thing you're using is a proposed but not standardized form of crypt that uses SHA2, and is not a raw SHA2 hash.
bcrypt (which is derived from, but is not Blowfish) is a key derivation function, which while a different thing than a cryptographic hash, still has the same result: data goes in, but there's no way to get it back out.
There is no way to simply convert one of these password hash types to another. This is true of almost every hash type. If you need to change the hash type, do so when the user next logs in.

Salt a key for secure encryption Cocoa?

I was reading a tutorial on how to salt a key to make your encryption secure, but couldn't make much of it. I don't know a lot about cryptography, and need some help. I am using commoncrypto to encrypt files, and am done, except for the fact that it isn't secure...
This is what I have:
- (NSData *)AES256EncryptWithKey:(NSString *)key
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)
NSLog(#"You are encrypting something...");
// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted );
if( cryptStatus == kCCSuccess )
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free( buffer ); //free the buffer
return nil;
}
If someone can help me out, and show me exactly how I would implement salt, that would be great! Thanks again!
dYhG9pQ1qyJfIxfs2guVoU7jr9oniR2GF8MbC9mi
Enciphering text
AKA jumbling it around, to try and make it indecipherable. This is the game you play in cryptography. To do this, you use deterministic functions.
Encrypting involves using a function which takes two parameters: usually a short, fixed length one, and an arbitrary length one. It produces output the same size as the second parameter.
We call the first parameter the key; the second, the plaintext; and the output, the ciphertext.
This will have an inverse function (which is sometimes the same one), which has the same signature, but given instead ciphertext will return the plaintext (when using the same key).
Obviously the property of a good encryption function is that the plaintext is not easily determinable from the ciphertext, without knowing the key. An even better one will produce ciphertext that is indistinguishable from random noise.
Hashing involves a function which takes one parameter, of arbitrary size, and returns an output of fixed size. Here, the goal is that given a particular output, it should be hard to find any input that will produce it. It is a one-way function, so it has no inverse. Again, it's awesome if the output looks completely random.
The problem with determinism
The above is all very well and good, but we have a problem with our ultimate goals of indecipherability when designing implementations of these functions: they're deterministic! That's no good for producing random output.
While we can design functions that still produce very random-looking output, thanks to confusion and diffusion, they're still going to give the same output given the same input. We both need this, and don't like it. We would never be able to decipher anything with a non-deterministic crypto system, but we don't like repeatable results! Repeatable means analysable... determinable (huh.). We don't want the enemy to see the same two ciphertexts and know that they came from the same input, that would be giving them information (and useful techniques for breaking crypto-systems, like rainbow tables). How do we solve this problem?
Enter: some random stuff inserted at the start.
That's how we defeat it! We prepend (or sometimes better, append), some unique random input with our actual input, everytime we use our functions. This makes our deterministic functions give different output even when we give the same input. We send the unique random input (when hashing, called a salt; when encrypting, called an Initialisation Vector, or IV) along with the ciphertext. It's not important whether the enemy sees this random input; our real input is already protected by our key (or the one-way hash). All that we were actually worried about is that our output is different all the time, so that it's non-analysable; and we've achieved this.
How do I apply this knowledge?
OK. So everybody has their app, and within it their cryptosystem protecting parts of the app.
Now we don't want to go reinventing the wheel with cryptosystems (Worst. Idea. Ever.), so some really knowledgable people have already come up with good components that can build any system (i.e, AES, RSA, SHA2, HMAC, PBKDF2). But if everyone is using the same components, then that still introduces some repeatability! Fortunately, if everyone uses different keys, and unique initial random inputs, in their own cryptosytem, they should be fine.
Enough already! Talk about implementation!
Let's talk about your example. You're wanting to do some simple encryption. What do we want for that? Well, A) we want a good random key, and B) we want a good random IV. This will make our ciphertext as secure as it can get. I can see you haven't supplied a random IV - it's better practice to do so. Get some bytes from a [secure/crypto]-random source, and chuck it in. You store/send those bytes along with the ciphertext. Yes, this does mean that the ciphertext is a constant length bigger than the plaintext, but it's a small price to pay.
Now what about that key? Sometimes we want a remember-able key (like.. a password), rather than a nice random one that computers like (if you have the option to just use a random key - do that instead). Can we get a compromise? Yes! Should we translate ASCII character passwords into bytes to make the key? HELL NO!
ASCII characters aren't very random at all (heck, they generally only use about 6-7 bits out of 8). If anything, what we want to do is make our key at least look random. How do we do this? Well, hashing happens to be good for this. What if we want to reuse our key? We'll get the same hash... repeatability again!
Luckily, we use the other form of unique random input - a salt. Make a unique random salt, and append that to your key. Then hash it. Then use the bytes to encrypt your data. Add the salt AND the IV along with your ciphertext when you send it, and you should be able to decrypt on the end.
Almost done? NO! You see the hashing solution I described in the paragraph above? Real cryptographers would call it amateurish. Would you trust a system which is amateurish? No! Am I going to discuss why it's amateurish? No, 'cus you don't need to know. Basically, it's just not REALLY-SUPER-SCRAMBLED enough for their liking.
What you need to know is that they've already devised a better system for this very problem. It's called PBKDF2. Find an implementation of it, and [learn to] use that instead.
Now all your data is secure.
Salting just involves adding a random string to the end of the input key.
So generate a random string of some length:
Generate a random alphanumeric string in cocoa
And then just append it to the key using:
NSString *saltedKey = [key stringByAppendingString:salt];
Unless salt is being used in a different way in the article you read this should be correct.
How a random salt is normally used:
#Ca1icoJack is completely correct in saying that all you have to do is generate some random data and append it to the end. The data is usually binary as opposed to alphanumeric though. The salt is then stored unencrypted alongside each hashed password, and gets concatenated with the user's plaintext password in order to check the hash every time the password gets entered.
What the is the point of a SALT if it's stored unencrypted next to the hashed password?
Suppose someone gets access to your hashed passwords. Human chosen passwords are fairly vulnerable to being discovered via rainbow tables. Adding a hash means the rainbow table needs to not only include the values having any possible combination of alphanumeric characters a person might use, but also the random binary salt, which is fairly impractical at this point in time. So, basically adding a salt means that a brute force attacker who has access to both the hashed password and the salt needs to both figure how how the salt was concatenated to the password (before or after, normally) and brute force each password individually, since readily available rainbow tables don't include any random binary data.
Edit: But I said encrypted, not hashed:
Okay, I didn't read very carefully, ignore me. Someone is going to have to brute-force the key whether it's salted or not with encryption. The only discernable benefit I can see would be as that article says to avoid having the same key (from the user's perspective) used to encrypt the same data produce the same result. That is useful in encryption for different reasons (encrypted messages tend to have repeating parts which could be used to help break the encryption more easily) but the commenters are correct in noting that it is normally not called an salt in this instance.
Regardless, the trick is to concatenate the salt, and store it alongside each bit of encrypted data.

Ruby on Rails - generating bit.ly style identifiers

I'm trying to generate UUIDs with the same style as bit.ly urls like:
http://bit [dot] ly/aUekJP
or cloudapp ones:
http://cl [dot] ly/1hVU
which are even smaller
how can I do it?
I'm now using UUID gem for ruby but I'm not sure if it's possible to limitate the length and get something like this.
I am currently using this:
UUID.generate.split("-")[0] => b9386070
But I would like to have even smaller and knowing that it will be unique.
Any help would be pretty much appreciated :)
edit note: replaced dot letters with [dot] for workaround of banned short link
You are confusing two different things here. A UUID is a universally unique identifier. It has a very high probability of being unique even if millions of them were being created all over the world at the same time. It is generally displayed as a 36 digit string. You can not chop off the first 8 characters and expect it to be unique.
Bitly, tinyurl et-al store links and generate a short code to represent that link. They do not reconstruct the URL from the code they look it up in a data-store and return the corresponding URL. These are not UUIDS.
Without knowing your application it is hard to advise on what method you should use, however you could store whatever you are pointing at in a data-store with a numeric key and then rebase the key to base32 using the 10 digits and 22 lowercase letters, perhaps avoiding the obvious typo problems like 'o' 'i' 'l' etc
EDIT
On further investigation there is a Ruby base32 gem available that implements Douglas Crockford's Base 32 implementation
A 5 character Base32 string can represent over 33 million integers and a 6 digit string over a billion.
If you are working with numbers, you can use the built in ruby methods
6175601989.to_s(30)
=> "8e45ttj"
to go back
"8e45ttj".to_i(30)
=>6175601989
So you don't have to store anything, you can always decode an incoming short_code.
This works ok for proof of concept, but you aren't able to avoid ambiguous characters like: 1lji0o. If you are just looking to use the code to obfuscate database record IDs, this will work fine. In general, short codes are supposed to be easy to remember and transfer from one medium to another, like reading it on someone's presentation slide, or hearing it over the phone. If you need to avoid characters that are hard to read or hard to 'hear', you might need to switch to a process where you generate an acceptable code, and store it.
I found this to be short and reliable:
def create_uuid(prefix=nil)
time = (Time.now.to_f * 10_000_000).to_i
jitter = rand(10_000_000)
key = "#{jitter}#{time}".to_i.to_s(36)
[prefix, key].compact.join('_')
end
This spits out unique keys that look like this: '3qaishe3gpp07w2m'
Reduce the 'jitter' size to reduce the key size.
Caveat:
This is not guaranteed unique (use SecureRandom.uuid for that), but it is highly reliable:
10_000_000.times.map {create_uuid}.uniq.length == 10_000_000
The only way to guarantee uniqueness is to keep a global count and increment it for each use: 0000, 0001, etc.

Resources