OpenSSL ile Kendi Kendine İmzalı Sertifika Oluşturma: Eksiksiz Master Rehberi

Kutay Utku
13 dk okuma

Dijital dünyada güven, iletişimin temelidir. Bir web sitesini ziyaret ettiğinizde, sunucuya bağlandığınızda veya API’ınıza istek gönderdiğinizde, karşı tarafın gerçekten kim olduğunu nasıl bilirsiniz? İşte bu noktada dijital sertifikalar devreye giriyor. Bu kapsamlı rehberde, OpenSSL kullanarak kendi kendine imzalı sertifikaları nasıl oluşturacağınızı, yöneteceğinizi ve güvenliğini nasıl sağlayacağınızı derinlemesine öğreneceksiniz.

Bölüm 1: Temel Kavramlar – Sertifika Nedir ve Nasıl Çalışır?

1.1 Dijital Sertifikanın Anatomisi

Bir dijital sertifika, temelde şu bileşenlerden oluşur:

  1. Genel Anahtar (Public Key): Herkesle paylaşılan şifreleme anahtarı
  2. Özel Anahtar (Private Key): Sadece sahibinde bulunan, gizli tutulan anahtar
  3. Konu Bilgileri (Subject): Sertifika sahibinin kimlik bilgileri
  4. İmza (Signature): Sertifika Yetkilisi (CA) tarafından atılan dijital imza
  5. Geçerlilik Süresi: Sertifikanın geçerli olduğu zaman aralığı

1.2 Asimetrik Şifreleme ve Sertifikalar

RSA Algoritması matematiksel olarak şöyle çalışır:

  • İki büyük asal sayının çarpımından oluşan bir modül (n)
  • Genel anahtar: (e, n) çifti
  • Özel anahtar: (d, n) çifti
  • Şifreleme: ciphertext = plaintext^e mod n
  • Deşifreleme: plaintext = ciphertext^d mod n

2048-bit RSA anahtarı yaklaşık 617 ondalık basamak uzunluğunda bir sayıdır. Bugünün teknolojisiyle kırılması pratikte imkansızdır.

Bölüm 2: OpenSSL Komutlarının Derinlemesine İncelenmesi

2.1 req Komutu: Sertifika İsteklerinin Kalbi

openssl req komutu PKCS#10 standardını uygular. Detaylı kullanım:

# Temel CSR oluşturma
openssl req -new -newkey rsa:2048 -keyout example.key -out example.csr

# Detaylı parametrelerle CSR oluşturma
openssl req -new \
  -newkey rsa:4096 \
  -keyout server.key \
  -out server.csr \
  -sha256 \
  -days 365 \
  -subj "/C=US/ST=California/L=San Francisco/O=Example Inc/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.com" \
  -addext "keyUsage=digitalSignature,keyEncipherment" \
  -addext "extendedKeyUsage=serverAuth"

Önemli Parametreler:

  • -sha256: SHA-256 hash algoritması kullan (SHA-1 artık güvenli değil)
  • -addext: X.509 v3 uzantıları ekleme
  • -config: Özel konfigürasyon dosyası belirtme

2.2 x509 Komutu: Sertifika İşlemlerinin İsviçre Çakısı

# Sertifika detaylarını görüntüleme
openssl x509 -in certificate.crt -text -noout

# Sertifika doğrulama
openssl verify -CAfile ca-bundle.crt certificate.crt

# Sertifika format dönüşümü (PEM to DER)
openssl x509 -in certificate.pem -outform DER -out certificate.der

# Sertifika seri numarasını görüntüleme
openssl x509 -in certificate.crt -serial -noout

# Sertifika parmak izi (fingerprint)
openssl x509 -in certificate.crt -fingerprint -noout

2.3 RSA Anahtar Üretimi ve Yönetimi

# 4096-bit RSA anahtarı oluşturma
openssl genrsa -out private.key 4096

# Anahtarı parola ile koruma
openssl genrsa -aes256 -out protected.key 2048

# Anahtar şifresini kaldırma
openssl rsa -in encrypted.key -out decrypted.key

# Genel anahtarı özel anahtardan çıkarma
openssl rsa -in private.key -pubout -out public.key

Anahtar Güvenliği İçin En İyi Uygulamalar:

  1. Production ortamlarında minimum 2048-bit, tercihen 4096-bit kullanın
  2. Özel anahtarları asla şifresiz saklamayın
  3. Anahtarları düzenli olarak rotate edin (yılda bir)
  4. Anahtarları versiyon kontrol sistemine eklemeyin

Bölüm 3: Kendi Sertifika Yetkilinizi (CA) Kurma

3.1 Kök CA (Root Certificate Authority) Oluşturma

# 1. Kök CA için özel anahtar oluşturma
openssl genrsa -aes256 -out rootCA.key 4096

# 2. Kök CA sertifikası oluşturma
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 7300 -out rootCA.crt \
  -subj "/C=TR/ST=Istanbul/O=My Root CA/CN=My Root CA"

# 3. Sertifika veritabanı dosyalarını oluşturma
touch index.txt
echo 1000 > serial

# Konfigürasyon dosyası (openssl.cnf)
cat > openssl.cnf << 'EOF'
[ ca ]
default_ca = CA_default

[ CA_default ]
dir               = .
certs             = $dir/certs
crl_dir           = $dir/crl
database          = $dir/index.txt
new_certs_dir     = $dir/newcerts
certificate       = $dir/rootCA.crt
serial            = $dir/serial
crlnumber         = $dir/crlnumber
crl               = $dir/crl.pem
private_key       = $dir/rootCA.key
RANDFILE          = $dir/.rand

default_days      = 365
default_crl_days  = 30
default_md        = sha256

policy            = policy_strict

[ policy_strict ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
default_bits        = 2048
default_keyfile     = server.key
distinguished_name  = req_distinguished_name
req_extensions      = req_ext

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = TR
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Istanbul

localityName                    = Locality Name (eg, city)
localityName_default            = Istanbul

organizationName                = Organization Name (eg, company)
organizationName_default        = My Company

commonName                      = Common Name (e.g. server FQDN or YOUR name)
commonName_max                  = 64

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1   = example.com
DNS.2   = www.example.com
IP.1    = 192.168.1.1
EOF

3.2 Ara CA (Intermediate CA) Oluşturma

# 1. Ara CA için özel anahtar
openssl genrsa -aes256 -out intermediateCA.key 4096

# 2. CSR oluşturma
openssl req -new -key intermediateCA.key -out intermediateCA.csr \
  -subj "/C=TR/ST=Istanbul/O=My Intermediate CA/CN=My Intermediate CA"

# 3. Kök CA ile imzalama
openssl ca -config openssl.cnf -extensions v3_intermediate_ca \
  -days 3650 -notext -md sha256 \
  -in intermediateCA.csr -out intermediateCA.crt

# 4. Sertifika zinciri oluşturma
cat intermediateCA.crt rootCA.crt > ca-chain.crt

Bölüm 4: Farklı Senaryolar İçin Sertifika Oluşturma

4.1 Web Sunucusu İçin SSL/TLS Sertifikası

# 1. Özel anahtar oluşturma
openssl genrsa -out webserver.key 2048

# 2. CSR oluşturma
openssl req -new -key webserver.key -out webserver.csr \
  -subj "/C=TR/ST=Istanbul/L=Istanbul/O=My Company/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.com,DNS:api.example.com" \
  -addext "keyUsage=digitalSignature,keyEncipherment" \
  -addext "extendedKeyUsage=serverAuth"

# 3. CA ile imzalama
openssl x509 -req -in webserver.csr \
  -CA intermediateCA.crt -CAkey intermediateCA.key -CAcreateserial \
  -out webserver.crt -days 365 -sha256 \
  -extfile <(printf "subjectAltName=DNS:example.com,DNS:www.example.com\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth")

4.2 İstemci Kimlik Doğrulama Sertifikası

# 1. İstemci anahtarı
openssl genrsa -out client.key 2048

# 2. İstemci CSR
openssl req -new -key client.key -out client.csr \
  -subj "/C=TR/ST=Istanbul/O=My Company/CN=client@example.com" \
  -addext "extendedKeyUsage=clientAuth"

# 3. İmzalama
openssl x509 -req -in client.csr \
  -CA intermediateCA.crt -CAkey intermediateCA.key -CAcreateserial \
  -out client.crt -days 365 -sha256 \
  -extfile <(printf "extendedKeyUsage=clientAuth")

4.3 Kod İmzalama Sertifikası

openssl req -newkey rsa:2048 -nodes -keyout codesigning.key \
  -out codesigning.csr \
  -subj "/C=TR/O=My Software Company/CN=Code Signing Certificate" \
  -addext "keyUsage=digitalSignature" \
  -addext "extendedKeyUsage=codeSigning"

4.4 E-posta Sertifikası (S/MIME)

openssl req -newkey rsa:2048 -nodes -keyout email.key \
  -out email.csr \
  -subj "/C=TR/CN=user@example.com/emailAddress=user@example.com" \
  -addext "keyUsage=digitalSignature,keyEncipherment" \
  -addext "extendedKeyUsage=emailProtection"

Bölüm 5: Gelişmiş Konfigürasyon ve Optimizasyon

5.1 OpenSSL Konfigürasyon Dosyası Örneği

# advanced_ssl.cnf
[ req ]
default_bits        = 2048
default_keyfile     = server.key
distinguished_name  = req_distinguished_name
req_extensions      = v3_req
prompt              = no
default_md          = sha256
string_mask         = utf8only

[ req_distinguished_name ]
countryName         = TR
stateOrProvinceName = Istanbul
localityName        = Istanbul
organizationName    = My Organization
commonName          = example.com

[ v3_req ]
basicConstraints        = CA:FALSE
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage        = serverAuth, clientAuth
subjectAltName          = @alt_names
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer:always

[ v3_ca ]
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer:always
basicConstraints        = critical, CA:true
keyUsage                = critical, digitalSignature, cRLSign, keyCertSign

[ alt_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = api.example.com
IP.1  = 192.168.1.100
IP.2  = 10.0.0.1

5.2 Sertifika İmza İsteklerini Otomatikleştirme

#!/bin/bash
# generate_cert.sh - Otomatik sertifika oluşturma scripti

set -e

DOMAIN="${1:-example.com}"
DAYS="${2:-365}"
KEY_SIZE="${3:-2048}"
ALT_NAMES="${4:-DNS:${DOMAIN},DNS:www.${DOMAIN}}"

# 1. Özel anahtar oluştur
openssl genrsa -out "${DOMAIN}.key" "${KEY_SIZE}"

# 2. Konfigürasyon dosyası oluştur
cat > "${DOMAIN}.cnf" << EOF
[ req ]
default_bits = ${KEY_SIZE}
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = TR
ST = Istanbul
L = Istanbul
O = My Organization
CN = ${DOMAIN}

[ req_ext ]
subjectAltName = ${ALT_NAMES}
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
EOF

# 3. CSR oluştur
openssl req -new -key "${DOMAIN}.key" -out "${DOMAIN}.csr" -config "${DOMAIN}.cnf"

# 4. Sertifikayı imzala (kendi kendine imzalı)
openssl x509 -req -in "${DOMAIN}.csr" \
  -signkey "${DOMAIN}.key" \
  -out "${DOMAIN}.crt" \
  -days "${DAYS}" \
  -extfile "${DOMAIN}.cnf" \
  -extensions req_ext

# 5. Sertifika bilgilerini görüntüle
echo "=== Sertifika Bilgileri ==="
openssl x509 -in "${DOMAIN}.crt" -text -noout | grep -A 1 "Subject:\|Validity\|Subject Alternative Name"

# 6. Dosyaları güvenli hale getir
chmod 600 "${DOMAIN}.key"
chmod 644 "${DOMAIN}.crt"

echo "Sertifika başarıyla oluşturuldu:"
echo "  Key: ${DOMAIN}.key"
echo "  CSR: ${DOMAIN}.csr"
echo "  CRT: ${DOMAIN}.crt"

Bölüm 6: Sertifika Doğrulama ve Hata Ayıklama

6.1 Sertifika Zinciri Doğrulama

# Sertifika zincirini doğrula
openssl verify -CAfile rootCA.crt -untrusted intermediateCA.crt server.crt

# Sertifika zincirini görüntüle
openssl crl2pkcs7 -nocrl -certfile server.crt | openssl pkcs7 -print_certs -text -noout

# OCSP (Online Certificate Status Protocol) kontrolü
openssl ocsp -issuer intermediateCA.crt -cert server.crt \
  -url http://ocsp.example.com -resp_text

6.2 Sertifika Uyumluluk Testleri

# SSL/TLS el sıkışması testi
openssl s_client -connect example.com:443 -showcerts

# Sertifika süresi kontrolü
openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -dates

# Kullanılan şifre paketlerini listele
openssl s_client -connect example.com:443 -cipher 'ALL:eNULL' 2>/dev/null | \
  grep "Cipher Suite"

6.3 Yaygın Hatalar ve Çözümleri

Hata 1: “self signed certificate”

# Çözüm: CA sertifikasını güvenilir depolara ekleyin
# Linux
sudo cp rootCA.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

# macOS
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain rootCA.crt

Hata 2: “certificate has expired”

# Çözüm: Yeni sertifika oluşturun
openssl x509 -in expired.crt -noout -enddate
# Geçerlilik süresini artırın
openssl x509 -in old.crt -signkey old.key -out new.crt -days 730

Hata 3: “subject alternative name missing”

# Çözüm: SAN uzantısı ekleyin
openssl x509 -req -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 365 \
  -extfile <(printf "subjectAltName=DNS:example.com")

Bölüm 7: Güvenlik En İyi Uygulamaları

7.1 Anahtar ve Sertifika Yönetimi

  1. Anahtar Rotasyonu:
  • Production anahtarlarını yılda bir değiştirin
  • Compromise şüphesinde hemen rotate edin
  • Key rotation’ı otomatikleştirin
  1. Anahtar Depolama:
   # Özel anahtarları şifreleyerek saklayın
   openssl rsa -aes256 -in private.key -out encrypted.key

   # Hardware Security Module (HSM) kullanın
   # Veya AWS KMS, Google Cloud KMS gibi managed servisler
  1. Sertifika Yaşam Döngüsü Yönetimi:
  • Otomatik yenileme sistemleri kurun
  • Süre dolmadan 30 gün önce uyarı alın
  • CRL (Certificate Revocation List) veya OCSP kullanın

7.2 Kriptografik Güçlendirme

# Güçlü şifreleme algoritmaları kullanın
openssl req -newkey rsa:4096 -sha384 -keyout server.key -out server.csr

# ECC (Elliptic Curve Cryptography) anahtarları için
openssl ecparam -genkey -name secp384r1 -out ecc.key
openssl req -new -key ecc.key -out ecc.csr -sha384

# Perfect Forward Secrecy (PFS) için Diffie-Hellman parametreleri
openssl dhparam -out dhparam.pem 4096

7.3 Sertifika Politikası ve Uyumluluk

  1. Certificate Policy (CP) ve Certification Practice Statement (CPS) oluşturun
  2. Baseline Requirements‘a uyun
  3. Audit log tutun:
   # Tüm sertifika işlemlerini loglayın
   openssl ca -config openssl.cnf -in request.csr -out cert.crt \
     -batch -notext -md sha256 \
     2>&1 | tee -a /var/log/ssl/ca_operations.log

Bölüm 8: Modern Geliştirme ve Dağıtım Senaryoları

8.1 Container Ortamları İçin Sertifika Yönetimi

# Dockerfile örneği
FROM nginx:alpine

# Sertifikaları container'a kopyala
COPY ssl/ /etc/nginx/ssl/

# Özel anahtarı güvenli hale getir
RUN chmod 600 /etc/nginx/ssl/server.key && \
    chown root:root /etc/nginx/ssl/server.key

# Nginx konfigürasyonu
COPY nginx.conf /etc/nginx/nginx.conf

# Health check ile sertifika süresi kontrolü
HEALTHCHECK --interval=1h --timeout=3s --start-period=5s --retries=3 \
  CMD openssl x509 -checkend 2592000 -noout -in /etc/nginx/ssl/server.crt || exit 1

8.2 Kubernetes Secret Olarak Sertifika

# k8s-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
  namespace: default
type: kubernetes.io/tls
data:
  tls.crt: $(cat server.crt | base64 | tr -d '\n')
  tls.key: $(cat server.key | base64 | tr -d '\n')
# Cert-Manager ile otomatik sertifika yönetimi
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com
  namespace: default
spec:
  secretName: example-com-tls
  duration: 2160h # 90 days
  renewBefore: 360h # 15 days
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: example.com
  dnsNames:
  - example.com
  - www.example.com

8.3 DevOps Pipeline Entegrasyonu

# .gitlab-ci.yml örneği
stages:
  - security
  - build
  - deploy

generate_certificate:
  stage: security
  script:
    - |
      openssl req -newkey rsa:2048 -nodes -keyout server.key \
        -out server.csr -subj "/C=TR/CN=${CI_PROJECT_NAME}" \
        -addext "subjectAltName=DNS:${CI_PROJECT_NAME}.example.com"

      # CA'dan imzala (simülasyon)
      openssl x509 -req -in server.csr -signkey server.key \
        -out server.crt -days 30

      # HashiCorp Vault'tan gerçek sertifika al
      # vault write pki/issue/example-dot-com common_name="${CI_PROJECT_NAME}.example.com"

  artifacts:
    paths:
      - server.crt
      - server.key
    expire_in: 1 hour

Bölüm 9: Monitoring ve Observability

9.1 Sertifika Süresi İzleme

# cert_monitor.py
import ssl
import socket
import datetime
import smtplib
from email.mime.text import MIMEText

def check_certificate(hostname, port=443):
    context = ssl.create_default_context()
    with socket.create_connection((hostname, port)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            cert = ssock.getpeercert()

    expires = datetime.datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
    days_remaining = (expires - datetime.datetime.now()).days

    if days_remaining < 30:
        send_alert(hostname, days_remaining)

    return days_remaining

def send_alert(hostname, days):
    msg = MIMEText(f"Sertifika {hostname} için {days} gün sonra dolacak!")
    msg['Subject'] = f'SSL Sertifika Uyarısı: {hostname}'
    msg['From'] = 'alerts@example.com'
    msg['To'] = 'admin@example.com'

    with smtplib.SMTP('localhost') as server:
        server.send_message(msg)

9.2 Prometheus ve Grafana ile Monitoring

# prometheus-cert-exporter.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cert-exporter
spec:
  template:
    spec:
      containers:
      - name: cert-exporter
        image: ribbybibby/ssl-cert-exporter:latest
        args:
        - --web.listen-address=:9117
        - --secrets.label-selector=app
        - --secrets.insecure-skip-verify=true
        ports:
        - containerPort: 9117
# Grafana için PromQL sorguları
# Kalan gün sayısı
ssl_cert_not_after - time()

# 30 günden az kalan sertifikalar
ssl_cert_not_after - time() < 30 * 24 * 3600

# Son 7 günde oluşturulan sertifikalar
ssl_cert_not_before > time() - 7 * 24 * 3600

Bölüm 10: Gelecek Trendler ve Sonuç

10.1 Sertifika Teknolojisindeki Gelişmeler

  1. ACME Protokolü ve Otomatikleşme: Let’s Encrypt gibi servisler
  2. Post-Quantum Cryptography: Kuantum bilgisayarlara dayanıklı algoritmalar
  3. Certificate Transparency: Sertifika şeffaflığı ve log kayıtları
  4. Short-lived Certificates: Dakikalık ömürlü sertifikalar

10.2 Son Tavsiyeler

  1. Asla production’da kendi kendine imzalı sertifika kullanmayın
  2. Sertifika yaşam döngüsünü otomatikleştirin
  3. Güvenlik denetimlerini düzenli yapın
  4. Ekip üyelerini eğitin ve farkındalık yaratın
  5. Disaster recovery planınızda sertifikaları unutmayın

10.3 Kaynaklar ve Devam Edecek Öğrenme

  • OpenSSL Documentation: https://www.openssl.org/docs/
  • RFC 5280: Internet X.509 Public Key Infrastructure
  • Mozilla SSL Configuration Generator: https://ssl-config.mozilla.org/
  • SSL Labs Test: https://www.ssllabs.com/ssltest/

Ek: Komut Referans Çizelgesi

AmaçKomutAçıklama
Özel anahtar oluşturopenssl genrsa -out key.pem 20482048-bit RSA anahtarı
CSR oluşturopenssl req -new -key key.pem -out req.csrSertifika İmza İsteği
Kendi kendine imzalı sertifikaopenssl req -x509 -key key.pem -in req.csr -out cert.pemSelf-signed cert
Sertifika görüntüleopenssl x509 -in cert.pem -text -nooutDetaylı bilgi
Sertifika doğrulaopenssl verify -CAfile ca.pem cert.pemDoğrulama
PFX/P12 oluşturopenssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pemWindows formatı
Anahtar şifreleopenssl rsa -aes256 -in key.pem -out encrypted.keyAES-256 şifreleme

Bu kapsamlı rehber, OpenSSL ile kendi kendine imzalı sertifikaları profesyonel seviyede anlamanız ve uygulamanız için gerekli tüm bilgileri içermektedir. Unutmayın: Güvenlik bir süreçtir, ürün değil. Düzenli güncelleme, izleme ve iyileştirme ile sistemlerinizi güvende tutun.

Güvenli kodlama, güvenli sistemler demektir.

💬 Yorum Bırak