I used a widely accepted pattern: SHA2+Salt+Iteration, that's been used many times, e.g. in Jasypt http://www.jasypt.org/ so I think that aspect of it is pretty conservative, and virtually all the algorithm's strength lies within the SHA implementation itself - so my opportunity to screw up via this wrapper is limited. Still, crypto is hard, and subtle flaws can be introduced in unexpected ways. I agree: just use bcrypt.
M. On Tuesday, March 5, 2013 1:52:46 AM UTC-5, FrankS wrote: > > Hi Mark, > > Thanks for sharing! > > I like the approach of hiding all the interaction with the > java.security.MessageDigest library, > and returning the pair of matching digest&verify functions - it will avoid > many mistakes. > > As far as the presented algorithm is concerned, it may be more prudent to > stick with bcrypt and friends though… > > Regards, Frank. > > > On Mar 4, 2013, at 7:32 PM, Mark C <cham...@netscape.net <javascript:>> > wrote: > > > For another cut at a hashing interface, you may want to look at one I > made specifically for passwords. You make a password hasher by passing in > algorithm, salt length, and iterations, and you get back a map containing a > pair of complementary functions: one that digests, the other that verifies. > https://gist.github.com/mchampine/868342 > > > > Example: Digester/verifier pair using SHA-256 with 16 bytes salt and 10k > iterations > > > > (def strongPWHasher (pwfuncs "SHA-256" 16 10000)) ; make the > digester/verifier pair > > (def hashed-pw ((strongPWHasher :digest) "mysecret")) ; hash the > password > > ((strongPWHasher :verify) "mysecret" hashed-pw) ; verify it > > > > M. > > > > On Monday, March 4, 2013 6:46:07 PM UTC-5, FrankS wrote: > > Larry, > > > > What I can advise though, is to look at my library code and it may give > you different perspectives. > > > > Furthermore, copy, borrow, and steal what you like and make it your own. > > > > -FS. > > > > > > On Mar 4, 2013, at 3:17 PM, Frank Siebenlist <frank.si...@gmail.com> > wrote: > > > > > If your code is for production… do not use my code! > > > > > > It's pretty much written over the weekend and it's "security code", > meaning that it deserves much more scrutiny than "ordinary" code. > > > > > > As mentioned in the readme, it's more an "educational exercise", > although it was good to see you struggling as it validated my concerns > about the java library's approach ;-) > > > > > > Don't even know if I'm willing to maintain it either… > > > > > > Sorry for the bad news - I was just trying to sollicit feedback about > alternative interfaces for the secure hashing. > > > > > > Regards, FrankS. > > > > > > > > > On Mar 4, 2013, at 3:09 PM, larry google groups <lawrenc...@gmail.com> > wrote: > > > > > >> Frank, > > >> > > >> Any idea when you might release your code in a stable form? I am > using > > >> this code at work so I am nervous about using code that is still > > >> marked SNAPSHOT. Lein reminds me not to use a SNAPSHOT: > > >> > > >> Could not find metadata org.clojars.franks42:clj.security.message- > > >> digest:0.1.0-SNAPSHOT/maven-metadata.xml in central (http:// > > >> repo1.maven.org/maven2) > > >> Could not find metadata org.clojars.franks42:clj.security.message- > > >> digest:0.1.0-SNAPSHOT/maven-metadata.xml in central-proxy (https:// > > >> repository.sonatype.org/content/repositories/centralm1/) > > >> Retrieving org/clojars/franks42/clj.security.message-digest/0.1.0- > > >> SNAPSHOT/maven-metadata.xml (1k) > > >> from https://clojars.org/repo/ > > >> Could not find artifact org.clojars.franks42:clj.security.message- > > >> digest:pom:0.1.0-20130304.220822-1 in central ( > http://repo1.maven.org/ > > >> maven2) > > >> Retrieving org/clojars/franks42/clj.security.message-digest/0.1.0- > > >> SNAPSHOT/clj.security.message-digest-0.1.0-20130304.220822-1.pom (3k) > > >> from https://clojars.org/repo/ > > >> Retrieving org/clojure/clojure/1.5.0/clojure-1.5.0.pom (6k) > > >> from http://repo1.maven.org/maven2/ > > >> Retrieving org/clojars/franks42/clj.security.message-digest/0.1.0- > > >> SNAPSHOT/clj.security.message-digest-0.1.0-20130304.220822-1.jar (6k) > > >> from https://clojars.org/repo/ > > >> Compiling 1 source files to /Users/lkrubner/projects/multi-platform- > > >> data-visualization/mpdv-clojure/target/classes > > >> Release versions may not depend upon snapshots. > > >> Freeze snapshots to dated versions or set the > > >> LEIN_SNAPSHOTS_IN_RELEASE environment variable to override. > > >> > > >> > > >> > > >> > > >> > > >> > > >> On Mar 4, 4:55 pm, Frank Siebenlist <frank.siebenl...@gmail.com> > > >> wrote: > > >>> Glad Larry has working code now... > > >>> > > >>> As I mentioned before in this thread, I'm working on this functional > interface for the message-digesting/secure-hashing, and this whole > discussion reads like a use case for the "why?" ;-) > > >>> > > >>> It "proofs" to me that there may be real value in a more > user-friendly approach than the one offered by java.security.MessageDigest. > > >>> > > >>> So instead of writing: > > >>> > > >>> (let [... > > >>> nonce-as-bytes (.getBytes nonce) > > >>> created-as-bytes (.getBytes created) > > >>> secret-as-bytes (.getBytes secret) > > >>> digest (.digest > > >>> (doto (java.security.MessageDigest/getInstance > "sha1") > > >>> .reset > > >>> (.update nonce-as-bytes) > > >>> (.update created-as-bytes) > > >>> (.update secret-as-bytes))) > > >>> …] > > >>> > > >>> my library lets you write: > > >>> > > >>> (let [… > > >>> digest (md/digest :sha-1 :utf-8 nonce created secret) > > >>> …] > > >>> > > >>> and the advantages of the more functional approach is much more than > just saving a few lines of code! > > >>> > > >>> Although it still needs some more work, any feedback on > > >>> "https://github.com/franks42/clj.security.message-digest" > > >>> is much appreciated. > > >>> > > >>> Regards, FrankS. > > >>> > > >>> On Mar 4, 2013, at 1:31 PM, larry google groups < > lawrencecloj...@gmail.com> wrote: > > >>> > > >>> > > >>> > > >>> > > >>> > > >>> > > >>> > > >>>> I finally got this to work. Many thanks for all of the help that I > was > > >>>> given here. > > >>> > > >>>> The final, winning combination was: > > >>> > > >>>> (let [username (get-in @um/interactions [:omniture-api- > > >>>> credentials :username]) > > >>>> secret (get-in @um/interactions [:omniture-api-credentials > :shared- > > >>>> secret]) > > >>>> random-number (math/round (* (rand 1 ) 1000000)) > > >>>> nonce (DigestUtils/md5Hex (str random-number)) > > >>>> nonce-encoded-base64 (base64-encode (.getBytes nonce)) > > >>>> date-formatter (new SimpleDateFormat "yyyy-MM-dd'T'HH:mm:ss") > > >>>> created (.format date-formatter (new Date)) > > >>>> nonce-as-bytes (.getBytes nonce) > > >>>> created-as-bytes (.getBytes created) > > >>>> secret-as-bytes (.getBytes secret) > > >>>> digest (.digest > > >>>> (doto (java.security.MessageDigest/getInstance > > >>>> "sha1") > > >>>> .reset > > >>>> (.update nonce-as-bytes) > > >>>> (.update created-as-bytes) > > >>>> (.update secret-as-bytes))) > > >>>> digest-base64 (base64-encode digest) > > >>>> header (apply str " UsernameToken Username=\"" username "\" > > >>>> PasswordDigest=\"" digest-base64 "\" Nonce=\"" nonce-encoded-base64 > > >>>> "\" Created=\"" created "\"")] > > >>>> header) > > >>> > > >>>> On Mar 4, 10:47 am, larry google groups <lawrencecloj...@gmail.com> > > > >>>> wrote: > > >>>>> I have been having problems making an API call to Omniture. I have > > >>>>> exchanged a dozen emails with a developer at Omniture, and he gave > me > > >>>>> the impression that I was constructing my security codes > incorrectly. > > >>>>> So now I am confronting my ignorance over how Java handles certain > > >>>>> conversions. > > >>> > > >>>>> The developer at Omniture sent me this explanation in an email: > > >>> > > >>>>> " The security digest is formed from a sha1 hash of the following > > >>>>> string concatenation: > > >>>>> digest = sha1( Binary Nonce + Created Time String + API Secret Hex > > >>>>> String (32 bytes) ) " > > >>> > > >>>>> I have been struggling with this for several days and I have tried > at > > >>>>> least (literally) 200 variations on this bit of code: > > >>> > > >>>>> (let [username (get-in @um/interactions [:omniture-api- > > >>>>> credentials :username]) > > >>>>> secret (get-in @um/interactions [:omniture-api- > > >>>>> credentials :shared-secret]) > > >>>>> nonce (DigestUtils/md5Hex (random-string 32)) > > >>>>> nonce-encoded-base64 (Base64/encodeBase64 (.getBytes nonce)) > > >>>>> date-formatter (new SimpleDateFormat "yyyy-MM- > > >>>>> dd'T'HH:mm:ss'Z'") > > >>>>> created (.format date-formatter (new Date)) > > >>>>> digest-as-string (apply str (.getBytes nonce) created secret) > > >>>>> digest (.digest (java.security.MessageDigest/getInstance > "sha1") > > >>>>> digest-as-string) > > >>>>> header (apply str " UsernameToken Username=\"" username "\" > > >>>>> PasswordDigest=\"" digest "\" Nonce=\"" nonce-encoded-base64 "\" > > >>>>> Created=\"" created "\"")] > > >>>>> header) > > >>> > > >>>>> This version gives me: > > >>> > > >>>>> "Exception in the main function: " #<ClassCastException > > >>>>> java.lang.ClassCastException: java.lang.String cannot be cast to > [B> > > >>> > > >>>>> For a long time I was using this for the last 3 lines: > > >>> > > >>>>> digest-as-string (apply str nonce created secret) > > >>>>> digest (.digest (java.security.MessageDigest/getInstance > "sha1") > > >>>>> (.getByes digest-as-string)) > > >>>>> header (apply str " UsernameToken Username=\"" username "\" > > >>>>> PasswordDigest=\"" digest "\" Nonce=\"" nonce-encoded-base64 "\" > > >>>>> Created=\"" created "\"") > > >>> > > >>>>> Here I wrapped the whole digest-as-string in (.getBytes) so there > was > > >>>>> no Java error, but this simply did not work when I pinged > Omniture. > > >>> > > >>>>> In his email, he seems to suggest that the nonce should be binary > but > > >>>>> that the date and the secret should be strings: > > >>> > > >>>>> digest = sha1( Binary Nonce + Created Time String + API Secret Hex > > >>>>> String (32 bytes) ) " > > >>> > > >>>>> But, as I said, when I tried this I got the ClassCastException. > > >>> > > >>>>> No doubt some of my confusion is due to my ignorance of Java. > > >>> > > >>>>> I was able to take their sample PHP code and get that to > successfully > > >>>>> ping their API, however, my company has an official policy of > moving > > >>>>> to the JVM, and of course I have a personal preference to work > with > > >>>>> Clojure. So I'd like to figure out how to get this to work in > Clojure. > > >>>>> (Needless to say that Omniture doesn't offer sample code in > Clojure.) > > >>> > > >>>>> I have been using clj-http to make the actual POST calls to > Omniture. > > >>>>> Since I am on a Mac, I have been using the excellent Charles > network > > >>>>> debugger (http://www.charlesproxy.com/) to watch the actual posts > > >>>>> being made. Everything looks correct, except that in the end the > > >>>>> requests fails, apparently because the digest is malformed. > > >>> > > >>>>> Any suggestions? > > >>> > > >>>> -- > > >>>> -- > > >>>> You received this message because you are subscribed to the Google > > >>>> Groups "Clojure" group. > > >>>> To post to this group, send email to clo...@googlegroups.com > > >>>> Note that posts from new members are moderated - please be patient > with your first post. > > >>>> To unsubscribe from this group, send email to > > >>>> clojure+u...@googlegroups.com > > >>>> For more options, visit this group at > > >>>> http://groups.google.com/group/clojure?hl=en > > >>>> --- > > >>>> You received this message because you are subscribed to the Google > Groups "Clojure" group. > > >>>> To unsubscribe from this group and stop receiving emails from it, > send an email to clojure+u...@googlegroups.com. > > >>>> For more options, visithttps://groups.google.com/groups/opt_out. > > >> > > >> -- > > >> -- > > >> You received this message because you are subscribed to the Google > > >> Groups "Clojure" group. > > >> To post to this group, send email to clo...@googlegroups.com > > >> Note that posts from new members are moderated - please be patient > with your first post. > > >> To unsubscribe from this group, send email to > > >> clojure+u...@googlegroups.com > > >> For more options, visit this group at > > >> http://groups.google.com/group/clojure?hl=en > > >> --- > > >> You received this message because you are subscribed to the Google > Groups "Clojure" group. > > >> To unsubscribe from this group and stop receiving emails from it, > send an email to clojure+u...@googlegroups.com. > > >> For more options, visit https://groups.google.com/groups/opt_out. > > >> > > >> > > > > > > > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.