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.


Reply via email to