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.


Reply via email to