Cryptkit is a Tcl binding to the Cryptlib security toolkit.
From the Cryptlib web site - "The Cryptlib security toolkit is a powerful security toolkit that allows even inexperienced crypto programmers to easily add encryption and authentication services to their software. The high-level interface provides anyone with the ability to add strong security capabilities to an application in as little as half an hour, without needing to know any of the low-level details that make the encryption or authentication work. Because of this, cryptlib dramatically reduces the cost involved in adding security to new or existing applications." [L1 ]
Cryptkit brings these benefits to Tcl.
This first release provides an API that closely matches the Cryptlib C API (to remain consistent with the existing documentation). The next release will have a more "Tclish" API.
Downloads
Cryptkit was written by Steve Landers and was made possible through the financial support of Eolas Technologies Inc.
Cryptkit is distributed under a Tcl BSD style license, as documented in the license.terms file in the distribution.
MDD: Great job Steve!
Example - test cipher
proc testCipher {cryptAlgo keySize algoName} { # Create context with random IV (if it needs one) and a key derived # from a password using a salt and iteration count to hinder guessing # attacks cryptCreateContext encContext CRYPT_UNUSED $cryptAlgo cryptSetAttribute $encContext CRYPT_CTXINFO_KEYSIZE $keySize cryptSetAttribute $encContext CRYPT_CTXINFO_KEYING_ITERATIONS 10000 cryptSetAttributeString $encContext CRYPT_CTXINFO_KEYING_SALT "salt1234" cryptSetAttributeString $encContext CRYPT_CTXINFO_KEYING_VALUE "password123" # Encrypt 10 MB of text set text [binary format a[expr {10 * 1024 * 1024}] \0] set startTime [clock seconds] cryptEncrypt $encContext $text set endTime [clock seconds] puts "$cryptAlgo 10 Mb in [expr {$endTime - $startTime}] seconds" cryptDestroyContext $encContext } cryptInit cryptAddRandom NULL CRYPT_RANDOM_SLOWPOLL testCipher CRYPT_ALGO_HMAC_SHA 32 "HMAC-SHA1 Processed" testCipher CRYPT_ALGO_RC4 16 "RC4 Encrypted" testCipher CRYPT_ALGO_AES 16 "AES-128 CBC Encrypted" testCipher CRYPT_ALGO_AES 32 "AES-256 CBC Encrypted" testCipher CRYPT_ALGO_3DES 24 "3DES CBC Encrypted" cryptEnd
Implementation
Cryptkit is implemented using Critcl and uses the new critcl::cdefines feature that maps C #defines and enums into a Tcl namespace.
For example, cryptkit.tcl uses the following to map Cryptlib symbols (i.e. #defines and enums) into the cryptkit namespace
# map Cryptlib #defines and enums into the current namespace critcl::cdefines CRYPT_* [namespace current] # other defines critcl::cdefines { NULL TRUE FALSE TCL_OK TCL_ERROR } cryptkit
SHA-1 Example
source cryptkit.kit package require cryptkit namespace import cryptkit::* cryptkit::cryptInit proc sha1 {data} { cryptCreateContext hashContext CRYPT_UNUSED CRYPT_ALGO_SHA cryptEncrypt $hashContext $data # Finalize: if you want to stream, wait until the last block to do this. cryptEncrypt $hashContext "" cryptGetAttributeString $hashContext CRYPT_CTXINFO_HASHVALUE hash 20 cryptDestroyContext $hashContext binary scan $hash H* hexhash return $hexhash }
RLH - Is there a way to put the 'source cryptkit.kit' in a pkgIndex file? I like to keep all my stuff in the lib directory (I am on Windows).
02feb05 - The way to do that is to unwrap the starkit, and copy all its lib/* directories to yours. The above "source" is a way to avoid the need for unwrapping when things live in a starkit - it does nothing but mount and add (all packages in) the starkit's lib area to auto_path -jcw
LV There was/is a TIP that aku I think proposed that described tcl modules, right? In that TIP, I was thinking that there was something about being able to distribute Tcl extensions in other forms, such as a starkit.
I know I think that being able to drop a starkit somewhere in $exec_prefix/lib and having a package require find and load it - without having to unwrap the starkit - would make distribution for me a lot easier.
jcw - Do:
foreach x [glob -nocomplain /path/to/my/starkit/collection/*] { source $x }
After that, all packages inside them can be used via package require.
RLH - That is cool...
Lars H: How about this for putting the source command in a pkgIndex file?
package ifneeded cryptkit.kit 0.0 [format { source [file join %s cryptkit.kit] package require cryptkit } [list $dir]]
Whether it will do any good in this particular case I cannot say, but perhaps it can serve as inspiration.
RLH - I tried the above on Windows XP and it does not work. But it would be cool if it did.
stevel - one technique mentioned to me by Steve Redler IV is to put the Starkit somewhere on your PATH, and use auto_execok thus
source [auto_execok cryptkit.kit] package require cryptkit
PT: The following pkgIndex.tcl will work with cryptkit.kit if it is installed in the same directory.
package ifneeded cryptkit 1.0 \ "source [file join $dir cryptkit.kit];\ source [file join $dir cryptkit.kit lib cryptkit critcl.tcl];\ critcl::loadlib [file join $dir cryptkit.kit lib cryptkit] cryptkit 1.0;\ eval \[package ifneeded cryptkit 1.0\]"
I have problems with importing certs witch cryptkit and accessing attributes. I loop on att and I dont't know how to see if an attribute will be in binary form (conversion needeed with binary scan) or in string form. ::cryptkit::cryptGetAttributeString $cert $att attributeNeeded ::cryptkit::NULL Any idea ?
RLH - Does cryptlib/Cryptkit support SHA-256/512?
PT 23-Feb-2005: Not at this time. See the FAQ at [L6 ]
stevel 23-Feb-2005: See also this post where the Cryptlib author puts concerns re SHA-1 into perspective [L7 ]
RLH - I happen to think it is not a real big deal myself but thought I would ask about the others.
Hermann Boeken 13-Aug-2009:
Is cryptkit from http://www.digitalsmarties.com/cryptkit/cryptkit.tar.gz compatible with cryptlib 3.3.3 from http://www.cs.auckland.ac.nz/~pgut001/cryptlib/ ? After building the static cryptlib library, copying the cryptlib.h and libcl.a (renaming it to libcl-linux-ix86.a) to the cryptkit directory and building the cryptkit with critcl2 I get an error when trying to load the package into my tclsh 8.5.4:
% package req cryptkit couldn't load file "/home/hermann/Tcl/cryptkit/lib/cryptkit/linux-ix86/cryptkit.so": /home/hermann/Tcl/cryptkit/lib/cryptkit/linux-ix86/cryptkit.so: undefined symbol: __res_query
Sorry for posting this here, but I couldn't find a better place.
stevel 13-Aug-2009 - That cryptkit version was built against Cryptlib 3.2, and I haven't yet tried building against the latest cryptlib. Re the res_query, depending on the Linux version you might need to add -lresolv to the link arguments.
Hermann Boeken 14-Aug-2009: I found where I had to add -lresolv (in cryptkit.tcl). Now when creating a session I get an error '::cryptkit::cryptCreateSession session CRYPT_UNUSED CRYPT_SESSION_SSH' : expected integer but got "("
Is the previous version of cryptlib (3.2) still available for download?
Acknowledgements
Pierre Coueffin July 20, 2007: All the Digital Smarties links for cryptkit appear to be down. The Starkit is still available, but there is no source tarball anymore. Any idea what happened?
stevel Yes, I changed servers and forgot to copy it. Fixed now.