@landwatersun

Научно-образовательный IT-форум при КНИТУ-КАИ

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Научно-образовательный IT-форум при КНИТУ-КАИ » Задачи и вопросы » [+] Верификация сертификата X.509


[+] Верификация сертификата X.509

Сообщений 21 страница 25 из 25

21

Может быть так инициализируется ключ:

X509Certificate2 certCur2 = new X509Certificate2(X509Certificate2.CreateFromCertFile(textBox1.Text));
rsa = certCur2.PublicKey.Key as RSACryptoServiceProvider;

22

Итак, давайте под итожим. Что мы имеем?

Первое. Генерируем сертификат с помощью кода:

using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Parameters;

...

        private void button1_Click(object sender, EventArgs e)
        {
            var KeyGenerate = new RsaKeyPairGenerator();
            KeyGenerate.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
            AsymmetricCipherKeyPair kp = KeyGenerate.GenerateKeyPair();
            var gen = new X509V3CertificateGenerator();
            var certName = new X509Name("CN=CA");
            var serialNo = new BigInteger("1", 10);
            gen.SetSerialNumber(serialNo);
            gen.SetSubjectDN(certName);
            gen.SetIssuerDN(certName);
            gen.SetNotAfter(DateTime.Now.AddYears(100));
            gen.SetNotBefore(DateTime.Now);
            gen.SetSignatureAlgorithm("SHA1WITHRSA");
            gen.SetPublicKey(kp.Public);
            var myCert = gen.Generate(kp.Private);
            byte[] result = DotNetUtilities.ToX509Certificate(myCert).Export(X509ContentType.Cert);
            FileStream fs = new FileStream(textBox1.Text + ".crt", FileMode.Create);
            fs.Write(result, 0, result.Length);           
            fs.Flush();
            fs.Close();
            MessageBox.Show("Сертификат создан!");                   
        }


Второе. Диляра упорно пытается заставить работать код, который пытается вытащить открытый ключ из самоподписанного сертификата, выдав его за сертификат второго уровня. Далее, проведя инициализацию объекта типа RSACryptoServiceProvider, проверить хеши посредством метода VerifyHash. Слова словами, но представляю реализацию данной идеи в виде следующего кода:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography.X509Certificates;
using Crypto = System.Security.Cryptography;
using System.Security.Permissions;
using System.IO;
using bcrypto = Org.BouncyCastle.X509;
using System.Xml;

...

        private void button2_Click(object sender, EventArgs e)
        {
            Stream certFile = new FileStream(textBox1.Text, FileMode.Open);
            bcrypto.X509CertificateParser cert_parser = new bcrypto.X509CertificateParser();
            bcrypto.X509Certificate cert = cert_parser.ReadCertificate(certFile);           
            Crypto.SHA1Managed hash_sha1 = new Crypto.SHA1Managed();
            byte[] hash_bytes = hash_sha1.ComputeHash(cert.GetTbsCertificate());
            certFile.Close();
            Crypto.X509Certificates.X509Certificate2 certCur = new X509Certificate2(X509Certificate2.CreateFromCertFile(textBox1.Text));
            Crypto.RSACryptoServiceProvider rsa = new Crypto.RSACryptoServiceProvider();
            //получаем открытый ключ
            rsa = certCur.PublicKey.Key as Crypto.RSACryptoServiceProvider;
            if (rsa.VerifyHash(hash_bytes, cert.SigAlgOid, cert.GetSignature()))
                MessageBox.Show("Сертификат прошел верификацию.");               
            else
                MessageBox.Show("Сертификат не прошел верификацию.");           
        }


После запуска программы имеем сообщение:

http://cs621319.vk.me/v621319045/14a30/JIjfhtYe_eQ.jpg

Далее думайте сами, решайте сами! :)

23

Основная причина, по которой данный код неработоспособен, на мой взгляд, в том, что мы применяем неверный способ извлечения открытого ключа. У самоподписанного сертификата мы извлекаем открытый ключ так, если бы мы работали с сертификатом второго уровня.

Crypto.X509Certificates.X509Certificate2 certCur = new X509Certificate2(X509Certificate2.CreateFromCertFile(textBox1.Text));
Crypto.RSACryptoServiceProvider rsa = new Crypto.RSACryptoServiceProvider();
//получаем открытый ключ
rsa = certCur.PublicKey.Key as Crypto.RSACryptoServiceProvider;

24

http://forumfiles.ru/files/000c/4b/84/26892.jpg

Рабочий код и решение задачи:

using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Parameters;
using bcrypto = Org.BouncyCastle.X509;
using Crypto = System.Security.Cryptography;

namespace Cert
{
    class Program
    {
        static void Main(string[] args)
        {
            var KeyGenerate = new RsaKeyPairGenerator();
            KeyGenerate.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
            AsymmetricCipherKeyPair kp = KeyGenerate.GenerateKeyPair();
            var gen = new X509V3CertificateGenerator();
            var certName = new X509Name("CN=CA");
            var serialNo = new BigInteger("1", 10);
            gen.SetSerialNumber(serialNo);
            gen.SetSubjectDN(certName);
            gen.SetIssuerDN(certName);
            gen.SetNotAfter(DateTime.Now.AddYears(100));
            gen.SetNotBefore(DateTime.Now);
            gen.SetSignatureAlgorithm("SHA1WITHRSA");
            gen.SetPublicKey(kp.Public);
            var myCert = gen.Generate(kp.Private);
            byte[] result = DotNetUtilities.ToX509Certificate(myCert).Export(X509ContentType.Cert);
            FileStream fs = new FileStream("Cert.crt", FileMode.Create);
            fs.Write(result, 0, result.Length);
            fs.Flush();
            fs.Close();

            Stream certFile = new FileStream("Cert.crt", FileMode.Open);
            bcrypto.X509CertificateParser cert_parser = new bcrypto.X509CertificateParser();
            bcrypto.X509Certificate cert = cert_parser.ReadCertificate(certFile);           
            Crypto.SHA1Managed hash_sha1 = new Crypto.SHA1Managed();
            byte[] hash_bytes = hash_sha1.ComputeHash(cert.GetTbsCertificate());
            certFile.Close();
            Crypto.X509Certificates.X509Certificate2 certCur = new X509Certificate2(X509Certificate2.CreateFromCertFile("Cert.crt"));
            Crypto.RSACryptoServiceProvider rsa = new Crypto.RSACryptoServiceProvider();
            //получаем открытый ключ
            rsa = certCur.PublicKey.Key as Crypto.RSACryptoServiceProvider;
            if (rsa.VerifyHash(hash_bytes, cert.SigAlgOid, cert.GetSignature()))
                Console.WriteLine("Успешно.");
            else Console.WriteLine("Не успешно.");
        }
    }
}


Рабочий проект с указанным выше кодом можно скачать по ссылке

25

Для интереса/самопроверки попробуйте использовать алгоритм хеширования SHA256 вместо SHA1.


Вы здесь » Научно-образовательный IT-форум при КНИТУ-КАИ » Задачи и вопросы » [+] Верификация сертификата X.509