11

I am creating various processes that do different tasks. One of them and only one of them, has a security module that creates the PyCrypto objects. So my program starts, creates the various processes, the process that handles messages uses the security module to decrypt and I get the following errors:

   firstSymKeybin = self.cipher.decrypt(encFirstSymKeybin, '')
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Cipher/PKCS1_v1_5.py", line 206, in decrypt
    m = self._key.decrypt(ct)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 174, in decrypt
    return pubkey.pubkey.decrypt(self, ciphertext)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/pubkey.py", line 93, in decrypt
    plaintext=self._decrypt(ciphertext)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 235, in _decrypt
    r = getRandomRange(1, self.key.n-1, randfunc=self._randfunc)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Util/number.py", line 123, in getRandomRange
    value = getRandomInteger(bits, randfunc)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Util/number.py", line 104, in getRandomInteger
    S = randfunc(N>>3)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 187, in read
    return self._singleton.read(bytes)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 163, in read
    return _UserFriendlyRNG.read(self, bytes)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 122, in read
    self._check_pid()
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Random/_UserFriendlyRNG.py", line 138, in _check_pid
    raise AssertionError("PID check failed. RNG must be re-initialized after fork(). Hint: Try Random.atfork()")
AssertionError: PID check failed. RNG must be re-initialized after fork(). Hint: Try Random.atfork()

Decrypting works well on interactive, when not called from a process.

My security module looks like this:

'''
Created on 25 Apr 2013

@author: max
'''

import base64, ast, binascii
from Crypto.Cipher import AES
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
import br_consts

class SecurityMod(object):
    '''
    classdocs
    '''

    def __init__(self):
        '''
        Constructor
        '''
        super(SecurityMod,self).__init__()
        self.privkey = RSA.importKey(open('./privkeyBR.pem', 'r').read())
        self.cipher = PKCS1_v1_5.new(self.privkey)
        self.ridToKeySalt = {}

    #depending on the type of message, encryption format is different 
    def encrypt(self, msg, rqId, rid):
        ##code
        return encMsg

    #return string of object so it can be parse by JSON
    def decrypt(self, encMsg, rqId, rid):

       #code
        return msgObjStr



    def pad_data(self,data):
        if len(data) == 0:
            return data
        if len(data) % 16 == 0:
            padding_required = 15
        else:
            padding_required = 15 - (len(data) % 16)
        data = '%s\x80' % data
        data = '%s%s' % (data, '\x00' * padding_required)
        return data


    def unpad_data(self,data):
        if not data:
            return data
        data = data.rstrip('\x00')
        if data[-1] == '\x80': 
            return data[:-1]
        else:
            return data
Anthony Hilyard
  • 1,220
  • 12
  • 27
unixsnob
  • 1,685
  • 2
  • 19
  • 45

2 Answers2

8

You need to call Crypto.Random.atfork() after os.fork()

I just put the __init__() in the security module before the other ones

Zulu
  • 8,765
  • 9
  • 49
  • 56
unixsnob
  • 1,685
  • 2
  • 19
  • 45
0

Installing the pycryptodome package fixed this issue for me on Mac and Linux. It is a fork of the Pycrypto package.

pip install pycryptodome

Here is the link to their docs: https://pycryptodome.readthedocs.io/en/latest/index.html

imapotatoe123
  • 656
  • 1
  • 10
  • 21
  • Should note that this library modifies the PyCrypto library and some of your functions may not work all of the sudden. Even after uninstalling pycryptodome, you would still need to re-install pycrypto in order to repair it. The right answer is as @unixsnob suggested is to just use the `Crypto.Random.atfork()`. – shaqed Aug 06 '19 at 07:30
  • The Crypto.Random.atfork() didn't work on my system, which is why I posted the above. – imapotatoe123 Aug 06 '19 at 09:55