Пример #1
0
        /// <summary>
        /// Упаковка открытого ключа ГОСТ 34.10-2012 512 и его параметров в Asn1c структуру.
        /// </summary>
        ///
        /// <param name="pub">Открытый ключ.</param>
        ///
        /// <returns>Asn1c структура <c>SubjectPublicKeyInfo</c> открытого
        /// ключа.</returns>
        private static SubjectPublicKeyInfo PackPublicKeyInfo2012_512(
            Gost3410CspObject pub)
        {
            SubjectPublicKeyInfo spki      = new SubjectPublicKeyInfo();
            Asn1BerEncodeBuffer  buffer    = new Asn1BerEncodeBuffer();
            Asn1OctetString      publicKey = new Asn1OctetString(pub._publicKey);

            publicKey.Encode(buffer);
            byte[] octetString = buffer.MsgCopy;
            spki.subjectPublicKey = new Asn1BitString(
                octetString.Length * 8, octetString);
            GostR3410_2012_PublicKeyParameters par =
                new GostR3410_2012_PublicKeyParameters();

            par.publicKeyParamSet  = fromString(pub._publicKeyParamSet);
            par.digestParamSet     = fromString(pub._digestParamSet);
            par.encryptionParamSet = CreateGost28147_89_ParamSet(
                pub._encryptionParamSet);
            buffer.Reset();
            par.Encode(buffer);
            spki.algorithm = new AlgorithmIdentifier(
                fromString(GostConstants.OID_CP_GOST_R3410_12_512),
                new Asn1OpenType(buffer.MsgCopy));
            return(spki);
        }
Пример #2
0
        /// <summary>
        /// Кодирование Public ключа ГОСТ 34.10 в BLOB для импорта.
        /// </summary>
        ///
        /// <param name="cspObject">Открытый ключ с параметрами.</param>
        /// <param name="alg">Тип алгоритма</param>
        ///
        /// <returns>BLOB для импорта.</returns>
        ///
        /// <exception cref="CryptographicException">При ошибках
        /// кодирования структуры.</exception>
        /// <argnull name="cspObject" />
        ///
        /// <intdoc><para>Аналог в MS отсутствует, часть реализации
        /// присутствует в ImportKey. У нас функция используется еще
        /// и при разборе открытого клуча в обходе
        /// CryptoPro.Sharpei.NetDetours.CPPublicKey.</para></intdoc>
        ///
        /// <unmanagedperm action="LinkDemand" />
        internal static byte[] EncodePublicBlob(Gost3410CspObject cspObject, CspAlgorithmType alg)
        {
            int keySize;
            int algId;

            switch (alg)
            {
            case CspAlgorithmType.PROV_GOST_2001_DH:
                keySize = GostConstants.GOST_3410EL_SIZE;
                algId   = GostConstants.CALG_GR3410EL;
                break;

            case CspAlgorithmType.PROV_GOST_2012_256:
                keySize = GostConstants.GOST3410_2012_256KEY_SIZE;
                algId   = GostConstants.CALG_GR3410_2012_256;
                break;

            case CspAlgorithmType.PROV_GOST_2012_512:
                keySize = GostConstants.GOST3410_2012_512KEY_SIZE;
                algId   = GostConstants.CALG_GR3410_2012_512;
                break;

            default:
                throw new CryptographicException(SR.Cryptography_CSP_WrongKeySpec);
            }

            if (cspObject == null)
            {
                throw new ArgumentNullException("cspObject");
            }

            byte[] encodedParameters = cspObject.EncodeParameters();

            byte[] data = new byte[16 + encodedParameters.Length
                                   + cspObject._publicKey.Length];
            data[0] = GostConstants.PUBLICKEYBLOB;
            data[1] = GostConstants.CSP_CUR_BLOB_VERSION;

            byte[] algid = BitConverter.GetBytes(algId);
            Array.Copy(algid, 0, data, 4, 4);

            byte[] magic = BitConverter.GetBytes(GostConstants.GR3410_1_MAGIC);
            Array.Copy(magic, 0, data, 8, 4);

            byte[] bitlen = BitConverter.GetBytes(keySize);
            Array.Copy(bitlen, 0, data, 12, 4);

            Array.Copy(encodedParameters, 0, data, 16,
                       encodedParameters.Length);
            Array.Copy(cspObject._publicKey, 0, data,
                       16 + encodedParameters.Length,
                       cspObject._publicKey.Length);
            return(data);
        }
Пример #3
0
        /// <summary>
        /// Упаковка открытого ключа ГОСТ 34.10 и его параметров в Asn1c структуру.
        /// </summary>
        ///
        /// <param name="pub">Открытый ключ.</param>
        /// <param name="alg"></param>
        ///
        /// <returns>Asn1c структура <c>SubjectPublicKeyInfo</c> открытого
        /// ключа.</returns>
        ///
        private static SubjectPublicKeyInfo PackPublicKeyInfo(
            Gost3410CspObject pub, CspAlgorithmType alg)
        {
            switch (alg)
            {
            case CspAlgorithmType.Gost2001:
                return(PackPublicKeyInfo2001(pub));

            case CspAlgorithmType.Gost2012_256:
                return(PackPublicKeyInfo2012_256(pub));

            case CspAlgorithmType.Gost2012_512:
                return(PackPublicKeyInfo2012_512(pub));

            default:
                throw new CryptographicException(
                          "Cryptography_CSP_WrongKeySpec");
            }
        }
Пример #4
0
        /// <summary>
        /// Разбор декодированной ASN1c структуры ГОСТ 34.10-2012 <c>SubjectPublicKeyInfo</c>.
        /// </summary>
        ///
        /// <param name="spki">ASN1c структура <c>SubjectPublicKeyInfo</c>.
        /// </param>
        ///
        /// <returns>Параметры открытого ключа.</returns>
        /// <argnull name="spki" />
        /// <exception cref="ArgumentException">Если вложенная структура
        /// не приводится к <c>GostR3410_2001_PublicKeyParameters</c>
        /// </exception>
        private static Gost3410CspObject UnpackPublicKeyInfo2012(
            SubjectPublicKeyInfo spki)
        {
            if (spki == null)
            {
                throw new ArgumentNullException("spki");
            }
            Asn1Choice choice = spki.algorithm.parameters as Asn1Choice;

            if (choice == null)
            {
                throw new ArgumentException(
                          "spki.algorithm.parameters");
            }
            GostR3410_2012_PublicKeyParameters publicKeyParameters =
                choice.GetElement() as GostR3410_2012_PublicKeyParameters;

            if (publicKeyParameters == null)
            {
                throw new ArgumentException(
                          "spki.algorithm.parameters.element");
            }
            byte[] bitString              = spki.subjectPublicKey.Value;
            Asn1BerDecodeBuffer buffer    = new Asn1BerDecodeBuffer(bitString);
            Asn1OctetString     publicKey = new Asn1OctetString();

            publicKey.Decode(buffer);
            Gost3410CspObject ret = new Gost3410CspObject();

            ret._publicKeyParamSet = toString(
                publicKeyParameters.publicKeyParamSet);
            ret._digestParamSet = toString(
                publicKeyParameters.digestParamSet);
            ret._encryptionParamSet = toString(
                publicKeyParameters.encryptionParamSet);
            ret._publicKey  = publicKey.Value;
            ret._privateKey = null;
            return(ret);
        }
Пример #5
0
        /// <summary>
        /// Разбор BLOB открытого ключа ГОСТ 34.10.
        /// </summary>
        ///
        /// <param name="obj">Gost3410CspObject</param>
        /// <param name="data">BLOB</param>
        /// <param name="alg">Тип алгоритма</param>
        ///
        /// <argnull name="obj" />
        /// <exception cref="CryptographicException">Если
        /// <paramref name="obj"/> не объект типа
        /// <see cref="Gost3410CspObject"/></exception>
        ///
        /// <intdoc><para>Аналог в MS отсутствует, часть реализации
        /// присутствует в ImportKey. </para></intdoc>
        ///
        /// <unmanagedperm action="LinkDemand" />
        internal static void DecodePublicBlob(Object obj, byte[] data, CspAlgorithmType alg)
        {
            int keySize;

            switch (alg)
            {
            case CspAlgorithmType.PROV_GOST_2001_DH:
                keySize = GostConstants.GOST_3410EL_SIZE;
                break;

            case CspAlgorithmType.PROV_GOST_2012_256:
                keySize = GostConstants.GOST3410_2012_256KEY_SIZE;
                break;

            case CspAlgorithmType.PROV_GOST_2012_512:
                keySize = GostConstants.GOST3410_2012_512KEY_SIZE;
                break;

            default:
                throw new CryptographicException(SR.Cryptography_CSP_WrongKeySpec);
            }

            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            Gost3410CspObject cspObject = obj as Gost3410CspObject;

            if (cspObject == null)
            {
                throw new CryptographicException(GostConstants.NTE_BAD_ALGID);
            }
            if (data.Length < 16 + keySize / 8)
            {
                throw new CryptographicException(GostConstants.NTE_BAD_DATA);
            }

            // CRYPT_PUBKEYPARAM -> 8 { Magic, BitLen )
            uint magic  = BitConverter.ToUInt32(data, 8);
            uint bitlen = BitConverter.ToUInt32(data, 12);

            if (magic != GostConstants.GR3410_1_MAGIC)
            {
                throw new CryptographicException(GostConstants.NTE_BAD_DATA);
            }
            if (bitlen != keySize)
            {
                throw new CryptographicException(GostConstants.NTE_BAD_DATA);
            }

            byte[] tmp = new byte[data.Length - 16 - keySize / 8];
            Array.Copy(data, 16, tmp, 0, data.Length - 16 - keySize / 8);


            var publicKeyParameters = new GostKeyExchangeParameters();
            var encodeKeyParameters = new byte[(data.Length - 16) - keySize / 8];

            Array.Copy(data, 16, encodeKeyParameters, 0, (data.Length - 16) - keySize / 8);
            publicKeyParameters.DecodeParameters(encodeKeyParameters);

            var publicKey = new byte[keySize / 8];

            Array.Copy(data, data.Length - keySize / 8, publicKey, 0, keySize / 8);
            publicKeyParameters.PublicKey = publicKey;

            cspObject._publicKey         = publicKeyParameters.PublicKey;
            cspObject._publicKeyParamSet = publicKeyParameters.PublicKeyParamSet;
            cspObject._digestParamSet    = publicKeyParameters.DigestParamSet;
        }