Haskell Cryptographic Library 1.1.2

This library collects together existing Haskell cryptographic functions and augments them so that they:

·        Have common type signatures.

·        Can be used with the standard mode and padding algorithms (in the case of block mode ciphers).

This release contains:

·        DES

·        Blowfish

·        Cipher Block Chaining (CBC) mode

·        PKCS5 and nulls padding

·        SHA-1

·        MD5

·        RSA

·        OAEP

·        ASN.1

·        PKCS#8

System Requirements

The code has been tested on GHC 5.04.1 and Hugs November 2003 and should work on all higher versions. It does not work NHC.

Installation Instructions

Download http://www.haskell.org/crypto/downloads/crypto-1.1.2.tar.

tar -xvf crypto-1.1.2.tar
make depend
make
make install
make doc

You will need to be root to make install. You should then be able to compile and run the test programs from anywhere:

ghc -o Test Test.hs -package crypto
./Test
Testing DES...
Passed
Testing Blowfish...
Passed

ghc -o RSATest RSATest.hs -package crypto

./RSATest

Testing product of primes...

Passed

Testing exponent1...

Passed

Testing encoding...

Passed

Testing encryption...

Passed

 

ghc -o Pkcs8Test Pkcs8Test.hs -package crypto

./Pkcs8Test

[78,111,119,32,105,115,32,116,104,101,32,116,105,109,101,46,46,46,10]

Examples

All examples assume that you have imported the correct modules, for example:

module Main(main) where

 

import Codec.Encryption.Utils

import Codec.Encryption.Blowfish as Blowfish

import Codec.Encryption.Modes

import Codec.Encryption.Padding

import Codec.Encryption.DES as DES

import Data.Word

import Data.Bits

import Numeric

import Char

 

Blowfish Word64 Block with Word8, Word16, Word64 & Word128 Keys

 

See http://www.counterpane.com/vectors.txt for more test vectors.

 

d = 0xFEDCBA9876543210 :: Word64

 

k = 0xF0 :: Word8

e = Blowfish.encrypt k d

 

k2 = 0xF0E1 :: Word16

e2 = Blowfish.encrypt k2 d

 

k8 = 0xF0E1D2C3B4A59687 :: Word64

e8 = Blowfish.encrypt k8 d

 

k16= 0xF0E1D2C3B4A5968778695A4B3C2D1E0F :: Word128

e16 = Blowfish.encrypt k16 d

 

Blowfish Cipher Block Chaining & Nulls Padding

 

key16 = 0x0123456789ABCDEFF0E1D2C3B4A59687 :: Word128

iv8     = 0xFEDCBA9876543210 :: Word64

data29  = "7654321 Now is the time for \NUL"

 

e29 =

   cbc Blowfish.encrypt iv8 key16 $ padNulls $

   map (fromIntegral . ord) data29

 

DES Cipher Block Chaining & PKCS5 Padding

 

Taken from http://www.itl.nist.gov/fipspubs/fip81.htm.

 

key = 0x0123456789abcdef

iv = 0x1234567890abcdef

plainText = "Now is the time for all "

 

cipherText =

   cbc DES.encrypt iv key $ pkcs5 $ map (fromIntegral . ord) plaintext

 

RSA

 

Generate a private key using openssl (http://www.openssl.org/)

openssl genrsa -out private.pem

Convert it to PKCS8 (you can look at it with Peter Gutmann's ASN.1 object dump program http://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c if required). N.B., in this example, the private key is unencrypted. Storing private keys in clear is not good security practice. The current implementation does not support encrypted private keys but this should be straightforward to add.

openssl pkcs8 -topk8 -inform PEM -outform DER -in private.pem -nocrypt -out private.der

Generate a public key from the private key.

openssl rsa -in private.pem -pubout -out public.pem

Create a plaintext file.

echo "Now is the time..." > plaintext

Encrypt it, not forgetting to specify OAEP encoding.

openssl rsautl -encrypt -pubin -inkey public.pem -in plaintext -out ciphertext -oaep

Decrypt it in your Haskell program.

 

module Main(main) where

 

import IO

import Char

import Control.Monad.State

import Codec.ASN1.ASN1 as A

import Codec.Encryption.Utils

import Codec.Encryption.PKCS8

import Codec.Encryption.SHA1

import Codec.Encryption.MGF

import Codec.Encryption.EMEOAEP as E

import Codec.Encryption.RSA

 

plaintext n d x =

   E.decode mgf hash [] $

   decrypt (n,d) $

   map (fromIntegral . ord) x

 

main =

   do ifh <- openFile "private.der" ReadMode

      (x,y) <- A.decode ifh

      let z = fromASN NoTag y

      x <- readFile "ciphertext"

      putStrLn $ show $ plaintext (toOctets $ modulus $ privateKey z)

                                  (toOctets $ privateExponent $ privateKey z) x

To Do

In no particular order:

·        Read and generate PKCS12 private keys so that it is easy to inter-work with other RSA implementations.

·        X.509 certificates.

·        Incorporate other symmetric key algorithms already coded in Haskell.

·        AES.

·        Performance analysis as Blowfish ought to run more quickly than DES.

·        Other modes / padding schemes.

·        XML encryption and digital signatures.

Links

http://www.hcsw.org/haskell

http://www.electronconsulting.com/rsa-haskell

http://web.comlab.ox.ac.uk/oucl/work/ian.lynagh

Contact

All questions, comments, bug reports, flames, requests for updates / changes and suggestions should be directed to .

Licensing

The modules in the library come from different authors and have been released under different licences. See the source code of each module for the license under which it has been released.

Disclaimer

Cryptography is a notoriously easy area in which to make mistakes, not necessarily with the algorithms but with how they are implemented (for example not protecting keys, using weak keys and so on). For a readable account of some of the pitfalls, see Ross Anderson’s book.

THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Acknowledgements

Doug Hoyte (HardCore SoftWare)

 

Ian Lynagh (http://web.comlab.ox.ac.uk/oucl/work/ian.lynagh)

 

David Sankel (http://www.electronconsulting.com/whois.html)

 

Ross Paterson (http://www.soi.city.ac.uk/~ross)

======================================================================
Copyright © 2003 - 2004 Dominic Steinitz. Last updated on 24th January 04.
======================================================================