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 _encryptAsymmetric(payload, key, keyName, params): """ Encrypt the payload using the asymmetric key according to params, and return an EncryptedContent. :param Blob payload: The data to encrypt. The size should be within range of the key. :param Blob key: The key value. :param Name keyName: The key name for the EncryptedContent key locator. :param EncryptParams params: The parameters for encryption. :return: A new EncryptedContent. :rtype: EncryptedContent """ algorithmType = params.getAlgorithmType() keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.setKeyName(keyName) if (algorithmType == EncryptAlgorithmType.RsaPkcs or algorithmType == EncryptAlgorithmType.RsaOaep): encryptedPayload = RsaAlgorithm.encrypt(key, payload, params) result = EncryptedContent() result.setAlgorithmType(algorithmType) result.setKeyLocator(keyLocator) result.setPayload(encryptedPayload) return result else: raise RuntimeError("Unsupported encryption method")
def _encryptSymmetric(payload, key, keyName, params): """ Encrypt the payload using the symmetric key according to params, and return an EncryptedContent. :param Blob payload: The data to encrypt. :param Blob key: The key value. :param Name keyName: The key name for the EncryptedContent key locator. :param EncryptParams params: The parameters for encryption. :return: A new EncryptedContent. :rtype: EncryptedContent """ algorithmType = params.getAlgorithmType() initialVector = params.getInitialVector() keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.setKeyName(keyName) if (algorithmType == EncryptAlgorithmType.AesCbc or algorithmType == EncryptAlgorithmType.AesEcb): if (algorithmType == EncryptAlgorithmType.AesCbc): if initialVector.size() != AesAlgorithm.BLOCK_SIZE: raise RuntimeError("incorrect initial vector size") encryptedPayload = AesAlgorithm.encrypt(key, payload, params) result = EncryptedContent() result.setAlgorithmType(algorithmType) result.setKeyLocator(keyLocator) result.setPayload(encryptedPayload) result.setInitialVector(initialVector) return result else: raise RuntimeError("Unsupported encryption method")
def _encryptSymmetric(payload, key, keyName, params): """ Encrypt the payload using the symmetric key according to params, and return an EncryptedContent. :param Blob payload: The data to encrypt. :param Blob key: The key value. :param Name keyName: The key name for the EncryptedContent key locator. :param EncryptParams params: The parameters for encryption. :return: A new EncryptedContent. :rtype: EncryptedContent """ algorithmType = params.getAlgorithmType() initialVector = params.getInitialVector() keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.setKeyName(keyName) if (algorithmType == EncryptAlgorithmType.AesCbc or algorithmType == EncryptAlgorithmType.AesEcb): if (algorithmType == EncryptAlgorithmType.AesCbc): if initialVector.size() != AesAlgorithm.BLOCK_SIZE: raise RuntimeError("incorrect initial vector size") encryptedPayload = AesAlgorithm.encrypt(key, payload, params) result = EncryptedContent() result.setAlgorithmType(algorithmType) result.setKeyLocator(keyLocator) result.setPayload(encryptedPayload) result.setInitialVector(initialVector) return result else: raise RuntimeError("Unsupported encryption method")
def addMember(self, memberCertificate): """ Authorize a member identified by memberCertificate to decrypt data under the policy. :param CertificateV2 memberCertificate: The certificate that identifies the member to authorize. :return: The published KDK Data packet. :rtype: Data """ kdkName = Name(self._nacKey.getIdentityName()) kdkName.append(EncryptorV2.NAME_COMPONENT_KDK).append( # key-id self._nacKey.getName().get(-1)).append( EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY).append( memberCertificate.getKeyName()) secretLength = 32 secret = bytearray(secretLength) for i in range(secretLength): secret[i] = _systemRandom.randint(0, 0xff) # To be compatible with OpenSSL which uses a null-terminated string, # replace each 0 with 1. And to be compatible with the Java security # library which interprets the secret as a char array converted to UTF8, # limit each byte to the ASCII range 1 to 127. for i in range(secretLength): if secret[i] == 0: secret[i] = 1 secret[i] &= 0x7f kdkSafeBag = self._keyChain.exportSafeBag( self._nacKey.getDefaultCertificate(), Blob(secret, False).toBytes()) memberKey = PublicKey(memberCertificate.getPublicKey()) encryptedContent = EncryptedContent() encryptedContent.setPayload(kdkSafeBag.wireEncode()) encryptedContent.setPayloadKey( memberKey.encrypt( Blob(secret, False).toBytes(), EncryptAlgorithmType.RsaOaep)) kdkData = Data(kdkName) kdkData.setContent(encryptedContent.wireEncodeV2()) # FreshnessPeriod can serve as a soft access control for revoking access. kdkData.getMetaInfo().setFreshnessPeriod( AccessManagerV2.DEFAULT_KDK_FRESHNESS_PERIOD_MS) self._keyChain.sign(kdkData, SigningInfo(self._identity)) self._storage.insert(kdkData) return kdkData
def _makeAndPublishCkData(self, onError): """ Make a CK Data packet for _ckName encrypted by the KEK in _kekData and insert it in the _storage. :param onError: On failure, this calls onError(errorCode, message) where errorCode is from EncryptError.ErrorCode, and message is an error string. :type onError: function object :return: True on success, else False. :rtype: bool """ try: kek = PublicKey(self._kekData.getContent()) content = EncryptedContent() content.setPayload( kek.encrypt(Blob(self._ckBits, False), EncryptAlgorithmType.RsaOaep)) ckData = Data( Name(self._ckName).append( EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY).append( self._kekData.getName())) ckData.setContent(content.wireEncodeV2()) # FreshnessPeriod can serve as a soft access control for revoking access. ckData.getMetaInfo().setFreshnessPeriod( EncryptorV2.DEFAULT_CK_FRESHNESS_PERIOD_MS) self._keyChain.sign(ckData, self._ckDataSigningInfo) self._storage.insert(ckData) logging.getLogger(__name__).info("Publishing CK data: " + ckData.getName().toUri()) return True except Exception as ex: onError( EncryptError.ErrorCode.EncryptionFailure, "Failed to encrypt generated CK with KEK " + self._kekData.getName().toUri()) return False
def _makeAndPublishCkData(self, onError): """ Make a CK Data packet for _ckName encrypted by the KEK in _kekData and insert it in the _storage. :param onError: On failure, this calls onError(errorCode, message) where errorCode is from EncryptError.ErrorCode, and message is an error string. :type onError: function object :return: True on success, else False. :rtype: bool """ try: kek = PublicKey(self._kekData.getContent()) content = EncryptedContent() content.setPayload(kek.encrypt (Blob(self._ckBits, False), EncryptAlgorithmType.RsaOaep)) ckData = Data( Name(self._ckName).append(EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY) .append(self._kekData.getName())) ckData.setContent(content.wireEncodeV2()) # FreshnessPeriod can serve as a soft access control for revoking access. ckData.getMetaInfo().setFreshnessPeriod( EncryptorV2.DEFAULT_CK_FRESHNESS_PERIOD_MS) self._keyChain.sign(ckData, self._ckDataSigningInfo) self._storage.insert(ckData) logging.getLogger(__name__).info("Publishing CK data: " + ckData.getName().toUri()) return True except Exception as ex: onError(EncryptError.ErrorCode.EncryptionFailure, "Failed to encrypt generated CK with KEK " + self._kekData.getName().toUri()) return False