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<javascript:>> 
> 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<javascript:>> 
> 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<javascript:> 
> >>>> 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 <javascript:> 
> >>>> 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 <javascript:>. 
> >>>> 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<javascript:> 
> >> 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 <javascript:> 
> >> 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 <javascript:>. 
> >> 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