Клиент-серверный TLS с настраиваемым ЦС

Я написал небольшую тестовую программу, которая создает

  1. настраиваемый самозаверяющий сертификат ЦС № 1
  2. создает сертификат сервера № 2, выданный этим ЦС — корневой сертификат № 1
  3. создает сервер с сертификатом №2
  4. создает клиент с RootCA, указывающим на сертификат № 1
  5. клиент пытается подключиться к серверу и получает ошибку:

Получите «https://localhost:2000»: x509: сертификат, подписанный неизвестным органом (возможно, из-за «x509: ошибка проверки Ed25519» при попытке проверить сертификат кандидата в центр «test-ca»)

Я понимаю, что тому есть десятки примеров. Я думал, что следую за ними довольно близко, и все же я здесь. Я показываю здесь только самые актуальные структуры, но полный текст программы можно найти здесь:

    ...
    templateCA := &x509.Certificate{
        Subject: pkix.Name{
            CommonName:   "test-ca",
            Organization: []string{"test ca"},
            Country:      []string{"USA"},
            Province:     []string{"NY"},
            Locality:     []string{"New York City"},
        },
        SerialNumber:          serialNumber,
        NotBefore:             time.Now(),
        NotAfter:              time.Now().AddDate(0, 0, 1),
        BasicConstraintsValid: true,
        IsCA:                  true,
        SubjectKeyId:          caSubjectKeyID[:],
        DNSNames:              []string{"test-ca"},
        KeyUsage:              x509.KeyUsageCertSign
    }
    ...
    certBytes, _ := x509.CreateCertificate(rand.Reader, templateCA, templateCA, privKey.Public(), privKey)
    ...
    templateServer := &x509.Certificate{
        Subject: pkix.Name{
            CommonName:   "localhost",
            Organization: []string{"Server"},
            Country:      []string{"USA"},
            Province:     []string{"NY"},
            Locality:     []string{"New York City"},
        },
        SerialNumber:          serialNumber,
        NotBefore:             time.Now(),
        NotAfter:              time.Now().AddDate(0, 0, 1),
        BasicConstraintsValid: true,
        SubjectKeyId:          servSubjectKeyID[:],
        AuthorityKeyId:        caSubjectKeyID[:],
        DNSNames:              []string{"localhost"},
        IPAddresses:           []net.IP{{127, 0, 0, 1}},
        KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    }
    ...
    certBytes, _ = x509.CreateCertificate(rand.Reader, templateServer, caCert, privKey.Public(), privKey)
    ...
var (
    tlsMinVersion = uint16(tls.VersionTLS12)
    tlsMaxVersion = uint16(tls.VersionTLS13)
    cipherSuites  = []uint16{
        tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
        tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    }
    curvePreferences = []tls.CurveID{
        tls.X25519,
        tls.CurveP256,
        tls.CurveP384,
        tls.CurveP521,
    }
)
    ...
    tlsServerConfig := &tls.Config{
        Certificates:             []tls.Certificate{*tlsSrvCert},
        MinVersion:               tlsMinVersion,
        MaxVersion:               tlsMaxVersion,
        CurvePreferences:         curvePreferences,
        CipherSuites:             cipherSuites,
        PreferServerCipherSuites: true,
    }
    ...
    tlsClientConfig := &tls.Config{
        ServerName:               "localhost",
        RootCAs:                  x509.NewCertPool(),
        MinVersion:               tlsMinVersion,
        MaxVersion:               tlsMaxVersion,
        CurvePreferences:         curvePreferences,
        CipherSuites:             cipherSuites,
        PreferServerCipherSuites: true,
    }
    tlsClientConfig.RootCAs.AddCert(caCert)
    

Что я упускаю или делаю неправильно?

Немного изменил фрагменты кода, чтобы отразить последние, но это немного не помогло. Все еще получаю ту же ошибку. Пошли еще дальше: создали вручную набор практически идентичных сертификатов, отличающихся только ID-ами, серийными номерами и байтами ключей. Созданные вручную сертификаты работают, а сгенерированные - нет.

Valo 28.12.2020 03:35
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
0
1
521
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать закрытый ключ для расшифровки данных и для шифрования хешированных данных для создания цифровой подписи.

Вы можете использовать открытый ключ для шифрования данных и расшифровать цифровую подпись для ее проверки.

что вам нужно сделать здесь, это использовать одну пару ключей (открытый/закрытый ключ) для создания сертификата CA и использовать этот сертификат + ту же пару ключей для создания одного или нескольких сертификатов для вашего сервера (ов).

Если вы хотите использовать браузер / curl в качестве клиента, вам необходимо добавить сертификат CA в корневые хранилища ключей.

Спасибо за ответ. Это то, что я делаю здесь. Приведенные выше фрагменты могут немного вводить в заблуждение из-за одинаковых имен переменных ключей pub/priv, но если вы посмотрите на код, вы увидите, что значения разные: github.com/vmelamed/testServerClient/blob/ мастер/testtls/…

Valo 28.12.2020 18:14

здесь (github.com/vmelamed/testServerClient/blob/…) вы переназначаете новое значение privateKey. удалите строку 72 и используйте первую пару ключей в следующей строке 73

djoudat 28.12.2020 18:28

Да! Вы правы - теперь я это вижу! Это ошибка. Спасибо!

Valo 28.12.2020 19:34

Спасибо @djoudat за указание на мою ошибку. Я вставляю сюда исправленные фрагменты кода сверху. Надеюсь, они могут помочь кому-то, когда-нибудь.

...
templateCA := &x509.Certificate{
    Subject: pkix.Name{
        CommonName:   "test-ca",
        Organization: []string{"test ca"},
        Country:      []string{"USA"},
        Province:     []string{"NY"},
        Locality:     []string{"New York City"},
    },
    SerialNumber:          serialNumber,
    NotBefore:             time.Now(),
    NotAfter:              time.Now().AddDate(0, 0, 1),
    BasicConstraintsValid: true,
    IsCA:                  true,
    KeyUsage:              x509.KeyUsageCertSign
    DNSNames:              []string{"test-ca"},
}
...
certBytes, _ := x509.CreateCertificate(rand.Reader, templateCA, templateCA, privKeyCA.Public(), privKeyCA)
...
templateServer := &x509.Certificate{
    Subject: pkix.Name{
        CommonName:   "localhost",
        Organization: []string{"Server"},
        Country:      []string{"USA"},
        Province:     []string{"NY"},
        Locality:     []string{"New York City"},
    },
    SerialNumber:          serialNumber,
    NotBefore:             time.Now(),
    NotAfter:              time.Now().AddDate(0, 0, 1),
    BasicConstraintsValid: true,
    KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
    ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    DNSNames:              []string{"localhost"},
}
...
certBytes, _ = x509.CreateCertificate(rand.Reader, templateServer, caCert, privKeyServer.Public(), privKeyCA)
...
var (
    tlsMinVersion = uint16(tls.VersionTLS12)
    tlsMaxVersion = uint16(tls.VersionTLS13)
    cipherSuites  = []uint16{
        tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
        tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    }
    curvePreferences = []tls.CurveID{
        tls.X25519,
        tls.CurveP256,
        tls.CurveP384,
        tls.CurveP521,
    }
)
...
tlsServerConfig := &tls.Config{
    Certificates:             []tls.Certificate{*tlsSrvCert},
    MinVersion:               tlsMinVersion,
    MaxVersion:               tlsMaxVersion,
    CurvePreferences:         curvePreferences,
    CipherSuites:             cipherSuites,
    PreferServerCipherSuites: true,
}
...
tlsClientConfig := &tls.Config{
    ServerName:               "localhost",
    RootCAs:                  x509.NewCertPool(),
    MinVersion:               tlsMinVersion,
    MaxVersion:               tlsMaxVersion,
    CurvePreferences:         curvePreferences,
    CipherSuites:             cipherSuites,
    PreferServerCipherSuites: true,
}
tlsClientConfig.RootCAs.AddCert(caCert)

Другие вопросы по теме