Exemplo n.º 1
0
        private static bool _VerifyStandardEncryptionKey(
            HashAlgorithm hAlg, _EncryptionInfo ei, byte[] hFinalPrev)
        {
            var pos = ei.verifierOffset;
            var evi = new byte[16];
            var evh = new byte[32];

            System.Array.Copy(ei.bytes, pos + 20, evi, 0, evi.Length);
            System.Array.Copy(ei.bytes, pos + 40, evh, 0, evh.Length);
            var dvi  = new byte[evi.Length];
            var dvh  = new byte[evh.Length];
            var cAlg = _CreateCipherAlgorithmForKey(ei);

            cAlg.Key = _MakeEncryptionKey(hAlg, ei, hFinalPrev, _ToBytes(0));
            using (var dec = cAlg.CreateDecryptor()) {
                dec.TransformBlock(evi, 0, dvi.Length, dvi, 0);
                dec.TransformBlock(evh, 0, dvh.Length, dvh, 0);
            }
            cAlg.Clear();
            var hv = hAlg.ComputeHash(dvi);

            for (var n = 0; n < hv.Length; ++n)
            {
                if (hv[n] != dvh[n])
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 2
0
        private static byte[] _MakeDataEncryptionKey(
            HashAlgorithm hAlg, _EncryptionInfo ei, byte[] hFinalPrev)
        {
            byte[] bk;
            if (ei.isStandardEncryption)
            {
                bk = _ToBytes(0);
                return(_MakeStandardEncryptionKey(hAlg, ei, hFinalPrev, bk));
            }
            bk = new byte[] { 0x14, 0x6E, 0x0B, 0xE7, 0xAB, 0xAC, 0xD0, 0xD6 };
            var ek   = _MakeEncryptionKey(hAlg, ei, hFinalPrev, bk);
            var node = ei.encryptedKeyNode;
            var ekv  = System.Convert.FromBase64String(
                node.GetAttribute("encryptedKeyValue")
                );
            var cAlg = _CreateCipherAlgorithmForKey(ei);

            cAlg.Key = ek;
            cAlg.IV  = _MakeIv(node);
            var dkv = new byte[ekv.Length];

            using (var dec = cAlg.CreateDecryptor()) {
                dec.TransformBlock(ekv, 0, dkv.Length, dkv, 0);
            }
            cAlg.Clear();
            return(dkv);
        }
Exemplo n.º 3
0
        private static string _VerifyEncryptionInfo(_EncryptionInfo ei)
        {
            if (ei.isExtensibleEncryption)
            {
                return("Extensible encryption is not supported.");
            }
            if (!ei.isStandardEncryption && !ei.isAgileEncryption)
            {
                return("Unknown encryption version.");
            }
            if (ei.isStandardEncryption)
            {
                var cAlgId = _ToU32(ei.bytes, 20);
                var hAlgId = _ToU32(ei.bytes, 24);
                if (cAlgId != 0x660E && cAlgId != 0x660F && cAlgId != 0x6610)
                {
                    return(string.Format(
                               "'{0:X8}' is invalid 'AlgID' value.", cAlgId
                               ));
                }
                if (hAlgId != 0x8004)
                {
                    return(string.Format(
                               "'{0:X8}' is invalid 'AlgIDHash' value.", hAlgId
                               ));
                }
                return(null);
            }
            XmlElement node    = null;
            string     algName = null;

            System.Func <string> algNameError = () => {
                return(string.Format(
                           "<{0}/> '{1}' is not supported.", node.Name, algName
                           ));
            };
            node    = ei.encryptedKeyNode;
            algName = node.GetAttribute("hashAlgorithm");
            if (!_hashAlgorithmCreators.ContainsKey(algName))
            {
                return(algNameError());
            }
            algName = node.GetAttribute("cipherAlgorithm");
            if (!_cipherAlgorithmCreators.ContainsKey(algName))
            {
                return(algNameError());
            }
            node    = ei.keyDataNode;
            algName = node.GetAttribute("hashAlgorithm");
            if (!_hashAlgorithmCreators.ContainsKey(algName))
            {
                return(algNameError());
            }
            algName = node.GetAttribute("cipherAlgorithm");
            if (!_cipherAlgorithmCreators.ContainsKey(algName))
            {
                return(algNameError());
            }
            return(null);
        }
Exemplo n.º 4
0
        private static IEnumerable <int> _DecryptPackage(
            _EncryptionInfo ei, byte[] encryptionKey, byte[] encryptedPackage,
            byte[] output, int startSegment, int segmentCount = -1)
        {
            const int SegSz = 4096;
            var       src   = encryptedPackage;
            var       dst   = output;
            var       cAlg  = _CreateCipherAlgorithmForData(ei);

            cAlg.Key = encryptionKey;
            var end = segmentCount * SegSz;

            if (end < 0 || end > dst.Length)
            {
                end = dst.Length;
            }
            var seg = startSegment;

            for (var n = seg * SegSz; n < end; n += SegSz, ++seg)
            {
                if (ei.isAgileEncryption)
                {
                    cAlg.IV = _MakeIv(ei.keyDataNode, _ToBytes((uint)seg));
                }
                var count = (SegSz < end - n) ? SegSz : (end - n);
                var dec   = cAlg.CreateDecryptor();
                dec.TransformBlock(src, 8 + n, count, dst, n);
                dec.Dispose();
                yield return(count);
            }
            cAlg.Clear();
        }
Exemplo n.º 5
0
 SymmetricAlgorithm _CreateCipherAlgorithmForKey(_EncryptionInfo ei)
 {
     if (ei.isStandardEncryption)
     {
         return(_CreateCipherAlgorithmForData(ei));
     }
     return(_CreateCipherAlgorithm(ei.encryptedKeyNode));
 }
Exemplo n.º 6
0
 private static bool _VerifyEncryptionKey(
     HashAlgorithm hAlg, _EncryptionInfo ei, byte[] key)
 {
     if (ei.isAgileEncryption)
     {
         return(_VerifyAgileEncryptionKey(hAlg, ei, key));
     }
     return(_VerifyStandardEncryptionKey(hAlg, ei, key));
 }
Exemplo n.º 7
0
 private static byte[] _MakeEncryptionKey(
     HashAlgorithm hAlg, _EncryptionInfo ei,
     byte[] hFinalPrev, byte[] blockKey)
 {
     if (ei.isAgileEncryption)
     {
         return(_MakeAgileEncryptionKey(hAlg, ei, hFinalPrev, blockKey));
     }
     return(_MakeStandardEncryptionKey(hAlg, ei, hFinalPrev, blockKey));
 }
Exemplo n.º 8
0
        HashAlgorithm _CreateHashAlgorithmForData(_EncryptionInfo ei)
        {
            if (ei.isStandardEncryption)
            {
                return(_CreateHashAlgorithm());
            }
            var node = ei.keyDataNode;
            var name = node.GetAttribute("hashAlgorithm");

            return(_CreateHashAlgorithm(name));
        }
Exemplo n.º 9
0
        private static byte[] _MakeStandardEncryptionKey(
            HashAlgorithm hAlg, _EncryptionInfo ei,
            byte[] hFinalPrev, byte[] blockKey)
        {
            var hFinal = _H(hAlg, hFinalPrev, blockKey);
            var x1     = _MakeX1(hAlg, hFinal);
            var x2     = _MakeX2(hAlg, hFinal);
            var x3     = _MakeX3(x1, x2);
            var cbRequiredKeyLength = ei.keyBits / 8;

            System.Array.Resize(ref x3, (int)cbRequiredKeyLength);
            return(x3);
        }
Exemplo n.º 10
0
        SymmetricAlgorithm _CreateCipherAlgorithmForData(_EncryptionInfo ei)
        {
            SymmetricAlgorithm cAlg = null;

            if (ei.isStandardEncryption)
            {
                cAlg         = _CreateCipherAlgorithm();
                cAlg.KeySize = (int)ei.keyBits;
                cAlg.Mode    = CipherMode.ECB;
                cAlg.Padding = PaddingMode.None;
                return(cAlg);
            }
            return(_CreateCipherAlgorithm(ei.keyDataNode));
        }
Exemplo n.º 11
0
        private static byte[] _MakeAgileEncryptionKey(
            HashAlgorithm hAlg, _EncryptionInfo ei,
            byte[] hFinalPrev, byte[] blockKey)
        {
            var hFinal  = _H(hAlg, hFinalPrev, blockKey);
            var node    = ei.encryptedKeyNode;
            var keySize = int.Parse(node.GetAttribute("keyBits")) / 8;
            var n       = hFinal.Length;

            System.Array.Resize(ref hFinal, keySize);
            for (; n < hFinal.Length; ++n)
            {
                hFinal[n] = 0x36;
            }
            return(hFinal);
        }
Exemplo n.º 12
0
        private static bool _VerifyAgileEncryptionKey(
            HashAlgorithm hAlg, _EncryptionInfo ei, byte[] hFinalPrev)
        {
            var node = ei.encryptedKeyNode;
            var evi  = System.Convert.FromBase64String(
                node.GetAttribute("encryptedVerifierHashInput")
                );
            var evh = System.Convert.FromBase64String(
                node.GetAttribute("encryptedVerifierHashValue")
                );
            var cAlg = _CreateCipherAlgorithmForKey(ei);

            cAlg.IV = _MakeIv(node);
            var dvi = new byte[evi.Length];
            var dvh = new byte[evh.Length];

            cAlg.Key = _MakeEncryptionKey(hAlg, ei, hFinalPrev,
                                          new byte[] { 0xFE, 0xA7, 0xD2, 0x76, 0x3B, 0x4B, 0x9E, 0x79 }
                                          );
            using (var dec = cAlg.CreateDecryptor()) {
                dec.TransformBlock(evi, 0, dvi.Length, dvi, 0);
            }
            cAlg.Key = _MakeEncryptionKey(hAlg, ei, hFinalPrev,
                                          new byte[] { 0xD7, 0xAA, 0x0F, 0x6D, 0x30, 0x61, 0x34, 0x4E }
                                          );
            using (var dec = cAlg.CreateDecryptor()) {
                dec.TransformBlock(evh, 0, dvh.Length, dvh, 0);
            }
            cAlg.Clear();
            var hv = hAlg.ComputeHash(dvi);

            for (var n = 0; n < hv.Length; ++n)
            {
                if (hv[n] != dvh[n])
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 13
0
        private static IEnumerable <byte[]> _GenerateHFinalPrev(
            HashAlgorithm hAlg, _EncryptionInfo ei, string password)
        {
            byte[] salt;
            uint   spinCount;

            if (ei.isAgileEncryption)
            {
                var node = ei.encryptedKeyNode;
                salt = System.Convert.FromBase64String(
                    node.GetAttribute("saltValue")
                    );
                spinCount = uint.Parse(node.GetAttribute("spinCount"));
            }
            else
            {
                salt = new byte[16];
                var offset = ei.verifierOffset + 4;
                System.Array.Copy(ei.bytes, offset, salt, 0, salt.Length);
                spinCount = 50000;
            }
            var hInit  = _H(hAlg, salt, Encoding.Unicode.GetBytes(password));
            var hSize  = hAlg.HashSize / 8;
            var hInput = new byte[4 + hSize];
            var hCurr  = hInit;

            for (uint i = 0; i < spinCount; ++i)
            {
                hInput[0] = (byte)(i >> 0);
                hInput[1] = (byte)(i >> 8);
                hInput[2] = (byte)(i >> 16);
                hInput[3] = (byte)(i >> 24);
                System.Array.Copy(hCurr, 0, hInput, 4, hSize);
                hCurr = hAlg.ComputeHash(hInput);
                yield return(null);
            }
            yield return(hCurr);
        }