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

-- 
-- 
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