I just became aware of this crypto-password clojure-library by compojure/hiccup/codox's James Reeve: https://github.com/weavejester/crypto-password
Supports bcrypt, script and pbkdf2. Very well designed and easy to use! This should be your goto-library for secure hashing of passwords!!! -Frank. On Mar 4, 2013, at 10:52 PM, Frank Siebenlist <frank.siebenl...@gmail.com> 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 <champi...@netscape.net> 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.