RSA-1.2.2.0: Implementation of RSA, using the padding schemes of PKCS#1 v2.1.

Safe HaskellNone

Codec.Crypto.RSA

Contents

Description

An implementation of RSA (PKCS #1) Cryptography, as described by the RSA standard and RFC 3447.

Synopsis

Keys and key generations

generateKeyPair :: CryptoRandomGen g => g -> Int -> (PublicKey, PrivateKey, g)Source

Randomly generate a key pair of the given modulus length (in bits) to use in any of the following functions. Use of a good random number generator is of considerable importance when using this function; the input CryptoRandomGen should never be used again for any other purpose.

data PrivateKey

Represent a RSA private key.

Only the pub, d fields are mandatory to fill.

p, q, dP, dQ, qinv are by-product during RSA generation, but are useful to record here to speed up massively the decrypt and sign operation.

implementations can leave optional fields to 0.

High-level encryption and signing functions

encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)Source

Encrypt an arbitrarily-sized message using the defaults for RSA encryption (specifically, using MGF1, SHA-256 as the hash function, and not adding a label). If the message is longer than the underlying encryption function can support, it is broken up into parts and each part is encrypted.

decrypt :: PrivateKey -> ByteString -> ByteStringSource

Decrypt an arbitrarily-sized message using the defaults for RSA decryption (specifically, using MGF1, SHA-256 as the hash function, and not adding a label). If the message is longer than the underlying decryption function supports, it is assumed that the message was generated by concatenating a series of blocks.

While the encryption function, above, can take an arbitrarily-sized message, this function cannot. The message passed must be a multiple of the modulus length.

sign :: PrivateKey -> ByteString -> ByteStringSource

Compute a signature for the given ByteString, using the SHA256 algorithm in the computation. This is currently defined as rsassa_pkcs1_v1_5_sign ha_SHA256. If you want to use a different function, simply use the pkcs function, below; it will accept arbitrary-length messages.

verify :: PublicKey -> ByteString -> ByteString -> BoolSource

Verity a signature for the given ByteString, using the SHA256 algorithm in the computation. Again, if you'd like to use a different algorithm, use the rsassa_pkcs1_v1_5_verify function.

The first bytestring is the message, the second is the signature to check.

data EncryptionOptions Source

Constructors

UseOAEP 

Fields

oaep_hash :: HashFunction

The hash function to use.

oaep_mgf :: MGF

The mask generation function to use.

oaep_label :: ByteString

The label to annotate items with.

UsePKCS1_v1_5 

encrypt' :: CryptoRandomGen g => EncryptionOptions -> g -> PublicKey -> ByteString -> (ByteString, g)Source

Encrypt an arbitrarily-sized message using the given options.

decrypt' :: EncryptionOptions -> PrivateKey -> ByteString -> ByteStringSource

Decrypt an arbitrarily-sized message using the given options. Well, sort of arbitrarily sized; the message should be a multiple of the modulus length.

Core OAEP Routines

type MGF = ByteString -> Int64 -> ByteStringSource

A 'mask generation function'. The input is a bytestring, and the output is a hash of the given length. Unless you know what you're doing, you should probably use a MGF1 formulation created with generate_MGF1.

rsaes_oaep_encrypt :: CryptoRandomGen g => g -> HashFunction -> MGF -> PublicKey -> ByteString -> ByteString -> (ByteString, g)Source

The generalized implementation of RSAES-OAEP-ENCRYPT. Using the default instantiontion of this, provided by the encrypt function, is a pretty good plan if this makes no sense to you, as it is instantiated with reasonable defaults.

The arguments to this function are, in order: the hash function to use, the mask generation function (MGF), the recipient's RSA public key, a random seed, a label to associate with the message, and the message to be encrypted.

The message to be encrypted may not be longer then (k - 2*hLen - 2), where k is the length of the RSA modulus in bytes and hLen is the length of a hash in bytes. Passing in a larger message will generate an error.

I have not put in a check for the length of the label, because I don't expect you to use more than 2^32 bytes. So don't make me regret that, eh?

rsaes_oaep_decrypt :: HashFunction -> MGF -> PrivateKey -> ByteString -> ByteString -> ByteStringSource

The generalized implementation of RSAES-OAEP-DECRYPT. Again, decrypt initializes this with a pretty good set of defaults if you don't understand what all of the arguments involve.

The ciphertext message passed to this function must be k bytes long, where k is the size of the modulus in bytes. If it is not, this function will generate an error.

Futher, k (the length of the ciphertext in bytes) must be greater than or equal to (2 * hLen + 2), where hLen is the length of the output of the hash function in bytes. If this equation does not hold, a (different) error will be generated.

Finally, there are any number of internal situations that may generate an error indicating that decryption failed.

The arguments to this function are the hash function to use, the mask generation function (MGF), the recipient's private key, the optional label whose association with this message should be verified, and the ciphertext message.

generate_MGF1 :: HashFunction -> MGFSource

Generate a mask generation function for the rsaes_oaep_*. As suggested by the name, the generated function is an instance of the MGF1 function. The arguments are the underlying hash function to use and the size of a hash in bytes.

The bytestring passed to the generated function cannot be longer than 2^32 * hLen, where hLen is the passed length of the hash.

Core PSS Routines

|RSASSA-PSS-Sign, RSASSA-PSS-Verify, and the related functions are not included because they are covered by U.S. Patent 7036014, and it's not clear what the restrictions on implementations are.

Core PKCS1 (v1.5) Routines

rsaes_pkcs1_v1_5_encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)Source

Implements RSAES-PKCS1-v1.5-Encrypt, as defined by the spec, for completeness and possible backward compatibility. Also because I've already written everything else, so why not?

This encryption / padding mechanism has several known attacks, which are described in the literature. So unless you absolutely need to use this for some historical reason, you shouldn't.

The message to be encrypted must be less then or equal to (k - 11) bytes long, where k is the length of the key modulus in bytes.

Because this function uses an unknown amount of randomly-generated data, it takes an instance of RandomGen rather than taking a random number as input, and returns the resultant generator as output. You should take care that you (a) do not reuse the input generator, thus losing important randomness, and (b) choose a decent instance of RandomGen for passing to this function.

rsaes_pkcs1_v1_5_decrypt :: PrivateKey -> ByteString -> ByteStringSource

Implements RSAES-PKCS1-v1.5-Decrypt, as defined by the spec, for completeness and possible backward compatibility. Please see the notes for rsaes_pkcs1_v1_5_encrypt regarding use of this function in new applications without historical algorithm requirements

The ciphertext message passed to this function must be of length k, where k is the length of the key modulus in bytes.

rsassa_pkcs1_v1_5_sign :: HashInfo -> PrivateKey -> ByteString -> ByteStringSource

Generates a signature for the given message using the given private key. This is obviously based on RSASSA-PKCS1-v1.5-Sign from the specification. Note that in researching what was required for this project, several independent sources suggested not using the same key across signvalidate and encryptdecrypt contexts.

The output of this function is the signature only, not the message and signature.

rsassa_pkcs1_v1_5_verify :: HashInfo -> PublicKey -> ByteString -> ByteString -> BoolSource

Validates a signature for the given message using the given public key. The arguments are, in order: the hash function to use, the public key, the message, and the signature. The signature must be exactly k bytes long, where k is the size of the RSA modulus in bytes.

Hashing algorithm declarations for use in RSA functions

data HashInfo Source

Constructors

HashInfo 

Fields

algorithmIdent :: ByteString

The ASN.1 DER encoding of the hash function identifier.

hashFunction :: HashFunction

The hash function.