summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2012-04-10 21:26:33 +0200
committerLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2012-04-10 21:26:33 +0200
commita7123247de876c8bafbd1d60a349d861e7111d58 (patch)
tree386c567ae57bb64998cd04c7482bffb2571920e2
parent7ad012fae30f558e40efdd541e4e6503e47343b1 (diff)
downloadpycrypto-a7123247de876c8bafbd1d60a349d861e7111d58.tar.gz
Refreshed documentation for RSA. epydoc does not generate documentation for private methods, and inherited ones are made more explicit.
-rw-r--r--Doc/epydoc-config7
-rw-r--r--lib/Crypto/PublicKey/DSA.py2
-rw-r--r--lib/Crypto/PublicKey/RSA.py147
-rw-r--r--lib/Crypto/PublicKey/pubkey.py122
4 files changed, 234 insertions, 44 deletions
diff --git a/Doc/epydoc-config b/Doc/epydoc-config
index 018e461..c71d200 100644
--- a/Doc/epydoc-config
+++ b/Doc/epydoc-config
@@ -8,6 +8,13 @@ output: html
target: Doc/apidoc/
sourcecode: no
+# Do not include private variables
+private: no
+
+# Include the complete set of inherited methods, but grouped in a special
+# section
+inheritance: grouped
+
name: PyCrypto API Documentation
url: http://www.pycrypto.org/
diff --git a/lib/Crypto/PublicKey/DSA.py b/lib/Crypto/PublicKey/DSA.py
index 5c349a9..71254a5 100644
--- a/lib/Crypto/PublicKey/DSA.py
+++ b/lib/Crypto/PublicKey/DSA.py
@@ -26,7 +26,7 @@
__revision__ = "$Id$"
-__all__ = ['generate', 'construct', 'error']
+__all__ = ['generate', 'construct', 'error', 'DSAImplementation', '_DSAobj']
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
diff --git a/lib/Crypto/PublicKey/RSA.py b/lib/Crypto/PublicKey/RSA.py
index 1e3a433..8849985 100644
--- a/lib/Crypto/PublicKey/RSA.py
+++ b/lib/Crypto/PublicKey/RSA.py
@@ -24,13 +24,45 @@
"""RSA public-key cryptography algorithm.
+RSA_ is the most widespread and used public key algorithm. Its security is
+based on the difficulty of factoring large integers. The algorithm has
+withstood attacks for 30 years, and it is therefore considered reasonably
+secure for new designs.
+
+The algorithm can be used for both confidentiality (encryption) and
+authentication (digital signature). It is worth noting that signing and
+decryption are significantly slower than verification and encryption.
+The cryptograhic strength is primarily linked to the length of the modulus.
+In 2012, a sufficient length is deemed to be 2048 bits. For more information,
+see the most recent ECRYPT_ report.
+
+This module provides facilities for generating fresh, new RSA keys, constructing
+them from known components, exporting them, and importing them.
+
+ >>> from Crypto.PublicKey import RSA
+ >>>
+ >>> key = RSA.generate(2048)
+ >>> f = open('mykey.pem','w')
+ >>> f.write(RSA.exportKey('PEM'))
+ >>> f.close()
+ ...
+ >>> f = open('mykey.pem','r')
+ >>> key = RSA.importKey(f.read())
+
+Even though you may choose to directly use the methods of an RSA key object
+to perform the primitive cryptographic operations (e.g. `_RSAobj.encrypt`),
+it is recommended to use one of the standardized schemes instead (like
+`Crypto.Cipher.PKCS1_v1_5` or `Crypto.Signature.PKCS1_v1_5`).
+
+.. _RSA: http://en.wikipedia.org/wiki/RSA_%28algorithm%29
+.. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf
+
:sort: generate,construct,importKey,error
-:undocumented: _fastmath, __revision__, _impl
"""
__revision__ = "$Id$"
-__all__ = ['generate', 'construct', 'error', 'importKey' ]
+__all__ = ['generate', 'construct', 'error', 'importKey', 'RSAImplementation', '_RSAobj']
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
@@ -56,8 +88,10 @@ except ImportError:
_fastmath = None
class _RSAobj(pubkey.pubkey):
- """Class defining an actual RSA key."""
+ """Class defining an actual RSA key.
+ :undocumented: __getstate__, __setstate__, __repr__, __getattr__
+ """
#: Dictionary of RSA parameters.
#:
#: A public key will only have the following entries:
@@ -88,6 +122,101 @@ class _RSAobj(pubkey.pubkey):
else:
raise AttributeError("%s object has no %r attribute" % (self.__class__.__name__, attrname,))
+ def encrypt(self, plaintext, K):
+ """Encrypt a piece of data with RSA.
+
+ :Parameter plaintext: The piece of data to encrypt with RSA. It may not
+ be numerically larger than the RSA module (**n**).
+ :Type plaintext: byte string or long
+
+ :Parameter K: A random parameter (*for compatibility only. This
+ value will be ignored*)
+ :Type K: byte string or long
+
+ :attention: this function performs the plain, primitive RSA encryption
+ (*schoolbook*). In real applications, you always need to use proper
+ cryptographic padding, and you should not directly encrypt data with
+ this method. Failure to do so may lead to security vulnerabilities.
+ It is recommended to use modules
+ `Crypto.Cipher.PKCS1_OAEP` or `Crypto.Cipher.PKCS1_v1_5` instead.
+
+ :Return: A tuple with two items. The first item is the ciphertext
+ of the same type as the plaintext (string or long). The second item
+ is always None.
+ """
+ return pubkey.pubkey.encrypt(self, plaintext, K)
+
+ def decrypt(self, ciphertext):
+ """Decrypt a piece of data with RSA.
+
+ Decryption always takes place with blinding.
+
+ :attention: this function performs the plain, primitive RSA decryption
+ (*schoolbook*). In real applications, you always need to use proper
+ cryptographic padding, and you should not directly decrypt data with
+ this method. Failure to do so may lead to security vulnerabilities.
+ It is recommended to use modules
+ `Crypto.Cipher.PKCS1_OAEP` or `Crypto.Cipher.PKCS1_v1_5` instead.
+
+ :Parameter ciphertext: The piece of data to decrypt with RSA. It may
+ not be numerically larger than the RSA module (**n**). If a tuple,
+ the first item is the actual ciphertext; the second item is ignored.
+
+ :Type ciphertext: byte string, long or a 2-item tuple as returned by
+ `encrypt`
+
+ :Return: A byte string if ciphertext was a byte string or a tuple
+ of byte strings. A long otherwise.
+ """
+ return pubkey.pubkey.decrypt(self, ciphertext)
+
+ def sign(self, M, K):
+ """Sign a piece of data with RSA.
+
+ Signing always takes place with blinding.
+
+ :attention: this function performs the plain, primitive RSA decryption
+ (*schoolbook*). In real applications, you always need to use proper
+ cryptographic padding, and you should not directly sign data with
+ this method. Failure to do so may lead to security vulnerabilities.
+ It is recommended to use modules
+ `Crypto.Signature.PKCS1_PSS` or `Crypto.Signature.PKCS1_v1_5` instead.
+
+ :Parameter M: The piece of data to sign with RSA. It may
+ not be numerically larger than the RSA module (**n**).
+ :Type M: byte string or long
+
+ :Parameter K: A random parameter (*for compatibility only. This
+ value will be ignored*)
+ :Type K: byte string or long
+
+ :Return: A 2-item tuple. The first item is the actual signature (a
+ long). The second item is always None.
+ """
+ return pubkey.pubkey.sign(self, M, K)
+
+ def verify(self, M, signature):
+ """Verify the validity of an RSA signature.
+
+ :attention: this function performs the plain, primitive RSA encryption
+ (*schoolbook*). In real applications, you always need to use proper
+ cryptographic padding, and you should not directly verify data with
+ this method. Failure to do so may lead to security vulnerabilities.
+ It is recommended to use modules
+ `Crypto.Signature.PKCS1_PSS` or `Crypto.Signature.PKCS1_v1_5` instead.
+
+ :Parameter M: The expected message.
+ :Type M: byte string or long
+
+ :Parameter signature: The RSA signature to verify. The first item of
+ the tuple is the actual signature (a long not larger than the modulus
+ **n**), whereas the second item is always ignored.
+ :Type signature: A 2-item tuple as return by `sign`
+
+ :Return: True if the signature is correct, False otherwise.
+ """
+ return pubkey.pubkey.verify(self, M, signature)
+
def _encrypt(self, c, K):
return (self.key._encrypt(c),)
@@ -195,7 +324,7 @@ class _RSAobj(pubkey.pubkey):
PKCS standards are not relevant for the *OpenSSH* format.
:Type pkcs: integer
- :Return: A string with the encoded public or private half.
+ :Return: A byte string with the encoded public or private half.
:Raise ValueError:
When the format is unknown.
"""
@@ -317,7 +446,7 @@ class RSAImplementation(object):
return self._current_randfunc
def generate(self, bits, randfunc=None, progress_func=None, e=65537):
- """Randomly generate a fresh, new RSA key object.
+ """Randomly generate a fresh, new RSA key.
:Parameters:
bits : int
@@ -349,6 +478,8 @@ class RSAImplementation(object):
:attention: Exponent 3 is also widely used, but it requires very special care when padding
the message.
+ :Return: An RSA key object (`_RSAobj`).
+
:Raise ValueError:
When **bits** is too little or not a multiple of 256, or when
**e** is not odd or smaller than 2.
@@ -364,7 +495,7 @@ class RSAImplementation(object):
return _RSAobj(self, key)
def construct(self, tup):
- """Construct an RSA key object from a tuple of valid RSA components.
+ """Construct an RSA key from a tuple of valid RSA components.
The modulus **n** must be the product of two primes.
The public exponent **e** must be odd and larger than 1.
@@ -387,6 +518,8 @@ class RSAImplementation(object):
4. First factor of n (p). Optional.
5. Second factor of n (q). Optional.
6. CRT coefficient, (1/p) mod q (u). Optional.
+
+ :Return: An RSA key object (`_RSAobj`).
"""
key = self._math.rsa_construct(*tup)
return _RSAobj(self, key)
@@ -458,6 +591,8 @@ class RSAImplementation(object):
In case of an encrypted PEM key, this is the pass phrase from which the encryption key is derived.
:Type passphrase: string
+ :Return: An RSA key object (`_RSAobj`).
+
:Raise ValueError/IndexError/TypeError:
When the given key cannot be parsed (possibly because the pass phrase is wrong).
"""
diff --git a/lib/Crypto/PublicKey/pubkey.py b/lib/Crypto/PublicKey/pubkey.py
index 90f4603..e44de8f 100644
--- a/lib/Crypto/PublicKey/pubkey.py
+++ b/lib/Crypto/PublicKey/pubkey.py
@@ -31,6 +31,10 @@ from Crypto.Util.number import *
# Basic public key class
class pubkey:
+ """An abstract class for a public key object.
+
+ :undocumented: __getstate__, __setstate__, __eq__, __ne__, validate
+ """
def __init__(self):
pass
@@ -52,9 +56,16 @@ integers, MPZ objects, or whatever."""
if d.has_key(key): self.__dict__[key]=bignum(d[key])
def encrypt(self, plaintext, K):
- """encrypt(plaintext:string|long, K:string|long) : tuple
- Encrypt the string or integer plaintext. K is a random
- parameter required by some algorithms.
+ """Encrypt a piece of data.
+
+ :Parameter plaintext: The piece of data to encrypt.
+ :Type plaintext: byte string or long
+
+ :Parameter K: A random parameter required by some algorithms
+ :Type K: byte string or long
+
+ :Return: A tuple with two items. Each item is of the same type as the
+ plaintext (string or long).
"""
wasString=0
if isinstance(plaintext, types.StringType):
@@ -66,8 +77,13 @@ integers, MPZ objects, or whatever."""
else: return ciphertext
def decrypt(self, ciphertext):
- """decrypt(ciphertext:tuple|string|long): string
- Decrypt 'ciphertext' using this key.
+ """Decrypt a piece of data.
+
+ :Parameter ciphertext: The piece of data to decrypt.
+ :Type ciphertext: byte string, long or a 2-item tuple as returned by `encrypt`
+
+ :Return: A byte string if ciphertext was a byte string or a tuple
+ of byte strings. A long otherwise.
"""
wasString=0
if not isinstance(ciphertext, types.TupleType):
@@ -79,9 +95,15 @@ integers, MPZ objects, or whatever."""
else: return plaintext
def sign(self, M, K):
- """sign(M : string|long, K:string|long) : tuple
- Return a tuple containing the signature for the message M.
- K is a random parameter required by some algorithms.
+ """Sign a piece of data.
+
+ :Parameter M: The piece of data to encrypt.
+ :Type M: byte string or long
+
+ :Parameter K: A random parameter required by some algorithms
+ :Type K: byte string or long
+
+ :Return: A tuple with two items.
"""
if (not self.has_private()):
raise TypeError('Private key not available in this object')
@@ -90,9 +112,15 @@ integers, MPZ objects, or whatever."""
return self._sign(M, K)
def verify (self, M, signature):
- """verify(M:string|long, signature:tuple) : bool
- Verify that the signature is valid for the message M;
- returns true if the signature checks out.
+ """Verify the validity of a signature.
+
+ :Parameter M: The expected message.
+ :Type M: byte string or long
+
+ :Parameter signature: The signature to verify.
+ :Type signature: tuple with two items, as return by `sign`
+
+ :Return: True if the signature is correct, False otherwise.
"""
if isinstance(M, types.StringType): M=bytes_to_long(M)
return self._verify(M, signature)
@@ -103,8 +131,15 @@ integers, MPZ objects, or whatever."""
DeprecationWarning)
def blind(self, M, B):
- """blind(M : string|long, B : string|long) : string|long
- Blind message M using blinding factor B.
+ """Blind a message to prevent certain side-channel attacks.
+
+ :Parameter M: The message to blind.
+ :Type M: byte string or long
+
+ :Parameter B: Blinding factor.
+ :Type B: byte string or long
+
+ :Return: A byte string if M was so. A long otherwise.
"""
wasString=0
if isinstance(M, types.StringType):
@@ -115,8 +150,13 @@ integers, MPZ objects, or whatever."""
else: return blindedmessage
def unblind(self, M, B):
- """unblind(M : string|long, B : string|long) : string|long
- Unblind message M using blinding factor B.
+ """Unblind a message after cryptographic processing.
+
+ :Parameter M: The encoded message to unblind.
+ :Type M: byte string or long
+
+ :Parameter B: Blinding factor.
+ :Type B: byte string or long
"""
wasString=0
if isinstance(M, types.StringType):
@@ -131,29 +171,35 @@ integers, MPZ objects, or whatever."""
# signature-only algorithms. They both return Boolean values
# recording whether this key's algorithm can sign and encrypt.
def can_sign (self):
- """can_sign() : bool
- Return a Boolean value recording whether this algorithm can
- generate signatures. (This does not imply that this
- particular key object has the private information required to
- to generate a signature.)
+ """Tell if the algorithm can deal with cryptographic signatures.
+
+ This property concerns the *algorithm*, not the key itself.
+ It may happen that this particular key object hasn't got
+ the private information required to generate a signature.
+
+ :Return: boolean
"""
return 1
def can_encrypt (self):
- """can_encrypt() : bool
- Return a Boolean value recording whether this algorithm can
- encrypt data. (This does not imply that this
- particular key object has the private information required to
- to decrypt a message.)
+ """Tell if the algorithm can deal with data encryption.
+
+ This property concerns the *algorithm*, not the key itself.
+ It may happen that this particular key object hasn't got
+ the private information required to decrypt data.
+
+ :Return: boolean
"""
return 1
def can_blind (self):
- """can_blind() : bool
- Return a Boolean value recording whether this algorithm can
- blind data. (This does not imply that this
- particular key object has the private information required to
- to blind a message.)
+ """Tell if the algorithm can deal with data blinding.
+
+ This property concerns the *algorithm*, not the key itself.
+ It may happen that this particular key object hasn't got
+ the private information required carry out blinding.
+
+ :Return: boolean
"""
return 0
@@ -161,21 +207,23 @@ integers, MPZ objects, or whatever."""
# subclasses.
def size (self):
- """size() : int
- Return the maximum number of bits that can be handled by this key.
+ """Tell the maximum number of bits that can be handled by this key.
+
+ :Return: int
"""
return 0
def has_private (self):
- """has_private() : bool
- Return a Boolean denoting whether the object contains
- private components.
+ """Tell if the key object contains private components.
+
+ :Return: bool
"""
return 0
def publickey (self):
- """publickey(): object
- Return a new key object containing only the public information.
+ """Construct a new key carrying only the public information.
+
+ :Return: A new `pubkey` object.
"""
return self