// here we are trying to find encryption provider with given Id and Version (they are stored within EncryptionProviderKey) private IEncryptionProvider ResolveDecryptionProvider(EncryptionProviderKey key) { IEncryptionProvider provider; lock (_encryptionProviders) { // If there is no provider in cache if (!_encryptionProviders.TryGetValue(key, out provider)) { // list all implementations of IEncryptionProvider within container. var availableProviders = _container.GetAllInstances <IEncryptionProvider>(); foreach (var encryptionProvider in availableProviders) { // add them into cache RegisterEncryptionProvider(encryptionProvider); // and check if this provider is what we are looking for if (encryptionProvider.Id == key.Id && encryptionProvider.Version == key.Version) { provider = encryptionProvider; } } } } if (provider == null) { throw new Exception($"Unable to resolve EncryptionProvider with Id = {key.Id} and Version = {key.Version}"); } return(provider); }
private Stream DecryptData(string peerId, byte[] encryptedData, out int typeCode) { if (encryptedData == null) { typeCode = -1; return(null); } if (encryptedData.Length < 12) { throw new ArgumentException($"Encrypted data has invalid size {encryptedData.Length}. Can't be less than 12 bytes."); } // read encrypted data header (12 bytes) // Using marshaling instead of BitConverter will result into more performant (and somewhat more clear) code, but this requieres Full Trust for execution. // Lets use BitConverter for now var providerKey = new EncryptionProviderKey( // First 4 bytes are 32-bit integer id of the encryption provider used to encrypt data BitConverter.ToInt32(encryptedData, 0), // Second 4 bytes are 32-bit integer version of the encryption provider used to encrypt data BitConverter.ToInt32(encryptedData, 4)); // Third 4 bytes are 32-integer represending type code of the data being encrypted typeCode = BitConverter.ToInt32(encryptedData, 8); var decryptedDataStream = new MemoryStream(); // there is no encrypted data. if (encryptedData.Length == 12) { return(decryptedDataStream); } var provider = ResolveDecryptionProvider(providerKey); using (var encryptedDataStream = new MemoryStream(encryptedData, 12, encryptedData.Length - 12, false)) { provider.DecryptData(encryptedDataStream, decryptedDataStream, peerId); decryptedDataStream.Seek(0, SeekOrigin.Begin); return(decryptedDataStream); } }
private bool Equals(EncryptionProviderKey other) { return(Id == other.Id && Version == other.Version); }