/// <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()); } }