CP-20200218

Cryptography Primitives Intermediate February 18, 2020

Back to All Tasks

Problem Statement

You are tasked with creating a simple digital signature system using SHA-256 as the hash function and RSA for signing. Your program should allow users to generate an RSA key pair, sign a message with their private key, and verify the signature using the corresponding public key. Ensure that your implementation correctly handles padding for the RSA encryption operation. Implement functions for generating keys, signing messages, and verifying signatures. Test your system by signing a sample text message and verifying the resulting signature.

Concepts

  • Hash Functions
  • Digital Signatures

Constraints

  • Use SHA-256 as the hashing algorithm
  • Utilize RSA with appropriate key size (e.g., 2048 bits)
  • Implement PKCS#1 v1.5 padding for RSA operations

Security Notes

  • Ensure that private keys are never exposed or logged
  • Verify the integrity of messages before accepting signatures
  • Consider the implications of using a fixed-size message digest in conjunction with RSA

Solutions

Java Solution

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

public class DigitalSignatureSystem {
    	// Method to generate RSA key pair
    	public static KeyPair generateRSAKeys() throws Exception {
        		KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        		keyGen.initialize(2048); // Initialize with a 2048-bit key size
        		return keyGen.generateKeyPair();
    	}
    
    	// Method to sign a message using SHA-256 and RSA
    	public static byte[] signMessage(byte[] message, PrivateKey privateKey) throws Exception {
        		Signature signature = Signature.getInstance("SHA256withRSA"); // Using SHA-256 with RSA
        		signature.initSign(privateKey);
        		signature.update(message);
        		return signature.sign();
    	}
    
    	// Method to verify a message's signature using the corresponding public key
    	public static boolean verifySignature(byte[] message, byte[] signatureBytes, PublicKey publicKey) throws Exception {
        		Signature signature = Signature.getInstance("SHA256withRSA"); // Using SHA-256 with RSA
        		signature.initVerify(publicKey);
        		signature.update(message);
        		return signature.verify(signatureBytes);
    	}
    
    	public static void main(String[] args) {
        		try {
            			// Generate RSA key pair
            			KeyPair keyPair = generateRSAKeys();
            			PrivateKey privateKey = keyPair.getPrivate();
            			PublicKey publicKey = keyPair.getPublic();
            
            			// Sample message to sign
            			String message = "Hello, this is a test message.";
            			byte[] messageBytes = message.getBytes();
            
            			// Sign the message with private key
            			byte[] signature = signMessage(messageBytes, privateKey);
            			System.out.println("Signature generated: " + new String(signature));
            
            			// Verify the signature using public key
            			boolean isVerified = verifySignature(messageBytes, signature, publicKey);
            			if (isVerified) {
                				System.out.println("The signature is verified.");
            			} else {
                				System.out.println("The signature failed verification.");
            			}
        		} catch (Exception e) {
            			e.printStackTrace();
        		}
    	}
}

This Java program implements a simple digital signature system using SHA-256 for hashing and RSA with PKCS#1 v1.5 padding for signing. The program consists of three main methods: generateRSAKeys, signMessage, and verifySignature.
The generateRSAKeys method generates an RSA key pair with a 2048-bit key size, which is considered secure for most applications. This method uses the KeyPairGenerator class from Java's security package to initialize and generate the keys.
The signMessage method takes a message (converted to bytes) and a private key as inputs. It initializes a Signature object using SHA256withRSA algorithm, updates it with the message, and then signs it. The resulting signature is returned as a byte array.
The verifySignature method verifies if a given signature corresponds to a particular message using a public key. Similar to signMessage, it initializes a Signature object but this time uses it for verification by updating it with the message and verifying against the provided signature bytes.
In the main method, we generate an RSA key pair, define a sample message, sign it using the private key, and then verify the signature with the corresponding public key. The program outputs whether the signature is verified or not.
The program follows security best practices by avoiding exposure of private keys and ensuring proper handling of signatures to maintain message integrity.