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());
        }
示例#3
0
        // https://tools.ietf.org/html/rfc4357#section-5.2
        public byte[] Vko(EncryptedPrivateKey encPk, ECPublicKeyParameters sessionKey)
        {
            var privKey = (ECPrivateKeyParameters)_keyPair.Private;

            var ukmBytes = (byte[])encPk.UKM.Clone();

            Array.Reverse(ukmBytes);
            var ukm = new BigInteger(1, ukmBytes);

            var p        = ukm.Multiply(privKey.D).Mod(sessionKey.Parameters.Curve.Order);
            var kekPoint = sessionKey.Q.Multiply(p).Normalize();
            var x        = kekPoint.XCoord.ToBigInteger().ToByteArrayUnsigned();
            var y        = kekPoint.YCoord.ToBigInteger().ToByteArrayUnsigned();

            var kekBytes = new byte[64];

            Array.Copy(y, 0, kekBytes, 0, 32);
            Array.Copy(x, 0, kekBytes, 32, 32);
            Array.Reverse(kekBytes);

            var kek = new byte[32];
            var dig = new Gost3411Digest();

            dig.BlockUpdate(kekBytes, 0, kekBytes.Length);
            dig.DoFinal(kek, 0);

            return(kek);
        }
示例#4
0
文件: Form1.cs 项目: Oboltys/ECP
        public BigInteger GetDigest(byte[] message)
        {
            Gost3411Digest gost3411Digest = new Gost3411Digest();

            gost3411Digest.BlockUpdate(message, 0, message.Length);
            byte[] hashmessage = new byte[gost3411Digest.GetDigestSize()];
            gost3411Digest.DoFinal(hashmessage, 0);
            return(new BigInteger(hashmessage));
        }
示例#5
0
        private byte[] generateKey(byte[] startkey)
        {
            byte[] newKey = new byte[Gost28147_KEY_LENGTH];

            Gost3411Digest digest = new Gost3411Digest();

            digest.BlockUpdate(startkey, 0, startkey.Length);
            digest.DoFinal(newKey, 0);

            return(newKey);
        }
示例#6
0
        /**
         * Test Sign and Verify with test parameters
         * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt
         * gostR3410-2001-TestParamSet  P.46
         */
        private void ecGOST3410_TestParam()
        {
            SecureRandom random = new SecureRandom();

            BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
            BigInteger mod_q = new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619");

            FpCurve curve = new FpCurve(
                mod_p,                                                                                           // p
                new BigInteger("7"),                                                                             // a
                new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414"), // b
                mod_q, BigInteger.One);

            ECDomainParameters parameters = new ECDomainParameters(
                curve,
                curve.CreatePoint(
                    new BigInteger("2"),                                                                             // x
                    new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")), // y
                mod_q);

            ECKeyPairGenerator        pGen     = new ECKeyPairGenerator();
            ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(
                parameters,
                random);

            pGen.Init(genParam);

            AsymmetricCipherKeyPair pair = pGen.GenerateKeyPair();

            ParametersWithRandom param = new ParametersWithRandom(pair.Private, random);

            ECGost3410Signer ecgost3410 = new ECGost3410Signer();

            ecgost3410.Init(true, param);

            //get hash message using the digest GOST3411.
            byte[]         message  = Encoding.ASCII.GetBytes("Message for sign");
            Gost3411Digest gost3411 = new Gost3411Digest();

            gost3411.BlockUpdate(message, 0, message.Length);
            byte[] hashmessage = new byte[gost3411.GetDigestSize()];
            gost3411.DoFinal(hashmessage, 0);

            BigInteger[] sig = ecgost3410.GenerateSignature(hashmessage);

            ecgost3410.Init(false, pair.Public);

            if (!ecgost3410.VerifySignature(hashmessage, sig[0], sig[1]))
            {
                Fail("signature fails");
            }
        }
示例#7
0
        private bool VerifyGost(byte[] buffer, int length, byte[] signature)
        {
            ECDomainParameters dParams = ECGost3410NamedCurves.GetByOid(CryptoProObjectIdentifiers.GostR3410x2001CryptoProA);

            byte[]  reversedPublicKey = PublicKey.Reverse().ToArray();
            ECPoint q = dParams.Curve.CreatePoint(new BigInteger(1, reversedPublicKey, 32, 32), new BigInteger(1, reversedPublicKey, 0, 32), false);
            ECPublicKeyParameters parameters = new ECPublicKeyParameters(q, dParams);

            var signer = new ECGost3410Signer();

            signer.Init(false, parameters);

            var digest = new Gost3411Digest();

            digest.BlockUpdate(buffer, 0, length);
            byte[] hash = new byte[digest.GetDigestSize()];
            digest.DoFinal(hash, 0);

            return(signer.VerifySignature(hash, new BigInteger(1, signature, 32, 32), new BigInteger(1, signature, 0, 32)));
        }
示例#8
0
        private byte[] SignGost(byte[] buffer, int length)
        {
            ECGost3410Signer signer = new ECGost3410Signer();

            signer.Init(true, new ParametersWithRandom(PrivateKeyFactory.CreateKey(PrivateKey), _secureRandom));

            var digest = new Gost3411Digest();

            digest.BlockUpdate(buffer, 0, length);
            byte[] hash = new byte[digest.GetDigestSize()];
            digest.DoFinal(hash, 0);

            var signature = signer.GenerateSignature(hash);

            byte[] res = new byte[64];

            signature[0].ToByteArrayUnsigned().CopyTo(res, 32);
            signature[1].ToByteArrayUnsigned().CopyTo(res, 0);

            return(res);
        }
示例#9
0
 public int DoFinal(byte[] output, int outOff)
 {
     return(digest.DoFinal(output, outOff));
 }