Google App Engine + PyCrypto = /dev/urandom not accessible
Question: I am using Google App Engine and PyCrypto to do some encryption. The error I
am getting, which is below, occurs _only on my local developement server,_
which is running Linux Mint Maya (13). I deployed the same code to the GAE
cloud, and it runs without error.

    
    
    ERROR    2012-06-29 16:04:20,717 webapp2.py:1553] [Errno 13] file not accessible: '/dev/urandom'
    Traceback (most recent call last):
      File "/home/eric/google_appengine/lib/webapp2/webapp2.py", line 1536, in __call__
        rv = self.handle_exception(request, response, e)
      File "/home/eric/google_appengine/lib/webapp2/webapp2.py", line 1530, in __call__
        rv = self.router.dispatch(request, response)
      File "/home/eric/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
        return route.handler_adapter(request, response)
      File "/home/eric/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
        return handler.dispatch()
      File "/home/eric/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
        return self.handle_exception(e, self.app.debug)
      File "/home/eric/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
        return method(*args, **kwargs)
      File "/home/eric/workspace/commentbox/src/controller/api.py", line 55, in get
        self.response.out.write(encrypt(json.dumps(to_json)))
      File "/home/eric/workspace/commentbox/src/controller/api.py", line 27, in encrypt
        iv = Random.new().read(AES.block_size)
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/__init__.py", line 33, in new
        return _UserFriendlyRNG.new(*args, **kwargs)
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 206, in new
        return RNGFile(_get_singleton())
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 200, in _get_singleton
        _singleton = _LockingUserFriendlyRNG()
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 144, in __init__
        _UserFriendlyRNG.__init__(self)
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 86, in __init__
        self._ec = _EntropyCollector(self._fa)
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 53, in __init__
        self._osrng = OSRNG.new()
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/OSRNG/posix.py", line 60, in new
        return DevURandomRNG(*args, **kwargs)
      File "/usr/lib/python2.7/dist-packages/Crypto/Random/OSRNG/posix.py", line 42, in __init__
        f = open(self.name, "rb", 0)
      File "/home/eric/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 592, in __init__
        raise IOError(errno.EACCES, 'file not accessible', filename)
    IOError: [Errno 13] file not accessible: '/dev/urandom'
    ERROR    2012-06-29 16:04:20,721 webapp2.py:1549] Exception 
    ERROR    2012-06-29 16:04:20,721 webapp2.py:1549] AttributeError
    ERROR    2012-06-29 16:04:20,721 webapp2.py:1549] : 
    ERROR    2012-06-29 16:04:20,721 webapp2.py:1549] "'DevURandomRNG' object has no attribute 'closed'"
    ERROR    2012-06-29 16:04:20,721 webapp2.py:1549]  in 
    ERROR    2012-06-29 16:04:20,721 webapp2.py:1549] <bound method DevURandomRNG.__del__ of <Crypto.Random.OSRNG.posix.DevURandomRNG object at 0x52707d0>>
    ERROR    2012-06-29 16:04:20,721 webapp2.py:1549]  ignored
    

The python code that is throwing the error is the second line in this block:

    
    
    from Crypto.Cipher import AES
    from Crypto import Random
    
    key = b'Sixteen byte key' 
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    return iv + cipher.encrypt(plaintext)
    

After seeing this error, [I realized it might be a permissions
error](http://serverfault.com/questions/391386/why-is-dev-urandom-only-
readable-by-root-since-ubuntu-12-04-and-how-can-i-fix). So then I did a quick
check of the permissions on /dev/urandom:

    
    
    eric@eric-Latitude-E5400 ~ $ dpkg -L udev | xargs grep urandom
    /lib/udev/rules.d/50-udev-default.rules:KERNEL=="null|zero|full|random|urandom", MODE="0666"
    eric@eric-Latitude-E5400 ~ $ ls -lart /dev/*random
    crw-rw-rw- 1 root root 1, 9 Jun 29 10:53 /dev/urandom
    crw-rw-rw- 1 root root 1, 8 Jun 29 10:53 /dev/random
    

So it looks like my permissions are fine. I have also tried running the
development server as root, but I get the same error. For some reason this
only happens with the development server, and not when deployed to google's
cloud. Any ideas on what to try next?

Thanks!


Answer: The error you are getting is because GAE restricts file access, and
[/dev/urandom](http://en.wikipedia.org/wiki//dev/random#Linux) is blocked.

Note that the error is not when you import PyCrypto, it's when you do
`AES.new(key, AES.MODE_CBC, iv)`

You can fix it, either by editing `Crypto/Random/OSRNG/__init__.py` and moving
the lines

    
    
    if hasattr(os, 'urandom'):
        from Crypto.Random.OSRNG.fallback import new
    

to the top, or by modifying os.name to something different than posix or nt,
at the beginning of your script. I suggest the first option.

ps: I assume you are using python 2.5 and pycrypto 2.2, because of your
Traceback. Next time please include these details.

