Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

in JAVA : for this assignment we will be generating signatures and validating si

ID: 3753123 • Letter: I

Question

in JAVA :

for this assignment we will be generating signatures and validating signatures using our ssh keys. we will be using RSA keys to do the signing and validation.

you will want to use test ssh keys for RSA:

be sure to generate keys that aren't password protected!

you need to implement the following class: (please don't change the package name, class name, or method signatures)

NOTE: when generating signatures with RSA use "SHA256withRSA" .

public class BlobSigner {
/**
* generate a signature file (dstSignatureFile) for fileToSign using
* sshPrivateKeyFile.
*
*
*
*
*
* @param fileToSign the file containing the data to be signed.
* @param sshPrivateKeyFile the ssh private key file with the signing key
* to use.
* @param dstSignatureFile the file to write the generated signature to.
* the signature will be base64 encoded.
*/
  
  
  
   public static void signFile(
File fileToSign, File sshPrivateKeyFile, File dstSignatureFile
) {}

/**
* validate the signature file (signatureFile) corresponding to
* signedFile using the public key in sshPublicKeyFile.
* @param signedFile the file containing the data that was signed.
* @param sshPublicKeyFile the file containing the public key corresponds
* to the private key that was used to sign
* signedFile.
* @param signatureFile the base64 encoded signature generated with the
* private key that corresponds to sshPublicKeyFile
* over the data in the signedFile.
* @return true if the signature is valid.
*/

Explanation / Answer

package com.chegg.test.signature;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

import static java.nio.charset.StandardCharsets.UTF_8;
import java.nio.file.Files;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import java.util.Base64;

import javax.crypto.Cipher;

// The below class is used to sign/verify the message
public class BlobSigner {
  
private KeyPairGenerator keyGen;
private KeyPair pair;
private PrivateKey privateKey;
private PublicKey publicKey;
  
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048, new SecureRandom());
KeyPair pair = generator.generateKeyPair();

return pair;
}
public BlobSigner(int keylength) throws NoSuchAlgorithmException, NoSuchProviderException {
this.keyGen = KeyPairGenerator.getInstance("RSA");
this.keyGen.initialize(keylength);
}


public void createKeys() {
this.pair = this.keyGen.generateKeyPair();
this.privateKey = pair.getPrivate();
this.publicKey = pair.getPublic();
}

public PrivateKey getPrivateKey() {
return this.privateKey;
}

public PublicKey getPublicKey() {
return this.publicKey;
}

public void writeToFile(String path, byte[] key) throws IOException {
File f = new File(path);
f.getParentFile().mkdirs();

FileOutputStream fos = new FileOutputStream(f);
fos.write(key);
fos.flush();
fos.close();
}
public static String encrypt(File fileToSign, PublicKey publicKey) throws Exception {
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);

byte[] cipherText = encryptCipher.doFinal(Files.readAllBytes(fileToSign.toPath()));

return Base64.getEncoder().encodeToString(cipherText);
}

public static String decrypt(String cipherText, PrivateKey privateKey) throws Exception {
byte[] bytes = Base64.getDecoder().decode(cipherText);

Cipher decriptCipher = Cipher.getInstance("RSA");
decriptCipher.init(Cipher.DECRYPT_MODE, privateKey);

return new String(decriptCipher.doFinal(bytes), UTF_8);
}
  
public byte[] getFileInBytes(File f) throws IOException {
FileInputStream fis = new FileInputStream(f);
byte[] fbytes = new byte[(int) f.length()];
fis.read(fbytes);
fis.close();
return fbytes;
}
// sign function
public void signFile(File fileToSign, File sshPrivateKeyFile , File dstSignatureFile) throws Exception {
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(this.getPrivate(sshPrivateKeyFile));
privateSignature.update(Files.readAllBytes(fileToSign.toPath()));
byte[] signature = privateSignature.sign();
Writer writer = new FileWriter(dstSignatureFile);
FileWriter fileWriter = new FileWriter(dstSignatureFile);
fileWriter.write(Base64.getEncoder().encodeToString(signature));
fileWriter.flush();
fileWriter.close();
}
// verify the message
public boolean verify(File signedFile , File signatureFile, File sshPublicKeyFile) throws Exception {
  
Signature publicSignature = Signature.getInstance("SHA256withRSA");
publicSignature.initVerify(this.getPublic(sshPublicKeyFile));
publicSignature.update(Files.readAllBytes(signedFile.toPath()));

byte[] signatureBytes = Base64.getDecoder().decode(Files.readAllBytes(signatureFile.toPath()));

return publicSignature.verify(signatureBytes);
}
  
// Driver method to verify the signature
public static void main(String... argv) throws Exception {
  
// Name of public key and private key
String publicKeyStr = "D:\Keys\publicKey.key";
String privateKeyStr = "D:\Keys\privateKey.key";
BlobSigner bs = new BlobSigner(2048);
// generating private key and public key
bs.createKeys();
bs.writeToFile(publicKeyStr, bs.getPublicKey().getEncoded());
bs.writeToFile(privateKeyStr, bs.getPrivateKey().getEncoded());

// creating files for public key and private key
File sshPublicKeyFile = new File(publicKeyStr);
File sshPrivateKeyFile = new File(privateKeyStr);
  
//First generate a public/private key pair
KeyPair pair = generateKeyPair();
File fileToSign = new File("D://TestMessage.txt");
File dstSignatureFile = new File("D://dstSignatureFile.txt");
//Let's sign our message
bs.signFile(fileToSign, sshPrivateKeyFile, dstSignatureFile);
//Let's verify the signature
boolean isCorrect = bs.verify(fileToSign, dstSignatureFile, sshPublicKeyFile);
System.out.println("Signature correct: " + isCorrect);
}
  
//Method to retrieve the Private Key from a file
public PrivateKey getPrivate(File filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(filename.toPath());
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
  
//Method to retrieve the public Key from a file
public PublicKey getPublic(File filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(filename.toPath());
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
}

/* Output

Signature correct: true

*/