public Message(Stream input, RSAPrivateKey key, Converter <Guid, Salt> sessionSecret) { (_protected = new MemoryStream(0)).Dispose(); _hash = new HashStream(new SHA256Managed(), input); _payload = input; ReadHeader(_hash, out _version, out _state, out _transferId, out _salt); Salt secret; if (!UsesSessionKey) { // Begin private key decryption _payload = key.Decrypt(input); _hash.ChangeStream(_payload); // Decrypt the aes key used in this package byte[] keybits = IOStream.Read(_hash, 32); secret = Salt.FromBytes(keybits); } else { secret = sessionSecret(_transferId); Check.IsEqual(32, Check.NotNull(secret).Length); } AESCryptoKey sessionKey = new AESCryptoKey( // Prefix the key with the message's salt and compute a SHA256 hash to be used as the key Hash.SHA256(_salt.GetData(secret.ToArray()).ToStream()).ToArray(), // Compute an IV for this aes key and salt combination IV(secret, _salt) ); _payload = sessionKey.Decrypt(_payload); _hash.ChangeStream(_payload); }
//private bool _verified; /* this is a debugging aid used to ensure all messages are signed or verified */ public Message(TransferState state, Guid transferId, RSAPublicKey key, Converter <Guid, Salt> sessionSecret) { _version = VersionHeader; _state = state; _transferId = transferId; _salt = new Salt(Salt.Size.b256); _protected = new MemoryStream(); _payload = new NonClosingStream(_protected); _hash = new HashStream(new SHA256Managed()); WriteHeader(_hash); Salt secret; if (!UsesSessionKey) { // Outer encryption is straight PKI based on the remote public key _payload = key.Encrypt(_payload); _hash.ChangeStream(_payload); // Preceed the message with a new, AES key secret = new Salt(Salt.Size.b256); _hash.Write(secret.ToArray(), 0, 32); } else { secret = sessionSecret(_transferId); Check.IsEqual(32, Check.NotNull(secret).Length); } AESCryptoKey sessionKey = new AESCryptoKey( // Prefix the key with the message's salt and compute a SHA256 hash to be used as the key Hash.SHA256(_salt.GetData(secret.ToArray()).ToStream()).ToArray(), // Compute an IV for this aes key and salt combination IV(secret, _salt) ); _payload = sessionKey.Encrypt(_payload); _hash.ChangeStream(_payload); }