~vcs-imports/paramiko/trunk

« back to all changes in this revision

Viewing changes to paramiko/pkey.py

  • Committer: Alex Gaynor
  • Date: 2014-03-30 02:22:36 UTC
  • mto: This revision was merged to the branch mainline in revision 746.
  • Revision ID: git-v1:6f211115f49edcea7d23b764d7cf3a84ff12f5f0
Switch from using PyCrypto's Random to using os.urandom.

There's several reasons for this change:

1) It's faster for reads up to 1024 bytes (nearly 10x faster for 16 byte reads)
2) It receives considerably more security review since it's in the kernel.
3) It's yet another step towards running on PyPy.
4) Using userspace CSPRNGs is considered something of an anti-pattern. See:
   http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
   http://webcache.googleusercontent.com/search?q=cache:2nTvpCgKZXIJ:www.2uo.de/myths-about-urandom/+&cd=3&hl=en&ct=clnk&gl=us

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
from Crypto.Cipher import DES3, AES
29
29
 
30
30
from paramiko import util
31
 
from paramiko.common import o600, rng, zero_byte
 
31
from paramiko.common import o600, zero_byte
32
32
from paramiko.py3compat import u, encodebytes, decodebytes, b
33
33
from paramiko.ssh_exception import SSHException, PasswordRequiredException
34
34
 
138
138
        """
139
139
        return u(encodebytes(self.asbytes())).replace('\n', '')
140
140
 
141
 
    def sign_ssh_data(self, rng, data):
 
141
    def sign_ssh_data(self, data):
142
142
        """
143
143
        Sign a blob of data with this private key, and return a `.Message`
144
144
        representing an SSH signature message.
145
145
 
146
 
        :param .Crypto.Util.rng.RandomPool rng: a secure random number generator.
147
146
        :param str data: the data to sign.
148
147
        :return: an SSH signature `message <.Message>`.
149
148
        """
331
330
            keysize = self._CIPHER_TABLE[cipher_name]['keysize']
332
331
            blocksize = self._CIPHER_TABLE[cipher_name]['blocksize']
333
332
            mode = self._CIPHER_TABLE[cipher_name]['mode']
334
 
            salt = rng.read(16)
 
333
            salt = os.urandom(16)
335
334
            key = util.generate_key_bytes(MD5, salt, password, keysize)
336
335
            if len(data) % blocksize != 0:
337
336
                n = blocksize - len(data) % blocksize
338
 
                #data += rng.read(n)
 
337
                #data += os.urandom(n)
339
338
                # that would make more sense ^, but it confuses openssh.
340
339
                data += zero_byte * n
341
340
            data = cipher.new(key, mode, salt).encrypt(data)