Beispiel #1
0
        //Load an encryption key from a file
        public void LoadKeyFromFile(string path)
        {
            if (_encryptionKey != null)
            {
                throw new KeyAlreadyLoadedException();
            }

            //We don't know how .NET buffers things in memory, so we write it ourselves for maximum security
            //avoid excess buffering where possible, even if slow
            using (var file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                if (file.Length != KEYLENGTH * KEYCOUNT)
                {
                    throw new InvalidKeyFileException();
                }

                _encryptionKey = new SecureBuffer(KEYLENGTH);
                _hmacKey       = new SecureBuffer(KEYLENGTH);

                foreach (var buffer in new [] { _encryptionKey.Buffer, _hmacKey.Buffer })
                {
                    int bytesRead = file.Read(buffer, 0, KEYLENGTH);
                    if (bytesRead != KEYLENGTH)
                    {
                        throw new IOException("Unable to read from key file!");
                    }
                }
            }
        }
Beispiel #2
0
        private EncryptedBlob Encrypt(SecureBuffer input)
        {
            EncryptedBlob blob;

#if NETSTANDARD1_3
            var aes = Aes.Create();
#elif NET20 || NET30
            var aes = Rijndael.Create();
#else
            var aes = new AesCryptoServiceProvider();
#endif

            using (aes)
            {
                aes.Mode      = CipherMode.CBC;
                aes.Key       = _encryptionKey.Buffer;
                aes.BlockSize = 128;
                aes.GenerateIV();

                blob.IV = aes.IV;

                using (var encryptor = aes.CreateEncryptor())
                {
                    blob.Payload = encryptor.TransformFinalBlock(input.Buffer, 0, input.Buffer.Length);
                }
            }

            blob.Hmac = Authenticate(blob.IV, blob.Payload);

            return(blob);
        }
        /// <summary>
        /// Creates a new <see cref="SecureBuffer"/> to hold a copy of
        /// the data contained in <paramref name="insecure"/>. Does not
        /// offer any protection, but provides compatibility between
        /// <c>byte[]</c> and <c>SecureBuffer</c>.
        /// </summary>
        /// <param name="insecure"></param>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static SecureBuffer From(byte[] insecure, int offset = 0, int?length = null)
        {
            var buffer = new SecureBuffer(length ?? insecure.Length);

            Array.Copy(insecure, offset, buffer.Buffer, 0, length ?? insecure.Length);
            return(buffer);
        }
 public T Retrieve <T>(string name)
 {
     using (var decrypted = new SecureBuffer(Decrypt(_vault.Data[name])))
     {
         //the conversion from bytes to string involves some non-shredded memory
         return(JsonConvert.DeserializeObject <T>(Encoding.UTF8.GetString(decrypted.Buffer)));
     }
 }
        public void LoadKey(SecureBuffer key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            LoadKey(key.Buffer);
        }
        public void Set <T>(string name, T value)
        {
            //JsonConvert and the UTF8 conversion likely involve non-shredded memory
            var insecure = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value));

            using (var secured = new SecureBuffer(insecure))
            {
                _vault.Data[name] = Encrypt(secured);
            }
        }
        //Generate a new key for a new store
        public void GenerateKey()
        {
            if (_encryptionKey != null)
            {
                throw new KeyAlreadyLoadedException();
            }

            _encryptionKey = new SecureBuffer(KEYLENGTH);
            GenerateBytes(_encryptionKey.Buffer);
            _hmacKey = new SecureBuffer(KEYLENGTH);
            GenerateBytes(_hmacKey.Buffer);
        }
 public void Dispose()
 {
     if (_hmacKey != null)
     {
         _hmacKey.Dispose();
         _hmacKey = null;
     }
     if (_encryptionKey != null)
     {
         _encryptionKey.Dispose();
         _encryptionKey = null;
     }
 }
        //Derive an encryption key from a password
        public void LoadKeyFromPassword(string password)
        {
            if (_encryptionKey != null)
            {
                throw new KeyAlreadyLoadedException();
            }

            var insecure = DerivePassword(password, _vault.IV);

            using (var sb = new SecureBuffer(insecure))
            {
                SplitKey(insecure);
            }
        }
        public SecureBuffer ExportKey()
        {
            if (_encryptionKey?.Buffer == null || _hmacKey?.Buffer == null)
            {
                throw new NoKeyLoadedException();
            }

            var secure = new SecureBuffer(KEYLENGTH * 2);

            Array.Copy(_encryptionKey.Buffer, secure.Buffer, KEYLENGTH);
            Array.Copy(_hmacKey.Buffer, 0, secure.Buffer, KEYLENGTH, KEYLENGTH);

            return(secure);
        }
        private void SplitKey(byte[] insecure)
        {
            //While the consensus is that AES and HMAC are "sufficiently different" that reusing
            //the same key for Encrypt-then-MAC is probably safe, it's not something provable
            //and therefore (esp. since we can without too much additional burden) we should use two
            //separate keys.
            using (var temp = new SecureBuffer(insecure))
            {
                _encryptionKey = new SecureBuffer(KEYLENGTH);
                _hmacKey       = new SecureBuffer(KEYLENGTH);

                Array.Copy(temp.Buffer, 0, _encryptionKey.Buffer, 0, KEYLENGTH);
                Array.Copy(temp.Buffer, KEYLENGTH, _hmacKey.Buffer, 0, KEYLENGTH);
            }
        }