internal static byte[] DecryptDataAsBytes(byte[] encryptedData, string privateKeyPem) { using (var encryptedDataStream = new MemoryStream(encryptedData)) using (var encryptedDataWithoutKeyPair = new MemoryStream()) { var encryptedKeyLengthBytes = new byte[4]; var bytesRead = encryptedDataStream.Read(encryptedKeyLengthBytes, 0, 4); if (bytesRead == -1) { throw new Exception("Unexpected end of encrypted data (expected encrypted key size)"); } var encryptedKeyLength = BitConverter.ToInt32(encryptedKeyLengthBytes, 0); var encryptedKey = new byte[encryptedKeyLength]; bytesRead = encryptedDataStream.Read(encryptedKey, 0, encryptedKeyLength); if (bytesRead != encryptedKeyLength) { throw new Exception("Unexpected end of encrypted data (expected encrypted key)"); } encryptedDataStream.CopyTo(encryptedDataWithoutKeyPair); var encryptionKey = AsymmetricCryptoUtil.DecryptDataWithPrivateKey(encryptedKey, privateKeyPem); return(EncryptedData.DecryptDataAsBytes(encryptionKey, encryptedDataWithoutKeyPair.ToArray())); } }
public static byte[] DecryptDataAsBytes(string serializedEncryptedData, string password) { var encryptedData = Convert.FromBase64String(serializedEncryptedData); using (var encryptedDataStream = new MemoryStream(encryptedData)) { var hmacNumBytes = new byte[4]; var bytesRead = encryptedDataStream.Read(hmacNumBytes, 0, 4); if (bytesRead != 4) { throw new Exception("Unexpected end of encrypted data (expected HMAC length)"); } var hmacLength = BitConverter.ToInt32(hmacNumBytes, 0); var givenMac = new byte[hmacLength]; bytesRead = encryptedDataStream.Read(givenMac, 0, hmacLength); if (bytesRead != hmacLength) { throw new Exception("Unexpected end of encrypted data (expected HMAC)"); } // Can't think of a more elegant way to read the remaining bytes of the stream. byte[] ciphertext; using (var encryptedDataWithoutPassword = new MemoryStream()) { encryptedDataStream.CopyTo(encryptedDataWithoutPassword); ciphertext = encryptedDataWithoutPassword.ToArray(); } var encryptionKey = PasswordHash.CreateHash(password, 1, ""); var authKey = Convert.FromBase64String(PasswordHash.CreateHash(password, 2, "")); var hmac = new HMac(new Sha256Digest()); var calculatedMac = new byte[hmac.GetMacSize()]; hmac.Init(new KeyParameter(authKey)); hmac.BlockUpdate(ciphertext, 0, ciphertext.Length); hmac.DoFinal(calculatedMac, 0); if (!Arrays.ConstantTimeAreEqual(givenMac, calculatedMac)) { throw new Exception("Encrypted data macs do not match"); } return(EncryptedData.DecryptDataAsBytes(Convert.FromBase64String(encryptionKey), ciphertext)); } }