示例#1
0
        public static int CipherKeySize(SymAlgorithms saAlgo)
        {
            int iKeySize = 0;

            switch (saAlgo)
            {
            case SymAlgorithms.AES128:
                iKeySize = 128;
                break;

            case SymAlgorithms.AES192:
                iKeySize = 192;
                break;

            case SymAlgorithms.AES256:
                iKeySize = 256;
                break;

            case SymAlgorithms.CAST5:
                iKeySize = 128;
                break;

            case SymAlgorithms.Triple_DES:
                iKeySize = 192;
                break;
            }
            return(iKeySize);
        }
示例#2
0
        public static SymmetricAlgorithm CreateSymAlgorithm(SymAlgorithms saAlgo)
        {
            SymmetricAlgorithm saReturn;

            switch (saAlgo) {
                case SymAlgorithms.AES128:
                    saReturn = Rijndael.Create();
                    saReturn.BlockSize = 128;
                    saReturn.KeySize = 128;
                    break;
                case SymAlgorithms.AES192:
                    saReturn = Rijndael.Create();
                    saReturn.BlockSize = 128;
                    saReturn.KeySize = 192;
                    break;
                case SymAlgorithms.AES256:
                    saReturn = Rijndael.Create();
                    saReturn.BlockSize = 128;
                    saReturn.KeySize = 256;
                    break;
                case SymAlgorithms.CAST5:
                    saReturn = CAST5.Create();
                    break;
                case SymAlgorithms.Triple_DES:
                    saReturn = TripleDES.Create();
                    break;
                default:
                    throw new System.Security.Cryptography.CryptographicException("The algorithm is not supported!");
            }

            return saReturn;
        }
示例#3
0
        private byte[] EncryptMessage(Message mToBeEncrypted, ulong[] lTargetKeyIDs)
        {
            CompressedMessage cmMessage = new CompressedMessage();

            cmMessage.Compress(mToBeEncrypted);

            TransportablePublicKey[] tpkSelectedKeys = new TransportablePublicKey[lTargetKeyIDs.Length];
            for (int i = 0; i < lTargetKeyIDs.Length; i++)
            {
                tpkSelectedKeys[i] = pkrKeyRing.Find(lTargetKeyIDs[i], true);
            }

            SymAlgorithms saAlgo = GetSymAlgorithmPreferences(tpkSelectedKeys);

            SymmetricallyEncryptedDataPacket sedpEncrypted = new SymmetricallyEncryptedDataPacket();
            SymmetricAlgorithm saEncrypt = CipherHelper.CreateSymAlgorithm(saAlgo);

            saEncrypt.Mode = CipherMode.OpenPGP_CFB;
            saEncrypt.GenerateKey();
            byte[] bKey = saEncrypt.Key;

            ESKSequence esksKeys = new ESKSequence();

            esksKeys = CreateESKSequence(tpkSelectedKeys, AsymActions.Encrypt, saAlgo, bKey);

            ICryptoTransform ictEncryptor = saEncrypt.CreateEncryptor();

            byte[] bMessage = cmMessage.GetEncoded();
            byte[] bOutput  = new byte[bMessage.Length];
            ictEncryptor.TransformBlock(bMessage, 0, bMessage.Length, ref bOutput, 0);
            bKey.Initialize();

            int iOutLength = (saEncrypt.BlockSize >> 3) + 2 + bMessage.Length;

            sedpEncrypted.Body = new byte[iOutLength];
            Array.Copy(bOutput, 0, sedpEncrypted.Body, 0, iOutLength);

            byte[] bESK       = esksKeys.GetEncoded();
            byte[] bEncrypted = sedpEncrypted.Generate();

            byte[] bReturn = new byte[bESK.Length + bEncrypted.Length];
            bESK.CopyTo(bReturn, 0);
            bEncrypted.CopyTo(bReturn, bESK.Length);

            return(bReturn);
        }
示例#4
0
 public static int CipherBlockSize(SymAlgorithms saAlgo)
 {
     int iBlockSize = 0;
     switch (saAlgo) {
         case SymAlgorithms.AES128:
         case SymAlgorithms.AES192:
         case SymAlgorithms.AES256:
             iBlockSize = 16;
             break;
         case SymAlgorithms.CAST5:
             iBlockSize = 8;
             break;
         case SymAlgorithms.Triple_DES:
             iBlockSize = 8;
             break;
     }
     return iBlockSize;
 }
示例#5
0
        public static int CipherBlockSize(SymAlgorithms saAlgo)
        {
            int iBlockSize = 0;

            switch (saAlgo)
            {
            case SymAlgorithms.AES128:
            case SymAlgorithms.AES192:
            case SymAlgorithms.AES256:
                iBlockSize = 16;
                break;

            case SymAlgorithms.CAST5:
                iBlockSize = 8;
                break;

            case SymAlgorithms.Triple_DES:
                iBlockSize = 8;
                break;
            }
            return(iBlockSize);
        }
示例#6
0
 public static int CipherKeySize(SymAlgorithms saAlgo)
 {
     int iKeySize = 0;
     switch (saAlgo) {
         case SymAlgorithms.AES128:
             iKeySize = 128;
             break;
         case SymAlgorithms.AES192:
             iKeySize = 192;
             break;
         case SymAlgorithms.AES256:
             iKeySize = 256;
             break;
         case SymAlgorithms.CAST5:
             iKeySize = 128;
             break;
         case SymAlgorithms.Triple_DES:
             iKeySize = 192;
             break;
     }
     return iKeySize;
 }
示例#7
0
        public static SymmetricAlgorithm CreateSymAlgorithm(SymAlgorithms saAlgo)
        {
            SymmetricAlgorithm saReturn;

            switch (saAlgo)
            {
            case SymAlgorithms.AES128:
                saReturn           = Rijndael.Create();
                saReturn.BlockSize = 128;
                saReturn.KeySize   = 128;
                break;

            case SymAlgorithms.AES192:
                saReturn           = Rijndael.Create();
                saReturn.BlockSize = 128;
                saReturn.KeySize   = 192;
                break;

            case SymAlgorithms.AES256:
                saReturn           = Rijndael.Create();
                saReturn.BlockSize = 128;
                saReturn.KeySize   = 256;
                break;

            case SymAlgorithms.CAST5:
                saReturn = CAST5.Create();
                break;

            case SymAlgorithms.Triple_DES:
                saReturn = TripleDES.Create();
                break;

            default:
                throw new System.Security.Cryptography.CryptographicException("The algorithm is not supported!");
            }

            return(saReturn);
        }
示例#8
0
        /// <summary>
        /// Parses the packet given as byte array into the current
        /// class and returns this with the populated parameters.
        /// </summary>
        /// <param name="bData">A byte array containing an OpenPGP
        /// representation of the packet.</param>
        /// <returns>Returns an SecretKeyPacket that containes
        /// the parsed properties.</returns>
        /// <remarks>No remarks</remarks>
        public override Packet ParsePacket(byte[] bData)
        {
            PublicKey = new PublicKeyPacket();
            PublicKey = (PublicKeyPacket)PublicKey.ParsePacket(bData);

            int iPos = this.PublicKey.Length;

            if (bData[iPos] == 255)
            {
                this.bIsEncrypted = true;
                iPos++;

                saSymmetricalAlgorithm = (SymAlgorithms)bData[iPos++];

                //String2Key Specifier expected
                // a S2K specifier is at max 11 bytes long
                byte[] bS2k = new byte[11];
                Array.Copy(bData, iPos, bS2k, 0, bS2k.Length);
                this.S2KSpecifier.ParseSpecifier(bS2k);
                iPos += S2KSpecifier.CraftContent().Length;

                //Parse Initial Vector
                int iBlockSize = CipherHelper.CipherBlockSize(saSymmetricalAlgorithm);
                this.InitialVector = new byte[iBlockSize];
                Array.Copy(bData, iPos, bInitialVector, 0, iBlockSize);
                iPos += iBlockSize;

                //Parse Encrypted MPIs (including checksum!!!)
                this.bEncryptedKeyMaterial = new byte[bData.Length - iPos];
                Array.Copy(bData, iPos, bEncryptedKeyMaterial, 0, bData.Length - iPos);
            }
            else if (bData[iPos] == 0)
            {
                this.bIsEncrypted = false;
                iPos++;

                //Parse unencrypted MPIs
                byte[] bMPIs = new byte[bData.Length - iPos - 2];
                Array.Copy(bData, iPos, bMPIs, 0, bMPIs.Length);

                biDecryptedKeyMaterial = BigInteger.ParseMPIs(bMPIs);

                iPos           += bMPIs.Length;
                this.sChecksum  = (ushort)(bData[iPos++] << 8);
                this.sChecksum ^= (ushort)bData[iPos];

                //validate checksum
                int iCurrentChecksum = 0;
                for (int i = 0; i < bMPIs.Length; i++)
                {
                    iCurrentChecksum = (iCurrentChecksum + bMPIs[i]) % 65536;
                }

                if (iCurrentChecksum != sChecksum)
                {
                    throw(new Exception("Key checksum is not correct. Someone played with the key?!"));
                }
            }
            else
            {
                //Encrypted in some strange way. We're not going
                //to support this
                throw(new Exception("This secret key is encrypted in some strange way. Sorry, but we're not going to support this. Get a real key!"));
            }


            this.bIsUpdated = false;
            return(this);
        }
示例#9
0
        private ESKSequence CreateESKSequence(TransportablePublicKey[] tpkKeys, AsymActions aaAction, SymAlgorithms saAlgo, byte[] bSymKey)
        {
            ESKSequence esksReturn = new ESKSequence();

            for (int i = 0; i < tpkKeys.Length; i++)
            {
                TransportablePublicKey tpkKey = tpkKeys[i];
                PublicKeyPacket        pkpKey = tpkKey.FindKey(aaAction);

                if (pkpKey == null)
                {
                    throw new Exception("Could not find subkey fitting to the selected action. Concerned Key: " + tpkKey.PrimaryUserID);
                }

                AsymSessionKeyPacket skpKey = new AsymSessionKeyPacket();
                skpKey.KeyID              = pkpKey.KeyID;
                skpKey.PublicAlgorithm    = pkpKey.Algorithm;
                skpKey.SymmetricAlgorithm = saAlgo;
                skpKey.SessionKey         = bSymKey;

                skpKey.EncryptSessionKey(pkpKey);

                esksReturn.AddAsymSessionKey(skpKey);
            }

            return(esksReturn);
        }
示例#10
0
        /// <summary>
        /// Creates a simmetric encrypted sequence
        /// </summary>
        /// <param name="alKeys">keys to produce the sequence for</param>
        /// <param name="aaAction">encrypt/sign</param>
        /// <param name="saAlgo">algorithm used</param>
        /// <param name="bSymKey">simmetric key</param>
        /// <returns>a simmetric encrypted sequence</returns>
        private static ESKSequence CreateESKSequence(ArrayList alKeys, AsymActions aaAction, SymAlgorithms saAlgo, byte[] bSymKey)
        {
            IEnumerator ieKeys = alKeys.GetEnumerator();
            ESKSequence esksReturn = new ESKSequence();

            while (ieKeys.MoveNext()) {
                TransportablePublicKey tpkKey = (TransportablePublicKey)ieKeys.Current;
                PublicKeyPacket pkpKey = tpkKey.FindKey(aaAction);

                if (pkpKey == null)
                    throw new Exception("Could not find subkey fitting to the selected action. Concerned Key: " + tpkKey.PrimaryUserID);

                AsymSessionKeyPacket skpKey = new AsymSessionKeyPacket();
                skpKey.KeyID = pkpKey.KeyID;
                skpKey.PublicAlgorithm = pkpKey.Algorithm;
                skpKey.SymmetricAlgorithm = saAlgo;
                skpKey.SessionKey = bSymKey;

                skpKey.EncryptSessionKey(pkpKey);

                esksReturn.AddAsymSessionKey(skpKey);
            }

            return esksReturn;
        }
示例#11
0
        public static void EncryptFiles(String[] strFiles, PublicKeyRing pkrPublicKeyRing, SecretKeyRing skrSecretKeyRing, bool bEncrypt, bool bSign)
        {
            PublicKeySelector pksSelectKeys = new PublicKeySelector(pkrPublicKeyRing);

            if (bEncrypt)
            {
                pksSelectKeys.ShowDialog();
                if (pksSelectKeys.SelectedKeys.Count == 0)
                {
                    MessageBox.Show("You did not select a public key to encrypt to. Doing nothing...", "Nothing Done...");
                    return;
                }
            }

            TransportableSecretKey tskKey = new TransportableSecretKey();
            string strPassphrase          = "";

            if (bSign)
            {
                QueryPassphrase qpPassphrase = new QueryPassphrase();
                qpPassphrase.ShowMyDialog(skrSecretKeyRing);
                tskKey        = qpPassphrase.SelectedKey;
                strPassphrase = qpPassphrase.Passphrase;
            }

            Working wWorking = new Working();

            wWorking.Show();


            for (int i = 0; i < strFiles.Length; i++)
            {
                byte[] bFileContent = new byte[0];
                try {
                    System.IO.FileStream fsFile   = new FileStream(strFiles[i], FileMode.Open);
                    BinaryReader         brReader = new BinaryReader(fsFile);
                    bFileContent = brReader.ReadBytes((int)fsFile.Length);
                    brReader.Close();
                    fsFile.Close();
                } catch (Exception e) {
                    wWorking.Hide();
                    MessageBox.Show("An error occured while opening the file " + strFiles[i] + ": " + e.Message, "Error...");
                    return;
                }

                LiteralMessage lmMessage = new LiteralMessage(DataFormatTypes.Binary);
                lmMessage.Binary      = bFileContent;
                lmMessage.TimeCreated = DateTime.Now;
                int iLastBackslash = strFiles[i].LastIndexOf("\\");
                lmMessage.Filename = strFiles[i].Substring(iLastBackslash + 1, strFiles[i].Length - iLastBackslash - 1);

                SharpPrivacy.OpenPGP.Messages.Message mEncryptionMessage = lmMessage;

                if (bSign)
                {
                    SignedMessage smMessage = new SignedMessage();
                    smMessage.MessageSigned = lmMessage;
                    SignaturePacket spPacket = new SignaturePacket();
                    spPacket.Version = SignaturePacketVersionNumbers.v3;
                    SecretKeyPacket skpKey = tskKey.FindKey(AsymActions.Sign);
                    spPacket.KeyID              = skpKey.PublicKey.KeyID;
                    spPacket.HashAlgorithm      = HashAlgorithms.SHA1;
                    spPacket.SignatureAlgorithm = skpKey.PublicKey.Algorithm;
                    spPacket.TimeCreated        = DateTime.Now;
                    spPacket.SignatureType      = SignatureTypes.TextSignature;
                    spPacket.Sign(lmMessage.Binary, skpKey, strPassphrase);
                    smMessage.Signature = spPacket;
                    mEncryptionMessage  = smMessage;
                }

                CompressedMessage cmMessage = new CompressedMessage();
                cmMessage.Compress(mEncryptionMessage);

                wWorking.Progress(20 / strFiles.Length);

                SymAlgorithms saAlgo = GetSymAlgorithmPreferences(pksSelectKeys.SelectedKeys);

                wWorking.Progress(10 / strFiles.Length);
                byte[] bReturn = new byte[0];
                if (bEncrypt)
                {
                    SymmetricallyEncryptedDataPacket sedpEncrypted = new SymmetricallyEncryptedDataPacket();
                    SymmetricAlgorithm saEncrypt = CipherHelper.CreateSymAlgorithm(saAlgo);
                    saEncrypt.Mode = CipherMode.OpenPGP_CFB;
                    saEncrypt.GenerateKey();
                    byte[] bKey = saEncrypt.Key;

                    ESKSequence esksKeys = new ESKSequence();
                    try {
                        esksKeys = CreateESKSequence(pksSelectKeys.SelectedKeys, AsymActions.Encrypt, saAlgo, bKey);
                    } catch (Exception e) {
                        wWorking.Hide();
                        MessageBox.Show("The following error occured: " + e.Message, "Error...");
                        return;
                    }

                    wWorking.Progress(50 / strFiles.Length);

                    ICryptoTransform ictEncryptor = saEncrypt.CreateEncryptor();
                    byte[]           bMessage     = cmMessage.GetEncoded();
                    byte[]           bOutput      = new byte[bMessage.Length];
                    ictEncryptor.TransformBlock(bMessage, 0, bMessage.Length, ref bOutput, 0);
                    bKey.Initialize();

                    wWorking.Progress(10 / strFiles.Length);

                    int iOutLength = (saEncrypt.BlockSize >> 3) + 2 + bMessage.Length;
                    sedpEncrypted.Body = new byte[iOutLength];
                    Array.Copy(bOutput, 0, sedpEncrypted.Body, 0, iOutLength);

                    byte[] bESK       = esksKeys.GetEncoded();
                    byte[] bEncrypted = sedpEncrypted.Generate();

                    bReturn = new byte[bESK.Length + bEncrypted.Length];
                    bESK.CopyTo(bReturn, 0);
                    bEncrypted.CopyTo(bReturn, bESK.Length);
                }
                else
                {
                    wWorking.Progress(60 / strFiles.Length);
                    bReturn = cmMessage.GetEncoded();
                }

                wWorking.Progress(10 / strFiles.Length);

                try {
                    FileStream   fsOut   = new FileStream(strFiles[i] + ".asc", FileMode.CreateNew);
                    BinaryWriter bwWrite = new BinaryWriter(fsOut);

                    bwWrite.Write(bReturn);
                    bwWrite.Close();
                    fsOut.Close();
                } catch (IOException io) {
                    MessageBox.Show("Could not write to file. The following error occured: " + io.Message, "Error...");
                }
            }

            wWorking.Hide();
        }
示例#12
0
        private static ESKSequence CreateESKSequence(ArrayList alKeys, AsymActions aaAction, SymAlgorithms saAlgo, byte[] bSymKey)
        {
            IEnumerator ieKeys     = alKeys.GetEnumerator();
            ESKSequence esksReturn = new ESKSequence();

            while (ieKeys.MoveNext())
            {
                TransportablePublicKey tpkKey = (TransportablePublicKey)ieKeys.Current;
                PublicKeyPacket        pkpKey = tpkKey.FindKey(aaAction);

                if (pkpKey == null)
                {
                    throw new Exception("Could not find subkey fitting to the selected action. Concerned Key: " + tpkKey.PrimaryUserID);
                }

                AsymSessionKeyPacket skpKey = new AsymSessionKeyPacket();
                skpKey.KeyID              = pkpKey.KeyID;
                skpKey.PublicAlgorithm    = pkpKey.Algorithm;
                skpKey.SymmetricAlgorithm = saAlgo;
                skpKey.SessionKey         = bSymKey;

                skpKey.EncryptSessionKey(pkpKey);

                esksReturn.AddAsymSessionKey(skpKey);
            }

            return(esksReturn);
        }
示例#13
0
        public static string EncryptText(string strMessage, PublicKeyRing pkrPublicKeyRing, SecretKeyRing skrSecretKeyRing, bool bSign)
        {
            PublicKeySelector pksSelectKeys = new PublicKeySelector(pkrPublicKeyRing);

            pksSelectKeys.ShowDialog();
            TransportableSecretKey tskKey = new TransportableSecretKey();
            string strPassphrase          = "";

            if (bSign)
            {
                QueryPassphrase qpPassphrase = new QueryPassphrase();
                qpPassphrase.ShowMyDialog(skrSecretKeyRing);
                tskKey        = qpPassphrase.SelectedKey;
                strPassphrase = qpPassphrase.Passphrase;
            }

            if (pksSelectKeys.SelectedKeys.Count == 0)
            {
                return(strMessage);
            }

            Working wWorking = new Working();

            wWorking.Show();

            LiteralMessage lmMessage = new LiteralMessage(DataFormatTypes.Text);

            lmMessage.Text        = strMessage;
            lmMessage.TimeCreated = DateTime.Now;
            lmMessage.Filename    = "";

            SharpPrivacy.OpenPGP.Messages.Message mEncryptionMessage = lmMessage;

            if (bSign)
            {
                SignedMessage smMessage = new SignedMessage();
                smMessage.MessageSigned = lmMessage;
                SignaturePacket spPacket = new SignaturePacket();
                spPacket.Version = SignaturePacketVersionNumbers.v3;
                SecretKeyPacket skpKey = tskKey.FindKey(AsymActions.Sign);
                spPacket.KeyID              = skpKey.PublicKey.KeyID;
                spPacket.HashAlgorithm      = HashAlgorithms.SHA1;
                spPacket.SignatureAlgorithm = skpKey.PublicKey.Algorithm;
                spPacket.TimeCreated        = DateTime.Now;
                spPacket.SignatureType      = SignatureTypes.TextSignature;
                spPacket.Sign(lmMessage.Binary, skpKey, strPassphrase);
                smMessage.Signature = spPacket;
                mEncryptionMessage  = smMessage;
            }

            CompressedMessage cmMessage = new CompressedMessage();

            cmMessage.Compress(mEncryptionMessage);

            wWorking.Progress(20);

            SymAlgorithms saAlgo = GetSymAlgorithmPreferences(pksSelectKeys.SelectedKeys);

            SymmetricallyEncryptedDataPacket sedpEncrypted = new SymmetricallyEncryptedDataPacket();
            SymmetricAlgorithm saEncrypt = CipherHelper.CreateSymAlgorithm(saAlgo);

            saEncrypt.Mode = CipherMode.OpenPGP_CFB;
            saEncrypt.GenerateKey();
            byte[] bKey = saEncrypt.Key;

            wWorking.Progress(10);
            ESKSequence esksKeys = new ESKSequence();

            try {
                esksKeys = CreateESKSequence(pksSelectKeys.SelectedKeys, AsymActions.Encrypt, saAlgo, bKey);
            } catch (Exception e) {
                wWorking.Hide();
                MessageBox.Show("The following error occured: " + e.Message, "Error...");
                return(strMessage);
            }

            wWorking.Progress(50);

            ICryptoTransform ictEncryptor = saEncrypt.CreateEncryptor();

            byte[] bMessage = cmMessage.GetEncoded();
            byte[] bOutput  = new byte[bMessage.Length];
            ictEncryptor.TransformBlock(bMessage, 0, bMessage.Length, ref bOutput, 0);
            bKey.Initialize();

            wWorking.Progress(10);

            int iOutLength = (saEncrypt.BlockSize >> 3) + 2 + bMessage.Length;

            sedpEncrypted.Body = new byte[iOutLength];
            Array.Copy(bOutput, 0, sedpEncrypted.Body, 0, iOutLength);

            byte[] bESK       = esksKeys.GetEncoded();
            byte[] bEncrypted = sedpEncrypted.Generate();

            byte[] bReturn = new byte[bESK.Length + bEncrypted.Length];
            bESK.CopyTo(bReturn, 0);
            bEncrypted.CopyTo(bReturn, bESK.Length);

            wWorking.Progress(10);
            string strReturn = Radix64.Encode(bReturn, true);

            strReturn = Armor.WrapMessage(strReturn);

            wWorking.Hide();
            return(strReturn);
        }
示例#14
0
        private ESKSequence CreateESKSequence(TransportablePublicKey[] tpkKeys, AsymActions aaAction, SymAlgorithms saAlgo, byte[] bSymKey)
        {
            ESKSequence esksReturn = new ESKSequence();

            for (int i=0; i<tpkKeys.Length; i++) {
                TransportablePublicKey tpkKey = tpkKeys[i];
                PublicKeyPacket pkpKey = tpkKey.FindKey(aaAction);

                if (pkpKey == null)
                    throw new Exception("Could not find subkey fitting to the selected action. Concerned Key: " + tpkKey.PrimaryUserID);

                AsymSessionKeyPacket skpKey = new AsymSessionKeyPacket();
                skpKey.KeyID = pkpKey.KeyID;
                skpKey.PublicAlgorithm = pkpKey.Algorithm;
                skpKey.SymmetricAlgorithm = saAlgo;
                skpKey.SessionKey = bSymKey;

                skpKey.EncryptSessionKey(pkpKey);

                esksReturn.AddAsymSessionKey(skpKey);
            }

            return esksReturn;
        }
示例#15
0
        /// <summary>
        /// Parses the packet given as byte array into the current
        /// class and returns this with the populated parameters.
        /// </summary>
        /// <param name="bData">A byte array containing an OpenPGP
        /// representation of the packet.</param>
        /// <returns>Returns an SecretKeyPacket that containes
        /// the parsed properties.</returns>
        /// <remarks>No remarks</remarks>
        public override Packet ParsePacket(byte[] bData)
        {
            PublicKey = new PublicKeyPacket();
            PublicKey = (PublicKeyPacket)PublicKey.ParsePacket(bData);

            int iPos = this.PublicKey.Length;

            if (bData[iPos] == 255) {
                this.bIsEncrypted = true;
                iPos++;

                saSymmetricalAlgorithm = (SymAlgorithms)bData[iPos++];

                //String2Key Specifier expected
                // a S2K specifier is at max 11 bytes long
                byte[] bS2k = new byte[11];
                Array.Copy(bData, iPos, bS2k, 0, bS2k.Length);
                this.S2KSpecifier.ParseSpecifier(bS2k);
                iPos += S2KSpecifier.CraftContent().Length;

                //Parse Initial Vector
                int iBlockSize = CipherHelper.CipherBlockSize(saSymmetricalAlgorithm);
                this.InitialVector = new byte[iBlockSize];
                Array.Copy(bData, iPos, bInitialVector, 0, iBlockSize);
                iPos += iBlockSize;

                //Parse Encrypted MPIs (including checksum!!!)
                this.bEncryptedKeyMaterial = new byte[bData.Length - iPos];
                Array.Copy(bData, iPos, bEncryptedKeyMaterial, 0, bData.Length - iPos);
            } else if (bData[iPos] == 0) {
                this.bIsEncrypted = false;
                iPos++;

                //Parse unencrypted MPIs
                byte[] bMPIs = new byte[bData.Length - iPos - 2];
                Array.Copy(bData, iPos, bMPIs, 0, bMPIs.Length);

                biDecryptedKeyMaterial = BigInteger.ParseMPIs(bMPIs);

                iPos += bMPIs.Length;
                this.sChecksum = (ushort)(bData[iPos++] << 8);
                this.sChecksum ^= (ushort)bData[iPos];

                //validate checksum
                int iCurrentChecksum = 0;
                for (int i=0; i<bMPIs.Length; i++)
                    iCurrentChecksum = (iCurrentChecksum + bMPIs[i]) % 65536;

                if (iCurrentChecksum != sChecksum)
                    throw(new Exception("Key checksum is not correct. Someone played with the key?!"));

            } else {
                //Encrypted in some strange way. We're not going
                //to support this
                throw(new Exception("This secret key is encrypted in some strange way. Sorry, but we're not going to support this. Get a real key!"));
            }

            this.bIsUpdated = false;
            return this;
        }