/// <summary>
 /// Decrypt a message using the private key.
 /// </summary>
 /// <param name="cipher">The encrypted bytes of an array of bytes.</param>
 /// <returns></returns>
 public byte[] Decrypt(byte[] cipher)
 {
     using (var ms = new MemoryStream(cipher))
         using (var br = new BinaryReader(ms))
         {
             var encryptedKeyLength = br.ReadInt32();
             var encryptedKey       = br.ReadBytes(encryptedKeyLength);
             var symmetricKey       = DecryptAsymmetric(encryptedKey);
             var encryptedMessage   = ms.ReadAllBytes();
             return(Symmetric.Decrypt(encryptedMessage, symmetricKey));
         }
 }
        /// <summary>
        /// Encrypt a message using the public key.
        /// NOTE: The decrypting party must use this library's protocol to decrypt the message.
        /// The protocol is:
        /// (1) RSA-encrypt a random key of 32-bytes (256 bits).
        /// (2) Write the length of this key as Int32.
        /// (3) Write the encrypted key.
        /// (4) Write the symmetric-encrypted bytes of the message.
        /// To summarize this protocol, the cipher returned is a byte array containing the asymmetric-encrypted key plus the symmetric-encrypted message.
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public byte[] Encrypt(byte[] message)
        {
            // _pri.Encrypt() (backed by RSA 2048) can only encrypt a message that is 245 bytes or less; an inherent constraint of asymmetric cryptography.
            // Maybe longer bit spaces (e.g. 4096) can encrypt longer messages, but they all will be limited to under 1KB.
            // Your document will be longer. To get around this limitation, you asymmetric encrypt a short one-time password (random bytes) and use that to
            // symmetrically encrypt your message, since symmetric encryption has no message length limit.

            // So let's create a one-time key:
            var symmetricKey = Bytes.RandomBytesSecure(32); // 256-bit one-time key.
            var encryptedKey = EncryptAsymmetric(symmetricKey);

            using (var ms = new MemoryStream())
                using (var bw = new BinaryWriter(ms))
                {
                    bw.Write(encryptedKey.Length);
                    bw.Write(encryptedKey);
                    bw.Write(Symmetric.Encrypt(message, symmetricKey));
                    return(ms.ToArray());
                }
        }