Skip to content

Add Digital Signature Algorithm (DSA) implementation for signing and verifying messages #5336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/main/java/com/thealgorithms/hashes/DSS.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.thealgorithms.hashes;

import java.security.*;
import java.util.Base64;
import java.util.Scanner;

/**
* The DSS class demonstrates the use of the Digital Signature Algorithm (DSA) for signing and verifying messages.
* DSA is a Federal Information Processing Standard for digital signatures, based on the mathematical concept of modular exponentiation and discrete logarithms.
*
* @see <a href="https://en.wikipedia.org/wiki/Digital_Signature_Algorithm">Digital Signature Algorithm on Wikipedia</a>
*/
public class DSS {

public static void main(String[] args) throws Exception {
// Generate a key pair (public and private keys) for DSA
KeyPair keyPair = generateKeyPair();

// Get message input from the user
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the message to sign: ");
String message = scanner.nextLine();
scanner.close();

// Sign the message using the private key
byte[] signature = signMessage(message.getBytes(), keyPair.getPrivate());
System.out.println("Signature: " + Base64.getEncoder().encodeToString(signature));

// Verify the signature using the public key
boolean verified = verifySignature(message.getBytes(), signature, keyPair.getPublic());
System.out.println("Signature verified: " + verified);
}

/**
* Generates a DSA key pair (private and public keys).
*
* @return a KeyPair containing a DSA private key and public key
* @throws NoSuchAlgorithmException if the DSA algorithm is not available
*/
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
// Create a KeyPairGenerator for DSA
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");

// Initialize the KeyPairGenerator with a key size and a secure random number generator
SecureRandom secureRandom = new SecureRandom();
keyPairGenerator.initialize(1024, secureRandom);

Check failure

Code scanning / CodeQL

Use of a cryptographic algorithm with insufficient key size High

This
key size
is less than the recommended key size of 2048 bits.

// Generate and return the KeyPair
return keyPairGenerator.generateKeyPair();
}

/**
* Signs a message using a private key.
*
* @param message the message to be signed
* @param privateKey the private key used to sign the message
* @return a byte array containing the digital signature
* @throws Exception if an error occurs during the signing process
*/
public static byte[] signMessage(byte[] message, PrivateKey privateKey) throws Exception {
// Create a Signature object for signing with the DSA algorithm and SHA-256
Signature signature = Signature.getInstance("SHA256withDSA");

// Initialize the Signature object with the private key
signature.initSign(privateKey);

// Add the data to be signed
signature.update(message);

// Sign the data and return the digital signature
return signature.sign();
}

/**
* Verifies a digital signature using a public key.
*
* @param message the original message data
* @param signature the digital signature to verify
* @param publicKey the public key used for verification
* @return true if the signature is valid, false otherwise
* @throws Exception if an error occurs during the verification process
*/
public static boolean verifySignature(byte[] message, byte[] signature, PublicKey publicKey) throws Exception {
// Create a Signature object for verification with the DSA algorithm and SHA-256
Signature sig = Signature.getInstance("SHA256withDSA");

// Initialize the Signature object with the public key
sig.initVerify(publicKey);

// Add the data to be verified
sig.update(message);

// Verify the signature and return the result
return sig.verify(signature);
}
}
73 changes: 73 additions & 0 deletions src/main/java/com/thealgorithms/hashes/MD5.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.thealgorithms.hashes;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;

/**
* The MD5 class provides a method to generate the MD5 hash for a given string.
* MD5 (Message Digest Algorithm 5) is a widely used cryptographic hash function that produces
* a 128-bit (16-byte) hash value. It is commonly used for checksums and data integrity,
* although it is no longer considered secure for cryptographic purposes.
*
* @see <a href="https://en.wikipedia.org/wiki/MD5">MD5 on Wikipedia</a>
*/
public class MD5 {

/**
* Generates the MD5 hash of the input string.
*
* @param input the string to be hashed
* @return the MD5 hash as a hexadecimal string
*/
public static String getMd5(String input) {
try {
// Create a MessageDigest instance for MD5
MessageDigest md = MessageDigest.getInstance("MD5");

Check failure

Code scanning / CodeQL

Use of a broken or risky cryptographic algorithm High

Cryptographic algorithm
MD5
is weak and should not be used.

// Compute the MD5 digest of the input string
byte[] messageDigest = md.digest(input.getBytes());

// Convert the byte array into a BigInteger to get the hash in hexadecimal format
BigInteger no = new BigInteger(1, messageDigest);

// Convert the BigInteger to a hexadecimal string
String hashtext = no.toString(16);

// Pad with leading zeros to ensure the hash is 32 characters long
while (hashtext.length() < 32) {
hashtext = "0" + hashtext;
}

// Return the generated MD5 hash
return hashtext;
} catch (NoSuchAlgorithmException e) {
// Handle the case where MD5 algorithm is not available
throw new RuntimeException(e);
}
}

/**
* The main method that takes user input, computes its MD5 hash, and prints the result.
*
* @param args command-line arguments
* @throws NoSuchAlgorithmException if the MD5 algorithm is not available
*/
public static void main(String args[]) throws NoSuchAlgorithmException {
// Create a Scanner object to read input from the user
Scanner scanner = new Scanner(System.in);

// Prompt the user to enter a string to hash
System.out.print("Enter the string to hash: ");

// Read the input string from the user
String s = scanner.nextLine();

// Compute the MD5 hash of the input string and print it
System.out.println("Your HashCode Generated by MD5 is: " + getMd5(s));

// Close the Scanner object
scanner.close();
}
}
73 changes: 73 additions & 0 deletions src/main/java/com/thealgorithms/hashes/SHA1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.thealgorithms.hashes;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;

/**
* The SHA1 class provides a method to generate the SHA-1 hash for a given string.
* SHA-1 (Secure Hash Algorithm 1) is a cryptographic hash function that produces
* a 160-bit (20-byte) hash value. It is commonly used for data integrity verification,
* although it is no longer considered secure for cryptographic purposes.
*
* @see <a href="https://en.wikipedia.org/wiki/SHA-1">SHA-1 on Wikipedia</a>
*/
public class SHA1 {

/**
* Generates the SHA-1 hash of the input string.
*
* @param input the string to be hashed
* @return the SHA-1 hash as a hexadecimal string
*/
public static String getSha1(String input) {
try {
// Create a MessageDigest instance for SHA-1
MessageDigest md = MessageDigest.getInstance("SHA-1");

// Compute the SHA-1 digest of the input string
byte[] messageDigest = md.digest(input.getBytes());

// Convert the byte array into a BigInteger to get the hash in hexadecimal format
BigInteger no = new BigInteger(1, messageDigest);

// Convert the BigInteger to a hexadecimal string
String hashtext = no.toString(16);

// Pad with leading zeros to ensure the hash is 32 characters long
while (hashtext.length() < 32) {
hashtext = "0" + hashtext;
}

// Return the generated SHA-1 hash
return hashtext;
} catch (NoSuchAlgorithmException e) {
// Handle the case where SHA-1 algorithm is not available
throw new RuntimeException(e);
}
}

/**
* The main method that takes user input, computes its SHA-1 hash, and prints the result.
*
* @param args command-line arguments
* @throws NoSuchAlgorithmException if the SHA-1 algorithm is not available
*/
public static void main(String args[]) throws NoSuchAlgorithmException {
// Create a Scanner object to read input from the user
Scanner scanner = new Scanner(System.in);

// Prompt the user to enter a string to hash
System.out.print("Enter the string to hash: ");

// Read the input string from the user
String s = scanner.nextLine();

// Compute the SHA-1 hash of the input string and print it
System.out.println("Your HashCode Generated by SHA-1 is: " + getSha1(s));

// Close the Scanner object
scanner.close();
}
}
96 changes: 96 additions & 0 deletions src/test/java/com/thealgorithms/hashes/DSS.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.thealgorithms.hashes;

import java.security.*;
import java.util.Base64;
import java.util.Scanner;

/**
* The DSS class demonstrates the use of the Digital Signature Algorithm (DSA) for signing and verifying messages.
* DSA is a Federal Information Processing Standard for digital signatures, based on the mathematical concept of modular exponentiation and discrete logarithms.
*
* @see <a href="https://en.wikipedia.org/wiki/Digital_Signature_Algorithm">Digital Signature Algorithm on Wikipedia</a>
*/
public class DSS {

public static void main(String[] args) throws Exception {
// Generate a key pair (public and private keys) for DSA
KeyPair keyPair = generateKeyPair();

// Get message input from the user
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the message to sign: ");
String message = scanner.nextLine();
scanner.close();

// Sign the message using the private key
byte[] signature = signMessage(message.getBytes(), keyPair.getPrivate());
System.out.println("Signature: " + Base64.getEncoder().encodeToString(signature));

// Verify the signature using the public key
boolean verified = verifySignature(message.getBytes(), signature, keyPair.getPublic());
System.out.println("Signature verified: " + verified);
}

/**
* Generates a DSA key pair (private and public keys).
*
* @return a KeyPair containing a DSA private key and public key
* @throws NoSuchAlgorithmException if the DSA algorithm is not available
*/
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
// Create a KeyPairGenerator for DSA
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");

// Initialize the KeyPairGenerator with a key size and a secure random number generator
SecureRandom secureRandom = new SecureRandom();
keyPairGenerator.initialize(1024, secureRandom);

Check failure

Code scanning / CodeQL

Use of a cryptographic algorithm with insufficient key size High test

This
key size
is less than the recommended key size of 2048 bits.

// Generate and return the KeyPair
return keyPairGenerator.generateKeyPair();
}

/**
* Signs a message using a private key.
*
* @param message the message to be signed
* @param privateKey the private key used to sign the message
* @return a byte array containing the digital signature
* @throws Exception if an error occurs during the signing process
*/
public static byte[] signMessage(byte[] message, PrivateKey privateKey) throws Exception {
// Create a Signature object for signing with the DSA algorithm and SHA-256
Signature signature = Signature.getInstance("SHA256withDSA");

// Initialize the Signature object with the private key
signature.initSign(privateKey);

// Add the data to be signed
signature.update(message);

// Sign the data and return the digital signature
return signature.sign();
}

/**
* Verifies a digital signature using a public key.
*
* @param message the original message data
* @param signature the digital signature to verify
* @param publicKey the public key used for verification
* @return true if the signature is valid, false otherwise
* @throws Exception if an error occurs during the verification process
*/
public static boolean verifySignature(byte[] message, byte[] signature, PublicKey publicKey) throws Exception {
// Create a Signature object for verification with the DSA algorithm and SHA-256
Signature sig = Signature.getInstance("SHA256withDSA");

// Initialize the Signature object with the public key
sig.initVerify(publicKey);

// Add the data to be verified
sig.update(message);

// Verify the signature and return the result
return sig.verify(signature);
}
}
Loading
Loading