analitics

Pages

Showing posts with label cryptography. Show all posts
Showing posts with label cryptography. Show all posts

Thursday, January 8, 2026

Python Qt6 : Check certificate of url.

Today, I will show this python script to check the certificate of url.
import sys
import ssl
import socket
from datetime import datetime

from cryptography import x509
from cryptography.hazmat.backends import default_backend

from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QLabel,
    QLineEdit, QPushButton, QTextEdit
)

def fetch_certificate_raw(hostname):
    """
    Connects to the server and retrieves the certificate in DER format.
    Also returns a validation status message.
    """

    # Create a default SSL context (validates certificates)
    context = ssl.create_default_context()

    try:
        # First attempt: strict validation
        with socket.create_connection((hostname, 443), timeout=5) as sock:
            with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                der_cert = ssock.getpeercert(binary_form=True)
                return der_cert, "Certificate is VALID"

    except ssl.SSLError as e:
        # Certificate is invalid → try to retrieve it anyway
        try:
            unverified_context = ssl._create_unverified_context()
            with socket.create_connection((hostname, 443), timeout=5) as sock:
                with unverified_context.wrap_socket(sock, server_hostname=hostname) as ssock:
                    der_cert = ssock.getpeercert(binary_form=True)
                    return der_cert, f"Certificate is INVALID: {str(e)}"
        except Exception:
            return None, f"Could not retrieve certificate: {str(e)}"

    except Exception as e:
        return None, f"Connection error: {str(e)}"

def parse_certificate(der_cert):
    """
    Converts a DER-encoded certificate into a cryptography.x509 object.
    """
    return x509.load_der_x509_certificate(der_cert, default_backend())

class CertViewer(QWidget):
    """
    Main GUI window for the HTTPS certificate viewer.
    """
    def __init__(self):
        super().__init__()

        self.setWindowTitle("HTTPS Certificate Checker")
        self.setGeometry(200, 200, 700, 600)

        layout = QVBoxLayout()

        # Input label + text field
        layout.addWidget(QLabel("Enter URL (example: example.com):"))
        self.input = QLineEdit()
        layout.addWidget(self.input)

        # Button to trigger certificate check
        self.button = QPushButton("Check Certificate")
        self.button.clicked.connect(self.check_certificate)
        layout.addWidget(self.button)

        # Output text box
        self.output = QTextEdit()
        self.output.setReadOnly(True)
        layout.addWidget(self.output)

        self.setLayout(layout)

    def check_certificate(self):
        """
        Triggered when the user presses the button.
        Retrieves and displays certificate information.
        """

        hostname = self.input.text().strip()

        # Clean URL (remove http://, https://, and paths)
        for prefix in ("https://", "http://"):
            if hostname.startswith(prefix):
                hostname = hostname[len(prefix):]

        hostname = hostname.split("/")[0]

        # Fetch certificate
        der_cert, status = fetch_certificate_raw(hostname)

        if der_cert is None:
            self.output.setText(status)
            return

        # Parse certificate
        cert = parse_certificate(der_cert)

        # Build output text
        text = f"=== CERTIFICATE STATUS ===\n{status}\n\n"
        text += "=== CERTIFICATE DETAILS ===\n\n"

        text += f"Subject:\n{cert.subject}\n\n"
        text += f"Issuer:\n{cert.issuer}\n\n"
        text += f"Serial Number: {cert.serial_number}\n\n"
        text += f"Version: {cert.version}\n\n"
        text += f"Valid From: {cert.not_valid_before}\n"
        text += f"Valid To:   {cert.not_valid_after}\n\n"

        # Check expiration
        if cert.not_valid_after < datetime.utcnow():
            text += f"⚠ Certificate EXPIRED on: {cert.not_valid_after}\n\n"

        # Subject Alternative Names (SAN)
        try:
            san = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName)
            text += f"Subject Alternative Names:\n{san.value}\n\n"
        except Exception:
            text += "Subject Alternative Names: (none)\n\n"

        self.output.setText(text)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    viewer = CertViewer()
    viewer.show()
    sys.exit(app.exec())

Sunday, January 5, 2020

Python 3.7.5 : Testing cryptography python package - part 001.

There are many python packets that present themselves as useful encryption and decryption solutions. I recommend before you test them, use them and spend time with them to focus on the correct study of cryptology because many disadvantages and problems can arise in the correct and safe writing of the source code.
Today I will show you a simple example with cryptography python package.
Let's install this with pip3 tool:
[mythcat@desk projects]$ pip3 install cryptography --user
You can read more about this python package on the documentation website.
Let's try a simple method of encryption and decryption.
I will show you how to solve this issue with the class cryptography.hazmat.primitives.ciphers.aead.AESGCM:
The AES-GCM construction is composed of the AES block cipher utilizing Galois Counter Mode (GCM).
The GCM (Galois Counter Mode) is a mode of operation for block ciphers.
An AEAD (authenticated encryption with additional data) mode is a type
of block cipher mode that simultaneously encrypts the message as well as authenticating it.

The Value of AESGCM key must be 128, 192, or 256 bits, see the size of the key:
[mythcat@desk projects]$ python3
Python 3.7.5 (default, Dec 15 2019, 17:54:26) 
[GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> from cryptography.hazmat.primitives.ciphers.aead import AESGCM
>>> aad = None
>>> key = 'catafestcatafestcatafestcatafest'
>>> aesgcm = AESGCM(key.encode('utf-8'))
>>> nonce = '12345678'
>>> data_binary = b'Hello world!'
>>> 
>>> cipher_text = aesgcm.encrypt(nonce.encode('utf-8'), data_binary, aad)
>>> print(cipher_text)
b'0\xab\xd2!mXe\xc3/\xdb\x15\xcaoT\x0f\x1d\xbb&\xc4\x92\xdf\\ZTMD\xa2\x9f'
>>> data_text = aesgcm.decrypt(nonce.encode('utf-8'), cipher_text, aad)
>>> print(data_text)
b'Hello world!'