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.


Reply via email to