예제 #1
0
        public MeshNode(Stream s, string password, string profileFolder, TorController torController)
        {
            _password      = password;
            _profileFolder = profileFolder;

            switch (s.ReadByte()) //version
            {
            case 1:
                //read headers and init decryptor
                Aes decryptionAlgo = Aes.Create();
                decryptionAlgo.Key     = MeshNetwork.GetKdfValue32(Encoding.UTF8.GetBytes(password), s.ReadBytes(32), 1, 1 * 1024 * 1024); //salt
                decryptionAlgo.IV      = s.ReadBytes(16);                                                                                  //IV
                decryptionAlgo.Padding = PaddingMode.ISO10126;
                decryptionAlgo.Mode    = CipherMode.CBC;

                byte[] hmac = s.ReadBytes(32);     //hmac
                long   cipherTextStartPosition = s.Position;

                //authenticate data in Encrypt-then-MAC (EtM) mode
                using (HMAC aeHmac = new HMACSHA256(decryptionAlgo.Key))
                {
                    byte[] computedHmac = aeHmac.ComputeHash(s);

                    if (!BinaryNumber.Equals(hmac, computedHmac))
                    {
                        throw new CryptographicException("Invalid password or data tampered.");
                    }
                }

                //decrypt data and init node
                s.Position = cipherTextStartPosition;
                CryptoStream cS = new CryptoStream(s, decryptionAlgo.CreateDecryptor(), CryptoStreamMode.Read);

                InitMeshNode(new BinaryReader(cS), torController);
                break;

            case -1:
                throw new EndOfStreamException();

            default:
                throw new InvalidDataException("MeshNode format version not supported.");
            }
        }
예제 #2
0
        public void SaveTo(Stream s)
        {
            //generate salt for KDF
            byte[] salt = new byte[32];
            _rng.GetBytes(salt);

            //create encryptor
            Aes encryptionAlgo = Aes.Create();

            encryptionAlgo.Key = MeshNetwork.GetKdfValue32(Encoding.UTF8.GetBytes(_password), salt, 1, 1 * 1024 * 1024);
            encryptionAlgo.GenerateIV();
            encryptionAlgo.Padding = PaddingMode.ISO10126;
            encryptionAlgo.Mode    = CipherMode.CBC;

            //write headers
            s.WriteByte((byte)1);       //version
            s.Write(salt);              //salt
            s.Write(encryptionAlgo.IV); //IV
            s.Write(new byte[32]);      //placeholder for HMAC

            long cipherTextStartPosition = s.Position;

            //write encrypted data
            {
                CryptoStream   cS = new CryptoStream(s, encryptionAlgo.CreateEncryptor(), CryptoStreamMode.Write);
                BufferedStream bS = new BufferedStream(cS);
                WriteTo(new BinaryWriter(bS));
                bS.Flush();
                cS.FlushFinalBlock();
            }

            //write hmac for authenticated encryption Encrypt-then-MAC (EtM) mode
            using (HMAC aeHmac = new HMACSHA256(encryptionAlgo.Key))
            {
                s.Position = cipherTextStartPosition;
                byte[] hmac = aeHmac.ComputeHash(s);

                //write hmac
                s.Position = cipherTextStartPosition - 32;
                s.Write(hmac);
            }
        }