private byte[] GetDecodeKey(byte[] salt, byte[] pin)
        {
            var pincode4 = new byte[pin.Length * 4];

            for (int i = 0; i < pin.Length; ++i)
            {
                pincode4[i * 4] = pin[i];
            }

            var digest = new Gost3411Digest(Gost28147Engine.GetSBox("D-A"));

            digest.BlockUpdate(salt, 0, salt.Length);
            if (pin.Length > 0)
            {
                digest.BlockUpdate(pincode4, 0, pincode4.Length);
            }

            var result = new byte[32];

            digest.DoFinal(result, 0);

            var current    = Encoding.ASCII.GetBytes("DENEFH028.760246785.IUEFHWUIO.EF");
            var material36 = new byte[32];
            var material5c = new byte[32];
            int len        = pin.Length > 0 ? 2000 : 2;

            for (int i = 0; i < len; ++i)
            {
                XorMaterial(material36, material5c, current);
                digest.Reset();
                digest.BlockUpdate(material36, 0, 32);
                digest.BlockUpdate(result, 0, 32);
                digest.BlockUpdate(material5c, 0, 32);
                digest.BlockUpdate(result, 0, 32);
                digest.DoFinal(current, 0);
            }

            XorMaterial(material36, material5c, current);
            digest.Reset();
            digest.BlockUpdate(material36, 0, 32);
            digest.BlockUpdate(salt, 0, 12);
            digest.BlockUpdate(material5c, 0, 32);
            if (pin.Length > 0)
            {
                digest.BlockUpdate(pincode4, 0, pincode4.Length);
            }
            digest.DoFinal(current, 0);

            var result_key = new byte[32];

            digest.Reset();
            digest.BlockUpdate(current, 0, 32);
            digest.DoFinal(result_key, 0);

            return(result_key);
        }
        private byte[] GetDecryptionKey(string pin, VipNetContainer defence)
        {
            var passwordData = Encoding.ASCII.GetBytes(pin ?? "");

            if (DefenceKeyInfo.KeyClass.Value.IntValue == 64 && DefenceKeyInfo.KeyType.Value.IntValue == 24622)
            {
                // Контейнер зашифрован ключом, лежащим в ещё одном контейнере
                if (defence == null)
                {
                    throw new CryptographicException("Закрытый ключ зашифрован секретным ключом, расположенным в отдельном вспомогательном контейнере. Используйте опцию --defence");
                }
                return(defence.Entries[0].GetProtectionKey(pin));
            }
            if (DefenceKeyInfo.Algorithm != null &&
                DefenceKeyInfo.Algorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdPbkdf2))
            {
                // PBKDF2 используется в контейнерах ViPNet Jcrypto SDK
                // Самое смешное, что сам десктопный ViPNet CSP не понимает такие контейнеры
                // А мы понимаем!
                var p = Pbkdf2Params.GetInstance(DefenceKeyInfo.Algorithm.Parameters);
                return(PBKDF2(
                           MacUtilities.GetMac(p.Prf.Algorithm),
                           passwordData,
                           p.GetSalt(),
                           p.IterationCount.IntValue,
                           p.KeyLength.IntValue
                           ));
            }
            var digest        = new Gost3411Digest();
            var keyData       = new byte[digest.GetDigestSize()];
            var unwrappingKey = new byte[digest.GetDigestSize()];

            digest.BlockUpdate(passwordData, 0, passwordData.Length);
            digest.DoFinal(keyData, 0);
            digest.Reset();

            var secodeData = passwordData.Concat(keyData).ToArray();

            digest.BlockUpdate(secodeData, 0, secodeData.Length);
            digest.DoFinal(unwrappingKey, 0);

            var tmp = new int[keyData.Length / 4];

            for (int i = 0; i < keyData.Length; i += 4)
            {
                tmp[i / 4] = BitConverter.ToInt32(keyData, i) - BitConverter.ToInt32(unwrappingKey, i);
            }

            return(tmp.SelectMany(x => BitConverter.GetBytes(x)).ToArray());
        }
Beispiel #3
0
 public void Reset()
 {
     digest.Reset();
 }