Hash and Sign Text with Key Pairs

Hash and digitally sign text using public/private key pairs.


Hash Text (OpenSSL)

 1# SHA-256 hash
 2echo -n "Hello, World!" | openssl dgst -sha256
 3echo -n "Hello, World!" | openssl sha256
 4
 5# SHA-512 hash
 6echo -n "Hello, World!" | openssl dgst -sha512
 7
 8# Hash file
 9openssl dgst -sha256 file.txt
10
11# Output in hex
12openssl dgst -sha256 -hex file.txt
13
14# Output in binary
15openssl dgst -sha256 -binary file.txt > hash.bin

Sign with RSA

 1# Generate RSA key pair
 2openssl genrsa -out private.pem 4096
 3openssl rsa -in private.pem -pubout -out public.pem
 4
 5# Sign text file
 6echo "Hello, World!" > message.txt
 7openssl dgst -sha256 -sign private.pem -out signature.bin message.txt
 8
 9# Sign with base64 encoding
10openssl dgst -sha256 -sign private.pem message.txt | base64 > signature.b64
11
12# Verify signature
13openssl dgst -sha256 -verify public.pem -signature signature.bin message.txt
14# Output: Verified OK
15
16# Verify base64 signature
17base64 -d signature.b64 | openssl dgst -sha256 -verify public.pem -signature /dev/stdin message.txt

Sign with ECDSA

 1# Generate ECC key pair
 2openssl ecparam -name prime256v1 -genkey -noout -out private.pem
 3openssl ec -in private.pem -pubout -out public.pem
 4
 5# Sign text file
 6echo "Hello, World!" > message.txt
 7openssl dgst -sha256 -sign private.pem -out signature.bin message.txt
 8
 9# Verify signature
10openssl dgst -sha256 -verify public.pem -signature signature.bin message.txt
11# Output: Verified OK

Sign with Ed25519

 1# Generate Ed25519 key pair
 2openssl genpkey -algorithm Ed25519 -out private.pem
 3openssl pkey -in private.pem -pubout -out public.pem
 4
 5# Sign text file
 6echo "Hello, World!" > message.txt
 7openssl pkeyutl -sign -inkey private.pem -out signature.bin -rawin -in message.txt
 8
 9# Verify signature
10openssl pkeyutl -verify -pubin -inkey public.pem -sigfile signature.bin -rawin -in message.txt
11# Output: Signature Verified Successfully

Sign with SSH Keys

 1# Generate SSH key
 2ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
 3
 4# Sign file
 5ssh-keygen -Y sign -f ~/.ssh/id_ed25519 -n file message.txt
 6
 7# Creates message.txt.sig
 8
 9# Verify signature (need allowed_signers file)
10echo "user@host $(cat ~/.ssh/id_ed25519.pub)" > allowed_signers
11ssh-keygen -Y verify -f allowed_signers -I user@host -n file -s message.txt.sig < message.txt
12# Output: Good "file" signature for user@host with ED25519 key...

GPG/PGP Signing

 1# Sign file (detached signature)
 2gpg --detach-sign --armor message.txt
 3# Creates message.txt.asc
 4
 5# Sign file (clear-sign)
 6gpg --clear-sign message.txt
 7# Creates message.txt.asc with message included
 8
 9# Sign file (embedded signature)
10gpg --sign message.txt
11# Creates message.txt.gpg (binary)
12
13# Verify detached signature
14gpg --verify message.txt.asc message.txt
15
16# Verify clear-signed message
17gpg --verify message.txt.asc
18
19# Verify embedded signature (extracts message)
20gpg --decrypt message.txt.gpg

Python: Hash Text

 1import hashlib
 2
 3# SHA-256
 4text = "Hello, World!"
 5hash_obj = hashlib.sha256(text.encode())
 6print(hash_obj.hexdigest())
 7
 8# SHA-512
 9hash_obj = hashlib.sha512(text.encode())
10print(hash_obj.hexdigest())
11
12# BLAKE2
13hash_obj = hashlib.blake2b(text.encode())
14print(hash_obj.hexdigest())
15
16# Hash file
17def hash_file(filename):
18    sha256 = hashlib.sha256()
19    with open(filename, 'rb') as f:
20        for chunk in iter(lambda: f.read(4096), b''):
21            sha256.update(chunk)
22    return sha256.hexdigest()
23
24print(hash_file('message.txt'))

Python: Sign with RSA

 1from cryptography.hazmat.primitives import hashes, serialization
 2from cryptography.hazmat.primitives.asymmetric import rsa, padding
 3from cryptography.hazmat.backends import default_backend
 4
 5# Generate key pair
 6private_key = rsa.generate_private_key(
 7    public_exponent=65537,
 8    key_size=4096,
 9    backend=default_backend()
10)
11public_key = private_key.public_key()
12
13# Message to sign
14message = b"Hello, World!"
15
16# Sign message
17signature = private_key.sign(
18    message,
19    padding.PSS(
20        mgf=padding.MGF1(hashes.SHA256()),
21        salt_length=padding.PSS.MAX_LENGTH
22    ),
23    hashes.SHA256()
24)
25
26print(f"Signature: {signature.hex()}")
27
28# Verify signature
29try:
30    public_key.verify(
31        signature,
32        message,
33        padding.PSS(
34            mgf=padding.MGF1(hashes.SHA256()),
35            salt_length=padding.PSS.MAX_LENGTH
36        ),
37        hashes.SHA256()
38    )
39    print("Signature is valid!")
40except Exception as e:
41    print(f"Signature is invalid: {e}")

Python: Sign with ECDSA

 1from cryptography.hazmat.primitives import hashes, serialization
 2from cryptography.hazmat.primitives.asymmetric import ec
 3from cryptography.hazmat.backends import default_backend
 4
 5# Generate key pair
 6private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
 7public_key = private_key.public_key()
 8
 9# Message to sign
10message = b"Hello, World!"
11
12# Sign message
13signature = private_key.sign(
14    message,
15    ec.ECDSA(hashes.SHA256())
16)
17
18print(f"Signature: {signature.hex()}")
19
20# Verify signature
21try:
22    public_key.verify(
23        signature,
24        message,
25        ec.ECDSA(hashes.SHA256())
26    )
27    print("Signature is valid!")
28except Exception as e:
29    print(f"Signature is invalid: {e}")

Python: Sign with Ed25519

 1from cryptography.hazmat.primitives.asymmetric import ed25519
 2from cryptography.hazmat.primitives import serialization
 3
 4# Generate key pair
 5private_key = ed25519.Ed25519PrivateKey.generate()
 6public_key = private_key.public_key()
 7
 8# Message to sign
 9message = b"Hello, World!"
10
11# Sign message
12signature = private_key.sign(message)
13
14print(f"Signature: {signature.hex()}")
15
16# Verify signature
17try:
18    public_key.verify(signature, message)
19    print("Signature is valid!")
20except Exception as e:
21    print(f"Signature is invalid: {e}")

Complete Python Example

  1#!/usr/bin/env python3
  2"""
  3Digital signature example with multiple algorithms
  4"""
  5
  6from cryptography.hazmat.primitives import hashes, serialization
  7from cryptography.hazmat.primitives.asymmetric import rsa, ec, ed25519, padding
  8from cryptography.hazmat.backends import default_backend
  9import base64
 10
 11class Signer:
 12    def __init__(self, algorithm='rsa'):
 13        self.algorithm = algorithm
 14        self._generate_keys()
 15    
 16    def _generate_keys(self):
 17        if self.algorithm == 'rsa':
 18            self.private_key = rsa.generate_private_key(
 19                public_exponent=65537,
 20                key_size=4096,
 21                backend=default_backend()
 22            )
 23        elif self.algorithm == 'ecdsa':
 24            self.private_key = ec.generate_private_key(
 25                ec.SECP256R1(),
 26                default_backend()
 27            )
 28        elif self.algorithm == 'ed25519':
 29            self.private_key = ed25519.Ed25519PrivateKey.generate()
 30        else:
 31            raise ValueError(f"Unknown algorithm: {self.algorithm}")
 32        
 33        self.public_key = self.private_key.public_key()
 34    
 35    def sign(self, message: bytes) -> bytes:
 36        if self.algorithm == 'rsa':
 37            return self.private_key.sign(
 38                message,
 39                padding.PSS(
 40                    mgf=padding.MGF1(hashes.SHA256()),
 41                    salt_length=padding.PSS.MAX_LENGTH
 42                ),
 43                hashes.SHA256()
 44            )
 45        elif self.algorithm == 'ecdsa':
 46            return self.private_key.sign(
 47                message,
 48                ec.ECDSA(hashes.SHA256())
 49            )
 50        elif self.algorithm == 'ed25519':
 51            return self.private_key.sign(message)
 52    
 53    def verify(self, message: bytes, signature: bytes) -> bool:
 54        try:
 55            if self.algorithm == 'rsa':
 56                self.public_key.verify(
 57                    signature,
 58                    message,
 59                    padding.PSS(
 60                        mgf=padding.MGF1(hashes.SHA256()),
 61                        salt_length=padding.PSS.MAX_LENGTH
 62                    ),
 63                    hashes.SHA256()
 64                )
 65            elif self.algorithm == 'ecdsa':
 66                self.public_key.verify(
 67                    signature,
 68                    message,
 69                    ec.ECDSA(hashes.SHA256())
 70                )
 71            elif self.algorithm == 'ed25519':
 72                self.public_key.verify(signature, message)
 73            return True
 74        except Exception:
 75            return False
 76    
 77    def export_public_key(self) -> str:
 78        pem = self.public_key.public_bytes(
 79            encoding=serialization.Encoding.PEM,
 80            format=serialization.PublicFormat.SubjectPublicKeyInfo
 81        )
 82        return pem.decode()
 83
 84# Example usage
 85if __name__ == "__main__":
 86    message = b"Hello, World!"
 87    
 88    for algo in ['rsa', 'ecdsa', 'ed25519']:
 89        print(f"\n=== {algo.upper()} ===")
 90        signer = Signer(algo)
 91        
 92        # Sign
 93        signature = signer.sign(message)
 94        print(f"Signature: {base64.b64encode(signature).decode()[:64]}...")
 95        
 96        # Verify
 97        is_valid = signer.verify(message, signature)
 98        print(f"Valid: {is_valid}")
 99        
100        # Verify tampered message
101        tampered = b"Hello, World!!"
102        is_valid = signer.verify(tampered, signature)
103        print(f"Tampered valid: {is_valid}")

Signature Verification Flow


Related Snippets