My Way: Web APIs and SHA1 encryption

by Erica Sadun

If you've been following my recent posts, you're probably well aware that I've been doing a lot of playing with Web APIs--particularly with iTunes and Amazon Web Services. I love the concept of API as User Interface and I love the new ways established companies are providing Web-based utilities.

Because the World Wide Web is such an open place, many Web API services demand that you authenticate your requests. Requests must come from the proper parties and sent without loss of message integrity.


2006-04-28 18:54:46
I've not used the APIs that you're referring to. But if I understand your code, then I feel that I must object to your use of the term "encrypt" in both your function name and your comments. An encrypt operation implies that there is a corresponding decrypt operation. But in this case there is not.

This is really cryptographic signing. When the server receives your call, it will cryptographically sign the very same data block, which it can do since it too knows your secret key. If their result comes out the same, then they know that you too knew the secret key, and have thereby authenticated you. But the important point is is that they're not decrypting what you did, they're re-doing it and then comparing.

And how about some maintable commented code? I suspect even you in six months time will be unclear as to what's going on. For example, what is a "riz" as in "rizlen"?

M. David Peterson
2006-04-28 21:39:31
Hi Erica,

It seems we have a similar interest in this general area. Have a look at this post from the beginning of April... would LOVE to see another hacker such as yourself take something like this and see what, if anything, could realistically be integrated into the existing world of web servers, with as little effort as possible as it seems to me that if this could be accomplished, some pretty neat things could be the result.

I have more to add to this post myself in the upcoming weeks, so if nothing else, I will update this post with a comment when I do.


Josh Peters
2006-04-29 21:58:29
To Bob:

Regarding the maintainable commented code remark, please keep in mind that this is a blog post meant to demonstrate some code. When one adds code to be executed or compiled it's generally expected and nice to keep the code as simple as possible.

Perhaps Erica could provide a more maintainable copy of the code, but it's all her call. Your sarcasm is a abit of an affront to her choice to post something interesting.

You've got a point about the difference between a hash computation and encryption, but it's really semantics. The important point isn't what you mentioned as the important point, it is that Erica has cooked up a simple application for her that she can use to get things done. I believe it's more of a "you say po-tay-toe; I say po-tah-toe" circumstance than anything.

I believe that "rizlen" is the lenth of the "results" array.

To Erica: Would you mind pointing us in the direction of some documentation for the APIs you're using?

Erica Sadun
2006-05-01 08:43:38
Bob & Josh: My bad. You're totally right on the fact that although it's a cryptographic function, it's not encryption. I will now smack my head against the wall several times. As for "riz"/"rizlen", it's become part of my programming idiom for so many years that I always know what it means.

Bob: What part of the code would you suggest needs more commenting? I've looked it over and I don't think I'd add more on a personal level, but I'd love to hear where you'd put it.

MDavid: I'm totally into putting together a group collection of tools. More about that later.

Josh: You can read about most of the Amazon API at The iTunes API, I'm reverse engineering, as I've been doing with Pandora as well.

Everyone: I think I'm missing a BIO_free_all(b64); in there.

M. David Peterson
2006-05-01 13:16:24
Hey Erica,

Excellent! Ill look forward to hearing more :)

2007-04-14 23:23:08
Interesting comments.. :D
michael venzke
2008-03-04 12:51:24
hey, thanks for putting this together in a nice googleable snippet.

For people who might copy the code directly though, I feel obligated to point out that the doEncrypt() function as written will result in memory leaks since the memory malloc'd for signature is never freed.

A simple way to remedy it is to just remove the malloc, since it's redundant.

This snippet:
siglen = BIO_get_mem_data(bio, &sigptr);
signature = malloc(siglen+1);
memcpy (signature, sigptr, siglen);
signature[siglen] = '\0';
sprintf(sigString, "%s", signature);

Could be replaced simply with this:
siglen = BIO_get_mem_data(bio, &sigptr);
memcpy (sigString, sigptr, siglen);
sigString[siglen] = '\0';

and behave exactly the same. However, I also want to point out to others that it is very dangerous as written since the string the result is being written to, the parameter "char * sigString", has no known length in the doEncrypt function and could result in buffer overflows & security exploits. I would suggest either adding a length parameter to the function & changing the memcpy to not exceed this length, or changing the parameter to a char **, allocating the memory within doEncrypt, and then freeing it within the calling function or elsewhere.

Also, erica mentioned the possible need for a BIO_free_all(b64). This is not necessary, as the line BIO_push(b64, bio) appends b64 to bio in a "BIO chain" (assuming it was successful). Calling BIO_free_all(bio) as this code does, frees the entire BIO chain, including the memory allocated for bio and b64.


2008-07-14 13:54:15
Hi, not that I insist or what, but... I wonder whether you use actually code mentioned above in real life. Because if you do use it, then getting your binary which executes that code is like looking under your door carpet, if you understand what I mean ;)