/// <summary> /// Peel the onion until we can return the original plain data. Remember that the calling environment must contain all /// necessary private keys. /// </summary> public byte[] PeelAll() { if (AsymmetricEncryptedKey == null) { throw new Exception( "AsymmetricEncryptedKey not found. Are you sure this onion doesn't have more layers?"); } byte[] plainData; var onion = this; while (!onion.IsRoot) { onion = onion.PeelOne(); } using (var aes = new AESCryptoAgent()) using (var rsa = new RSACryptoAgent(onion.AsymmetricThumbprint)) { var decryptedSymmetricKey = rsa.Decrypt(onion.AsymmetricEncryptedKey); plainData = aes.Decrypt(onion.SymmetricEncryptedData, decryptedSymmetricKey, onion.SymmetricAlgorithmIV); } return(plainData); }
/// <summary> /// Return an onion with the top layer removed /// </summary> public PublicKeyEncryptionOnion PeelOne() { if (IsRoot) { throw new Exception( "This object is the root of the onion so there are no more layers to peel. Call 'PeelAll()' instead."); } if (AsymmetricEncryptedKey == null) { throw new Exception( "AsymmetricEncryptedKey not found. Are you sure this onion doesn't have more layers?"); } var rv = InnerOnion.Clone(); // here we want to generate a new object to return since we don't want to decrease the security of the current object using (var aes = new AESCryptoAgent()) using (var rsa = new RSACryptoAgent(AsymmetricThumbprint)) { // decrypt the previously encrypted key var decryptedSymmetricKey = rsa.Decrypt(AsymmetricEncryptedKey); rv.AsymmetricEncryptedKey = aes.Decrypt(SymmetricEncryptedData, decryptedSymmetricKey, SymmetricAlgorithmIV); } return(rv); }