def encrypt(self, plainData): """ Encrypt the plainData using the existing Content Key (CK) and return a new EncryptedContent. :param plainData: The data to encrypt. :type plainData: Blob or an array which implements the buffer protocol :return: The new EncryptedContent. :rtype: EncryptedContent """ # Generate the initial vector. initialVector = bytearray(EncryptorV2.AES_IV_SIZE) for i in range(len(initialVector)): initialVector[i] = _systemRandom.randint(0, 0xff) params = EncryptParams(EncryptAlgorithmType.AesCbc) params.setInitialVector(Blob(initialVector, False)) encryptedData = AesAlgorithm.encrypt(Blob(self._ckBits, False), Blob(plainData, False), params) content = EncryptedContent() content.setInitialVector(params.getInitialVector()) content.setPayload(encryptedData) content.setKeyLocatorName(self._ckName) return content
def encrypt(self, plainData): """ Encrypt the plainData using the existing Content Key (CK) and return a new EncryptedContent. :param plainData: The data to encrypt. :type plainData: Blob or an array which implements the buffer protocol :return: The new EncryptedContent. :rtype: EncryptedContent """ # Generate the initial vector. initialVector = bytearray(EncryptorV2.AES_IV_SIZE) for i in range(len(initialVector)): initialVector[i] = _systemRandom.randint(0, 0xff) params = EncryptParams(EncryptAlgorithmType.AesCbc) params.setInitialVector(Blob(initialVector, False)) encryptedData = AesAlgorithm.encrypt( Blob(self._ckBits, False), Blob(plainData, False), params) content = EncryptedContent() content.setInitialVector(params.getInitialVector()) content.setPayload(encryptedData) content.setKeyLocatorName(self._ckName) return content
def _doDecrypt(content, ckBits, onSuccess, onError): """ :param EncryptedContent content: :param Blob ckBits: :param onSuccess: On success, this calls onSuccess(plainData) where plainData is a Blob. :param onError: On error, this calls onError(errorCode, message) :type onError: function object """ if not content.hasInitialVector(): onError( EncryptError.ErrorCode.MissingRequiredInitialVector, "Expecting Initial Vector in the encrypted content, but it is not present" ) return try: params = EncryptParams(EncryptAlgorithmType.AesCbc) params.setInitialVector(content.getInitialVector()) plainData = AesAlgorithm.decrypt(ckBits, content.getPayload(), params) except Exception as ex: onError(EncryptError.ErrorCode.DecryptionFailure, "Decryption error in doDecrypt: " + repr(ex)) return try: onSuccess(plainData) except: logging.exception("Error in onSuccess")
def _doDecrypt(content, ckBits, onSuccess, onError): """ :param EncryptedContent content: :param Blob ckBits: :param onSuccess: On success, this calls onSuccess(plainData) where plainData is a Blob. :param onError: On error, this calls onError(errorCode, message) :type onError: function object """ if not content.hasInitialVector(): onError(EncryptError.ErrorCode.MissingRequiredInitialVector, "Expecting Initial Vector in the encrypted content, but it is not present") return try: params = EncryptParams(EncryptAlgorithmType.AesCbc) params.setInitialVector(content.getInitialVector()) plainData = AesAlgorithm.decrypt( ckBits, content.getPayload(), params) except Exception as ex: onError(EncryptError.ErrorCode.DecryptionFailure, "Decryption error in doDecrypt: " + repr(ex)) return try: onSuccess(plainData) except: logging.exception("Error in onSuccess")
def _decrypt(encryptedContent, keyBits, onPlainText, onError): """ Decrypt encryptedContent using keyBits. :param encryptedContent: The EncryptedContent to decrypt, or a Blob which is first decoded as an EncryptedContent. :type encryptedContent: Blob or EncryptedContent :param {Blob} keyBits The key value. :param onPlainText: When encryptedBlob is decrypted, this calls onPlainText(decryptedBlob) with the decrypted Blob. :type onPlainText: function object :param onError: This calls onError(errorCode, message) for an error, where errorCode is from EncryptError.ErrorCode and message is a str. :type onError: function object """ if isinstance(encryptedContent, Blob): # Decode as EncryptedContent. encryptedBlob = encryptedContent encryptedContent = EncryptedContent() encryptedContent.wireDecode(encryptedBlob) payload = encryptedContent.getPayload() if encryptedContent.getAlgorithmType() == EncryptAlgorithmType.AesCbc: # Prepare the parameters. decryptParams = EncryptParams(EncryptAlgorithmType.AesCbc) decryptParams.setInitialVector(encryptedContent.getInitialVector()) # Decrypt the content. try: content = AesAlgorithm.decrypt(keyBits, payload, decryptParams) except Exception as ex: try: onError(EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex)) except: logging.exception("Error in onError") return onPlainText(content) elif encryptedContent.getAlgorithmType( ) == EncryptAlgorithmType.RsaOaep: # Prepare the parameters. decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep) # Decrypt the content. try: content = RsaAlgorithm.decrypt(keyBits, payload, decryptParams) except Exception as ex: Consumer._callOnError( onError, EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex)) return onPlainText(content) else: Consumer._callOnError( onError, EncryptError.ErrorCode.UnsupportedEncryptionScheme, repr(encryptedContent.getAlgorithmType()))
def _decrypt(encryptedContent, keyBits, onPlainText, onError): """ Decrypt encryptedContent using keyBits. :param encryptedContent: The EncryptedContent to decrypt, or a Blob which is first decoded as an EncryptedContent. :type encryptedContent: Blob or EncryptedContent :param {Blob} keyBits The key value. :param onPlainText: When encryptedBlob is decrypted, this calls onPlainText(decryptedBlob) with the decrypted Blob. :type onPlainText: function object :param onError: This calls onError(errorCode, message) for an error, where errorCode is from EncryptError.ErrorCode and message is a str. :type onError: function object """ if isinstance(encryptedContent, Blob): # Decode as EncryptedContent. encryptedBlob = encryptedContent encryptedContent = EncryptedContent() encryptedContent.wireDecode(encryptedBlob) payload = encryptedContent.getPayload() if encryptedContent.getAlgorithmType() == EncryptAlgorithmType.AesCbc: # Prepare the parameters. decryptParams = EncryptParams(EncryptAlgorithmType.AesCbc) decryptParams.setInitialVector(encryptedContent.getInitialVector()) # Decrypt the content. try: content = AesAlgorithm.decrypt(keyBits, payload, decryptParams) except Exception as ex: try: onError(EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex)) except: logging.exception("Error in onError") return onPlainText(content) elif encryptedContent.getAlgorithmType() == EncryptAlgorithmType.RsaOaep: # Prepare the parameters. decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep) # Decrypt the content. try: content = RsaAlgorithm.decrypt(keyBits, payload, decryptParams) except Exception as ex: Consumer._callOnError(onError, EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex)) return onPlainText(content) else: Consumer._callOnError(onError, EncryptError.ErrorCode.UnsupportedEncryptionScheme, repr(encryptedContent.getAlgorithmType()))
def createContentKey(self, timeSlot, onEncryptedKeys, onError=defaultOnError): """ Create the content key corresponding to the timeSlot. This first checks if the content key exists. For an existing content key, this returns the content key name directly. If the key does not exist, this creates one and encrypts it using the corresponding E-KEYs. The encrypted content keys are passed to the onEncryptedKeys callback. :param float timeSlot: The time slot as milliseconds since Jan 1, 1970 UTC. :param onEncryptedKeys: If this creates a content key, then this calls onEncryptedKeys(keys) where keys is a list of encrypted content key Data packets. If onEncryptedKeys is None, this does not use it. NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onEncryptedKeys: function object :param onError: (optional) This calls errorCode, message) for an error, where errorCode is from EncryptError.ErrorCode and message is a str. If omitted, use a default callback which does nothing. NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onError: function object :return: The content key name. :rtype: Name """ hourSlot = Producer._getRoundedTimeSlot(timeSlot) # Create the content key name. contentKeyName = Name(self._namespace) contentKeyName.append(Encryptor.NAME_COMPONENT_C_KEY) contentKeyName.append(Schedule.toIsoString(hourSlot)) # Check if we have created the content key before. if self._database.hasContentKey(timeSlot): # We have created the content key. Return its name directly. return contentKeyName # We haven't created the content key. Create one and add it into the # database. aesParams = AesKeyParams(128) contentKeyBits = AesAlgorithm.generateKey(aesParams).getKeyBits() self._database.addContentKey(timeSlot, contentKeyBits) # Now we need to retrieve the E-KEYs for content key encryption. timeCount = round(timeSlot) self._keyRequests[timeCount] = Producer._KeyRequest(len( self._eKeyInfo)) keyRequest = self._keyRequests[timeCount] # Send interests for all nodes in the tree. for keyName in self._eKeyInfo: # For each current E-KEY. keyInfo = self._eKeyInfo[keyName] if (timeSlot < keyInfo.beginTimeSlot or timeSlot >= keyInfo.endTimeSlot): # The current E-KEY cannot cover the content key, so retrieve one. keyRequest.repeatAttempts[keyName] = 0 self._sendKeyInterest(Interest(keyName), timeSlot, onEncryptedKeys, onError) else: # The current E-KEY can cover the content key. # Encrypt the content key directly. eKeyName = Name(keyName) eKeyName.append(Schedule.toIsoString(keyInfo.beginTimeSlot)) eKeyName.append(Schedule.toIsoString(keyInfo.endTimeSlot)) self._encryptContentKey(keyInfo.keyBits, eKeyName, timeSlot, onEncryptedKeys, onError) return contentKeyName
def createContentKey(self, timeSlot, onEncryptedKeys, onError=defaultOnError): """ Create the content key corresponding to the timeSlot. This first checks if the content key exists. For an existing content key, this returns the content key name directly. If the key does not exist, this creates one and encrypts it using the corresponding E-KEYs. The encrypted content keys are passed to the onEncryptedKeys callback. :param float timeSlot: The time slot as milliseconds since Jan 1, 1970 UTC. :param onEncryptedKeys: If this creates a content key, then this calls onEncryptedKeys(keys) where keys is a list of encrypted content key Data packets. If onEncryptedKeys is None, this does not use it. NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onEncryptedKeys: function object :param onError: (optional) This calls errorCode, message) for an error, where errorCode is from EncryptError.ErrorCode and message is a str. If omitted, use a default callback which does nothing. NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onError: function object :return: The content key name. :rtype: Name """ hourSlot = Producer._getRoundedTimeSlot(timeSlot) # Create the content key name. contentKeyName = Name(self._namespace) contentKeyName.append(Encryptor.NAME_COMPONENT_C_KEY) contentKeyName.append(Schedule.toIsoString(hourSlot)) # Check if we have created the content key before. if self._database.hasContentKey(timeSlot): # We have created the content key. Return its name directly. return contentKeyName # We haven't created the content key. Create one and add it into the # database. aesParams = AesKeyParams(128) contentKeyBits = AesAlgorithm.generateKey(aesParams).getKeyBits() self._database.addContentKey(timeSlot, contentKeyBits) # Now we need to retrieve the E-KEYs for content key encryption. timeCount = round(timeSlot) self._keyRequests[timeCount] = Producer._KeyRequest(len(self._eKeyInfo)) keyRequest = self._keyRequests[timeCount] # Check if the current E-KEYs can cover the content key. timeRange = Exclude() Producer.excludeAfter(timeRange, Name.Component(Schedule.toIsoString(timeSlot))) # Send interests for all nodes in the tree. for keyName in self._eKeyInfo: # For each current E-KEY. keyInfo = self._eKeyInfo[keyName] if timeSlot < keyInfo.beginTimeSlot or timeSlot >= keyInfo.endTimeSlot: # The current E-KEY cannot cover the content key, so retrieve one. keyRequest.repeatAttempts[keyName] = 0 self._sendKeyInterest( Interest(keyName).setExclude(timeRange).setChildSelector(1), timeSlot, onEncryptedKeys, onError ) else: # The current E-KEY can cover the content key. # Encrypt the content key directly. eKeyName = Name(keyName) eKeyName.append(Schedule.toIsoString(keyInfo.beginTimeSlot)) eKeyName.append(Schedule.toIsoString(keyInfo.endTimeSlot)) self._encryptContentKey(keyInfo.keyBits, eKeyName, timeSlot, onEncryptedKeys, onError) return contentKeyName