Beispiel #1
0
        public override void Parse(TreeBuilder tree)
        {
            S2K = new S2K();

            Version     = tree.ReadByte("Version");
            S2K.SymAlgo = tree.ReadByte("Symmetric Algorithm", SymmetricAlgorithmTypes.Get);
            byte S2KSpecifier = tree.ReadByte("S2K Specifier", S2KTypes.Get);

            if (S2KSpecifier != S2KTypes.Salted && S2KSpecifier != S2KTypes.Simple && S2KSpecifier != S2KTypes.IteratedAndSalted)
            {
                throw new InvalidDataException("Invalid S2K Specifier");
            }

            S2K.HashAlgorithm = tree.ReadByte("Hash Algorithm", HashAlgorithmTypes.Get);

            if (S2KSpecifier == S2KTypes.Salted || S2KSpecifier == S2KTypes.IteratedAndSalted)
            {
                S2K.Salt = tree.ReadBytes("Salt", 8);
                if (S2KSpecifier == S2KTypes.IteratedAndSalted)
                {
                    byte CodedCount = tree.ReadByte("Coded Iteration");
                    S2K.ByteCount = (16 + (CodedCount & 15)) << ((CodedCount >> 4) + 6);
                }
            }

            if (tree.IsMoreData())
            {
                EncryptedSessionKey = tree.ReadBytes("Encrypted Session Key");
            }
            else
            {
                EncryptedSessionKey = null;
            }
        }
Beispiel #2
0
        public bool DecryptS2K(string Password)
        {
            byte[] SessionKey = S2K.GetKey(Password);

            var decryptor = SymmProcess.GetDecryptor(S2K, SessionKey);

            var BlockSizeBytes  = S2K.IV.Length;
            int EncryptedLength = EncryptedPrivateKey.Length;
            int BlockFillLength = BlockSizeBytes * ((EncryptedLength / BlockSizeBytes) + 1);

            byte[] CryptBytes = new byte[BlockFillLength];
            Array.Copy(EncryptedPrivateKey, 0, CryptBytes, 0, EncryptedLength);


            byte[] ClearBytes;
            using (MemoryStream msDecrypt = new MemoryStream())
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
                {
                    csDecrypt.Write(CryptBytes, 0, CryptBytes.Length);
                    csDecrypt.Close();
                }
                ClearBytes = msDecrypt.ToArray().SubArray(0, EncryptedLength);
            }

            // Validate Decrypted Key
            int CheckLen = (S2K.S2KUsage == 254) ? 20 : 2;
            int DataLen  = ClearBytes.Length - CheckLen;

            byte[] CheckSum = ClearBytes.SubArray(DataLen, CheckLen);
            bool   bSuccess;

            if (CheckLen == 2)
            {
                long C = 0;
                for (int i = 0; i < DataLen; i++)
                {
                    C += ClearBytes[i];
                }
                C = C % 65536;

                bSuccess = ((C >> 8) == CheckSum[0] && (C & 0xff) == CheckSum[1]);
            }
            else
            {
                SHA1Managed sha           = new SHA1Managed();
                byte[]      HashToCompare = sha.ComputeHash(ClearBytes.SubArray(0, DataLen));
                bSuccess = HashToCompare.SequenceEqual(CheckSum);
            }

            if (bSuccess)
            {
                return(SetPrivate(ClearBytes));
            }


            return(false);
        }
Beispiel #3
0
        public static ICryptoTransform GetDecryptor(S2K S2k, byte[] SessionKey)
        {
            return(GetDecryptor(S2k.SymAlgo, S2k.IV, SessionKey));

            //if (S2k.SymAlgo != SymmetricAlgorithmTypes.AES128)
            //    throw new NotImplementedException("Non AES128 not yet implemented");


            //int KeySize = SymmetricAlgorithmTypes.GetKeySize(S2k.SymAlgo);
            //int BlockSizeBytes = S2k.IV.Length;

            //RijndaelManaged aes = new RijndaelManaged
            //{
            //    KeySize = KeySize,
            //    BlockSize = BlockSizeBytes * 8,
            //    FeedbackSize = BlockSizeBytes * 8,
            //    Key = SessionKey,
            //    IV = S2k.IV,
            //    Mode = CipherMode.CFB,
            //    Padding = PaddingMode.None
            //};

            //return aes.CreateDecryptor();
        }
Beispiel #4
0
        public override void Parse(TreeBuilder tree)
        {
            base.Parse(tree);

            bool IsEncrypted = true;

            tree.SetBookMark();
            var S2K = new S2K
            {
                S2KUsage = tree.ReadByte()
            };

            if (S2K.S2KUsage == 254 || S2K.S2KUsage == 255)
            {
                S2K.SymAlgo = tree.ReadByte("Symmetric Algorithm", SymmetricAlgorithmTypes.Get);

                byte S2KSpecifier = tree.ReadByte("S2K Specifier", S2KTypes.Get);

                if (S2KSpecifier != S2KTypes.Salted && S2KSpecifier != S2KTypes.Simple && S2KSpecifier != S2KTypes.IteratedAndSalted)
                {
                    //tree.AddCalculated("Invalid S2K", S2KSpecifier.ToString());
                    tree.AddCalculated("Unable to Process", S2KSpecifier.ToString(), ByteBlockType.CalculatedError);
                    return;
                }

                S2K.HashAlgorithm = tree.ReadByte("Hash Algorithm", HashAlgorithmTypes.Get);

                if (S2KSpecifier == S2KTypes.Salted || S2KSpecifier == S2KTypes.IteratedAndSalted)
                {
                    S2K.Salt = tree.ReadBytes("Salt", 8);
                    if (S2KSpecifier == S2KTypes.IteratedAndSalted)
                    {
                        byte CodedCount = tree.ReadByte("Coded Iteration");
                        S2K.ByteCount = (16 + (CodedCount & 15)) << ((CodedCount >> 4) + 6);
                    }
                }

                int BlockSizeBytes = SymmetricAlgorithmTypes.GetBlockSize(S2K.SymAlgo) / 8;
                S2K.IV = tree.ReadBytes("IV", BlockSizeBytes);
            }
            else
            {
                byte SymAlgo = S2K.S2KUsage;
                S2K.SymAlgo = SymAlgo;

                if (SymAlgo != 0)
                {
                    tree.GoToBookMark();
                    tree.ReadByte("Symmetric Algorithm", SymmetricAlgorithmTypes.Get);
                    int BlockSize = SymmetricAlgorithmTypes.GetBlockSize(SymAlgo) / 8;
                    S2K.IV = tree.ReadBytes("IV", BlockSize);
                }
                else
                {
                    IsEncrypted = false;
                }
            }

            PublicKeyAlgorithm.S2K = S2K;

            if (IsEncrypted)
            {
                byte[] Encrypted = tree.ReadBytes("Encrypted Secret Key");
                PublicKeyAlgorithm.EncryptedPrivateKey = Encrypted;
                tree.CurrentBlock.ProcessBlock        += ExtractPrivateKey;
                SecretKeyNode = tree.CurrentBlock;
            }
            else
            {
                byte[] ClearBytes = tree.ReadBytes("Unencrypted Secret Key");

                var SecBlockClear = PublicKeyAlgorithm.SetPrivate(ClearBytes);
                tree.AddChild(PublicKeyAlgorithm.GetPrivateByteBlocks());
            }
        }