示例#1
0
        /// <remarks>
        /// This method demonstrates using a PackageFactory to extract a key.
        /// StreamMac to verify with a keyed HMAC, that tests the encrypted file before it is conditionally decrypted. 
        /// If accepted the stream is then decrypted using the StreamCipher class.
        /// </remarks>
        private void Decrypt()
        {
            CipherDescription cipherDesc;
            KeyParams keyParam;
            byte[] extKey;

            try
            {
                using (FileStream inStream = new FileStream(_inputPath, FileMode.Open, FileAccess.Read))
                {
                    byte[] keyId = MessageHeader.GetKeyId(inStream);

                    // get the keyheader and key material from the key file
                    using (PackageFactory keyFactory = new PackageFactory(_keyFilePath, _container.Authority))
                    {
                        if (keyFactory.AccessScope == KeyScope.NoAccess)
                        {
                            MessageBox.Show(keyFactory.LastError);
                            return;
                        }
                        keyFactory.Extract(keyId, out cipherDesc, out keyParam, out extKey);
                    }

                    // offset start position is base header + Mac size
                    int hdrOffset = MessageHeader.GetHeaderSize + cipherDesc.MacSize;

                    // decrypt file extension and create a unique path
                    _outputPath = Utilities.GetUniquePath(_outputPath + MessageHeader.GetExtension(inStream, extKey));

                    // if a signing key, test the mac: (MacSize = 0; not signed)
                    if (cipherDesc.MacSize > 0)
                    {
                        // get the hmac for the encrypted file; this could be made selectable
                        // via the KeyHeaderStruct MacDigest and MacSize members.
                        using (StreamMac mstrm = new StreamMac(new SHA512HMAC(keyParam.IKM)))
                        {
                            // get the message header mac
                            byte[] chksum = MessageHeader.GetMessageMac(inStream, cipherDesc.MacSize);

                            // initialize mac stream
                            inStream.Seek(hdrOffset, SeekOrigin.Begin);
                            mstrm.Initialize(inStream);

                            // get the mac; offset by header length + Mac and specify adjusted length
                            byte[] hash = mstrm.ComputeMac(inStream.Length - hdrOffset, hdrOffset);

                            // compare, notify and abort on failure
                            if (!Compare.AreEqual(chksum, hash))
                            {
                                MessageBox.Show("Message hash does not match! The file has been tampered with.");
                                return;
                            }
                        }
                    }

                    // with this constructor, the StreamCipher class creates the cryptographic
                    // engine using the description contained in the CipherDescription structure.
                    // The (cipher and) engine are automatically destroyed in the cipherstream dispose
                    using (StreamCipher cstrm = new StreamCipher(false, cipherDesc, keyParam))
                    {
                        using (FileStream outStream = new FileStream(_outputPath, FileMode.Create, FileAccess.Write))
                        {
                            // start at an input offset equal to the message header size
                            inStream.Seek(hdrOffset, SeekOrigin.Begin);
                            // use a percentage counter
                            cstrm.ProgressPercent += new StreamCipher.ProgressDelegate(OnProgressPercent);
                            // initialize internals
                            cstrm.Initialize(inStream, outStream);
                            // write the decrypted output to file
                            cstrm.Write();
                        }
                    }
                }
                // destroy the key
                keyParam.Dispose();
            }
            catch (Exception ex)
            {
                if (File.Exists(_outputPath))
                    File.Delete(_outputPath);

                string message = ex.Message == null ? "" : ex.Message;
                MessageBox.Show("An error occured, the file could not be encrypted! " + message);
            }
            finally
            {
                Invoke(new MethodInvoker(() => { Reset(); }));
            }
        }
示例#2
0
        /// <summary>
        /// Demonstrates saving a key file using the PackageFactory class
        /// </summary>
        private void SaveKey()
        {
            try
            {
                // add the time/date expiration stamp if key policy is volatile
                if (HasPolicy(KeyPolicies.Volatile))
                {
                    if (dtVolatileTime.Value.Ticks > DateTime.Now.Ticks)
                        _container.Authority.OptionFlag = dtVolatileTime.Value.Ticks;
                    else
                        throw new Exception("Invalid Expiry time. If a key is marked as Volatile, the expired time must be greater than the current time.");
                }

                // get the key tag description
                if (!string.IsNullOrEmpty(txtKeyDescription.Text))
                {
                    byte[] data = new byte[32];
                    byte[] tag = Encoding.ASCII.GetBytes(txtKeyDescription.Text);
                    Array.Copy(tag, data, tag.Length < 32 ? tag.Length : 32);
                    _container.Authority.PackageTag = data;
                }

                // get the number of subkeys to create in this package
                int keyCount = 1;
                if (!string.IsNullOrEmpty(txtSubKeyCount.Text) && txtSubKeyCount.Text != "0")
                    int.TryParse(txtSubKeyCount.Text, out keyCount);

                // create a PackageKey; a key package can contain 1 or many thousands of 'subkeys'. Each subkey set
                // contains one group of unique random keying material; key, iv, and optional hmac key.
                // Each key set is used only once for encryption, guaranteeing that a unique set of values is used for every encryption cycle.
                PackageKey package = new PackageKey(
                    _container.Authority,           // the KeyAuthority structure
                    _container.Description,         // the CipherDescription structure
                    keyCount,                       // the number of subkeys to add to this key package
                    IdGenerator());                 // the file extension encryption key

                // create and write the key
                using (PackageFactory factory = new PackageFactory(_keyFilePath, _container.Authority))
                    factory.Create(package);

                // store path
                _lastKeyPath = Path.GetDirectoryName(_keyFilePath);

                Reset();
                lblStatus.Text = "The Key has been saved!";
            }
            catch (Exception ex)
            {
                if (File.Exists(_keyFilePath))
                    File.Delete(_keyFilePath);

                string message = ex.Message == null ? "" : ex.Message;
                MessageBox.Show("An error occured, the key could not be created! " + message);
            }
        }
示例#3
0
        private void OnSelectKeyClick(object sender, EventArgs e)
        {
            string keyFile = GetFileOpenPath(KEY_DESC, KEY_FILT, _lastKeyPath);
            if (string.IsNullOrEmpty(keyFile))
                return;

            // get the key policy flag
            long policies = 0;
            using (FileStream keyStream = new FileStream(keyFile, FileMode.Open, FileAccess.Read))
                policies = PackageKey.GetKeyPolicy(keyStream);

            // test if key requires authentication
            if ((policies & (long)KeyPolicies.PackageAuth) == (long)KeyPolicies.PackageAuth)
            {
                // ask for passphrase
                if (ShowAuthDialog())
                {
                    using (PackageFactory keyFactory = new PackageFactory(keyFile, _container.Authority))
                    {
                        if (keyFactory.AccessScope == KeyScope.NoAccess)
                        {
                            Array.Clear(_container.Authority.PackageId, 0, _container.Authority.PackageId.Length);
                            MessageBox.Show("Passphrase does not match! This key requires authentication.");
                            txtKeyFile.Text = KEY_DEFN;
                            btnEncrypt.Enabled = false;
                            return;
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Access denied! This key requires authentication.");
                    txtKeyFile.Text = KEY_DEFN;
                    btnEncrypt.Enabled = false;
                    return;
                }
            }

            if (!_isEncryption)
            {
                if (IsMatchingKey(_inputPath, keyFile))
                {
                    _keyFilePath = keyFile;
                    txtKeyFile.Text = keyFile;
                    btnEncrypt.Enabled = true;
                    btnInfo.Enabled = true;
                }
                else
                {
                    _keyFilePath = string.Empty;
                    txtKeyFile.Text = KEY_DEFN;
                    btnEncrypt.Enabled = false;
                    MessageBox.Show("Key does not match the message! Choose a different key..");
                }
            }
            else
            {
                _keyFilePath = keyFile;
                txtKeyFile.Text = _keyFilePath;
                btnEncrypt.Enabled = true;
                btnInfo.Enabled = true;
            }

            if (!string.IsNullOrEmpty(_keyFilePath))
                _lastKeyPath = Path.GetDirectoryName(_keyFilePath);
        }
示例#4
0
 private void OnInfoButtonClick(object sender, EventArgs e)
 {
     using (PackageFactory keyFactory = new PackageFactory(_keyFilePath, _container.Authority))
     {
         using (FormInfo frmInfo = new FormInfo())
         {
             frmInfo.SetInfo(keyFactory.KeyInfo());
             frmInfo.ShowDialog(this);
         }
     }
 }
示例#5
0
        /// <summary>
        /// Compares keys between a message file and a key file
        /// </summary>
        private bool IsMatchingKey(string MessagePath, string KeyPath)
        {
            bool isEqual = false;

            if (File.Exists(MessagePath) && File.Exists(KeyPath))
            {
                using (FileStream msgFile = new FileStream(MessagePath, FileMode.Open, FileAccess.Read))
                {
                    byte[] messageId = MessageHeader.GetKeyId(msgFile);

                    using (PackageFactory factory = new PackageFactory(KeyPath, _container.Authority))
                        isEqual = factory.ContainsSubKey(messageId) > -1;
                }
            }

            return isEqual;
        }
示例#6
0
        /// <remarks>
        /// This method demonstrates using a PackageFactory and StreamCipher class to
        /// both encrypt a file, and optionally sign the message with an SHA512 HMAC.
        /// See the StreamCipher and StreamMac documentation for more examples.
        /// </remarks>
        private void Encrypt()
        {
            CipherDescription keyHeader;
            KeyParams keyParam;

            try
            {
                byte[] keyId = null;
                byte[] extKey = null;

                // get the keyheader and key material from the key file
                using (PackageFactory keyFactory = new PackageFactory(_keyFilePath, _container.Authority))
                {
                    // get the key info
                    PackageInfo pki = keyFactory.KeyInfo();

                    if (!keyFactory.AccessScope.Equals(KeyScope.Creator))
                    {
                        MessageBox.Show(keyFactory.LastError);
                        return;
                    }
                    keyId = (byte[])keyFactory.NextKey(out keyHeader, out keyParam, out extKey).Clone();
                }
                // offset start position is base header + Mac size
                int hdrOffset = MessageHeader.GetHeaderSize + keyHeader.MacSize;

                // with this constructor, the StreamCipher class creates the cryptographic
                // engine using the description in the CipherDescription.
                // The (cipher and) engine are destroyed in the cipherstream dispose
                using (StreamCipher cstrm = new StreamCipher(true, keyHeader, keyParam))
                {
                    using (FileStream inStream = new FileStream(_inputPath, FileMode.Open, FileAccess.Read))
                    {
                        using (FileStream outStream = new FileStream(_outputPath, FileMode.Create, FileAccess.ReadWrite))
                        {
                            // start at an output offset equal to the message header + MAC length
                            outStream.Seek(hdrOffset, SeekOrigin.Begin);
                            // use a percentage counter
                            cstrm.ProgressPercent += new StreamCipher.ProgressDelegate(OnProgressPercent);
                            // initialize internals
                            cstrm.Initialize(inStream, outStream);
                            // write the encrypted output to file
                            cstrm.Write();

                            // write the key id to the header
                            MessageHeader.SetKeyId(outStream, keyId);
                            // write the encrypted file extension
                            MessageHeader.SetExtension(outStream, MessageHeader.GetEncryptedExtension(Path.GetExtension(_inputPath), extKey));

                            // if this is a signing key, calculate the mac
                            if (keyHeader.MacSize > 0)
                            {
                                // Get the mac for the encrypted file; Mac engine is SHA512 by default,
                                // configurable via the CipherDescription MacSize and MacEngine members.
                                // This is where you would select and initialize the correct Digest via the
                                // CipherDescription members, and initialize the corresponding digest.
                                // For expedience, this example is fixed on the default SHA512.
                                // An optional progress event is available in the StreamMac class.
                                using (StreamMac mstrm = new StreamMac(new SHA512HMAC(keyParam.IKM)))
                                {
                                    // seek to end of header
                                    outStream.Seek(hdrOffset, SeekOrigin.Begin);
                                    // initialize mac stream
                                    mstrm.Initialize(outStream);
                                    // get the hash; specify offset and adjusted size
                                    byte[] hash = mstrm.ComputeMac(outStream.Length - hdrOffset, hdrOffset);
                                    // write the keyed hash value to the message header
                                    MessageHeader.SetMessageMac(outStream, hash);
                                }
                            }
                        }
                    }
                }
                // destroy the key
                keyParam.Dispose();
            }
            catch (Exception ex)
            {
                if (File.Exists(_outputPath))
                    File.Delete(_outputPath);

                string message = ex.Message == null ? "" : ex.Message;
                MessageBox.Show("An error occured, the file could not be encrypted! " + message);
            }
            finally
            {
                Invoke(new MethodInvoker(() => { Reset(); }));
            }
        }
示例#7
0
        /// <summary>
        /// Creates a temporary PackageKey on disk, extracts and compares the copy
        /// <para>Throws an Exception on failure</</para>
        /// </summary>
        public static void PackageFactoryTest()
        {
            string path = GetTempPath();
            KeyGenerator kgen = new KeyGenerator();
            // populate a KeyAuthority structure
            KeyAuthority authority = new KeyAuthority(kgen.GetBytes(16), kgen.GetBytes(16), kgen.GetBytes(16), kgen.GetBytes(32), 0);

            // cipher paramaters
            CipherDescription desc = new CipherDescription(
                SymmetricEngines.RDX, 32,
                IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.X923,
                BlockSizes.B128,
                RoundCounts.R14,
                Digests.Keccak512,
                64,
                Digests.Keccak512);

            // create the package key
            PackageKey pkey = new PackageKey(authority, desc, 10);

            // write a key file
            using (PackageFactory pf = new PackageFactory(path, authority))
                pf.Create(pkey);

            for (int i = 0; i < pkey.SubKeyCount; i++)
            {
                CipherDescription desc2;
                KeyParams kp1;
                KeyParams kp2;
                byte[] ext;
                byte[] id = pkey.SubKeyID[i];

                // get at index
                using (FileStream stream = new FileStream(path, FileMode.Open))
                    kp2 = PackageKey.AtIndex(stream, i);

                // read the package from id
                using (PackageFactory pf = new PackageFactory(path, authority))
                    pf.Extract(id, out desc2, out kp1, out ext);

                // compare key material
                if (!Compare.AreEqual(kp1.Key, kp2.Key))
                    throw new Exception();
                if (!Compare.AreEqual(kp1.IV, kp2.IV))
                    throw new Exception();
                if (!Compare.AreEqual(pkey.ExtensionKey, ext))
                    throw new Exception();
                if (!desc.Equals(desc2))
                    throw new Exception();
            }
            if (File.Exists(path))
                File.Delete(path);
        }