reverse hash

417 views
Skip to first unread message

alan....@bellaliant.net

unread,
Oct 24, 2013, 10:53:18 AM10/24/13
to guava-...@googlegroups.com
Hi there,
 
I'm working with the Guava HashFunction class to create license keys.  My code looks like this:
 

public class LicenseKey

   public static void main(String[] args) { 
     String userName = "John Doe"; 
     String productKey = "1002-1"; 
     String versionNumber = "1";  

     String licenseKey = createLicenseKey(userName, productKey, versionNumber);

     System.out.println("licenseKey = " + licenseKey);

     //License Key should be similar to this: 7F4727-423B69-4275C6-2E8012-38EC2F-663D65-5E68 


public static String createLicenseKey(String userName, String productKey, String versionNumber) {

   String s = userName + "|" + productKey + "|" + versionNumber; 
   HashFunction hashFunction = Hashing.sha1();
   HashCode hashCode = hashFunction.hashUnencodedChars(s);
   String upper = hashCode.toString().toUpperCase(); 
    return group(upper);


private static String group(String s) {
   String result = ""; 
   for (int i=0; i < s.length(); i++) { 
        if (i%6==0 && i > 0) {
              result += '-'; 
        }

    result += s.charAt(i); 
    } 
    return result;
}

}

 

This certainly works, but I don't understand how to reverse it.  How do I take the licenseKey string and regain the String sequence: John Doe|1002-1|1

 

Please advise,

 

Alan

Luke Sandberg

unread,
Oct 24, 2013, 11:03:52 AM10/24/13
to alan....@bellaliant.net, guava-...@googlegroups.com
HashCodes are not reversible.  In general there are many different inputs that can lead to the same output so there is no unique way to reverse a single hashcode.  Sha-1 in particular is a Secure Hash Function which is designed to make it difficult to find any input for a particular output.



--
--
guava-...@googlegroups.com
Project site: http://guava-libraries.googlecode.com
This group: http://groups.google.com/group/guava-discuss
 
This list is for general discussion.
To report an issue: http://code.google.com/p/guava-libraries/issues/entry
To get help: http://stackoverflow.com/questions/ask (use the tag "guava")
---
You received this message because you are subscribed to the Google Groups "guava-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to guava-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/guava-discuss/c5952520-2a5d-4ebb-91a6-d2397e4c0208%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

alan....@bellaliant.net

unread,
Oct 24, 2013, 11:14:28 AM10/24/13
to guava-...@googlegroups.com, alan....@bellaliant.net
Well, then perhaps license keys are created using some other method?  I'm just trying to figure out how one validates a license key?  If I can't decrypt a hashcode, then maybe some other method is used?

Luke Sandberg

unread,
Oct 24, 2013, 11:22:41 AM10/24/13
to alan....@bellaliant.net, guava-...@googlegroups.com
I don't know how that problem is typically solved, but you could consider encrypting your inputs which is reversible. (hashing is not encrypting).

that being said I would do some more research first to see what the best practices are since i would be very wary of rolling my own encryption scheme.  If you are just generating license keys, you could just hand out random numbers (UUIDs) and then just store the mapping in a database.  That would probably be easier than an encryption scheme, and since you are probably storing customer information anyway you already have a storage solution.



Kevin Bourrillion

unread,
Oct 24, 2013, 11:22:52 AM10/24/13
to alan....@bellaliant.net, guava-discuss
1. Hash the same data again and compare.
2. Look it up in a database.
3. Use something reversible, like a plain BaseEncoding, but watch out if you expect these keys to be secure.

(btw, instead of writing your group() function, you can just pass the hashCode.asBytes() to a BaseEncoding that uses withSeparator().)


On Thu, Oct 24, 2013 at 8:14 AM, <alan....@bellaliant.net> wrote:

For more options, visit https://groups.google.com/groups/opt_out.



--
Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com

Coda Hale

unread,
Oct 24, 2013, 1:12:59 PM10/24/13
to alan....@bellaliant.net, guava-...@googlegroups.com
On Thu, Oct 24, 2013 at 8:14 AM, <alan....@bellaliant.net> wrote:
Well, then perhaps license keys are created using some other method?  I'm just trying to figure out how one validates a license key?  If I can't decrypt a hashcode, then maybe some other method is used?

You should use a digital signature: http://en.wikipedia.org/wiki/Digital_signature

This isn't provided by Guava, but Java comes with support for this baked in via the JCE and JCA.

This will allow you to generate licenses which are a) not forgeable by third parties and b) verifiable without requiring secret data.

--
Coda Hale
http://codahale.com

Martin Grajcar

unread,
Oct 24, 2013, 2:31:27 PM10/24/13
to guava-...@googlegroups.com, alan....@bellaliant.net
Whatever you do, in the moment you hand your program out to the customer, it can be cracked. Simply finding and replacing  if (licenceIsRight()) by if (true) does the job. The effort for this is much less than for cracking any sane cryptography, so running some stupid home-grown crypto is not such a disaster as when used for something else. But still, don't do it. Digital signatures are best here.

Try http://stackoverflow.com/search?q=license+number, there's really everything about it.

Reply all
Reply to author
Forward
0 new messages