You can ignore everything up to update 3, the rest is just for reference about what got me to the point I am at.
Okay, so I'm pretty new to coding, and I wanted to tackle something functional. I've been working on a RSA cryptosystem that will generate a key pair and will encrypt/decrypt messages using said key pair. So far, I've figured out how to generate the modulus and exponent for each key, and how to get each key to function properly when encoding/decoding. But I'm working with the raw modulus and exponent separately for each key, and I have no real clue how the formatting of an RSA key is supposed to look. So, I want to know how I can create a properly formatted RSA key (I know I have to use the javax.crypto, but I don't quite get how). What I'd prefer is if I can take the code I already have (which is below) and add a part which takes the modulus and the exponent and puts them together into a proper key. Oh, and I'd like to be able to find the modulus and exponent from a key so I can add it to my encrypt/decrypt code parts. Additionally I have the public key I've generated as a modulus and exponent.
UPDATE on issue: Okay, so thanks to ArtJom B. I have been looking at the security library in java. But now I've run into a new issue, and I'm completely lost. I edited my code so that it (hopefully) should take the parts of each key and turn them into key objects using the keyfactory. But I keep getting the same error. Below is the new program's code, and also the error I keep getting. I don't really care if it means that I'm remaking the algorithm's implementation, I just want to get my code functioning.
Update 2: Okay, so GregS linked me to a thing about exceptions. Great! the code will compile now, and run. But a few problems exist. A) the private key only displays as [this part is fixed]and I don't know what I can do with that... B) the public key is still separated as the modulus and public exponent, I thought it wasn't supposed to do that
Small update: Oh, I figured it out, I accidentally put the private exponent in the modulus area and he public exponent in the private exponent area in the RSAPublicKeySpec ctor. But issues A and B still exist...
Final Edit: Okay, so the question was starting to get too broad. I was changing its focus from the original intention. My original question was answered, and so the code that works is below. I generate a key object then get the base64 of its encode.
Here's the new code:
import javax.xml.bind.DatatypeConverter;
import java.util.Base64;
import java.math.*;
import java.util.Scanner;
import java.security.spec.KeySpec;
import java.security.*;
import javax.crypto.Cipher;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.Provider;
import java.security.Key;
import java.security.Security;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
public class RSAcryptprop {
public static void main(String[] args){
try{
Scanner reader = new Scanner(System.in);
KeyFactory kF = KeyFactory.getInstance("RSA");
BigInteger valP, valQ, valN, totN, valE, valD, valC, valM, valMD, valsub, valDD, valED, valND, valQE, valPE, valCrtC;
String valPt, valQt, valEt, valMt;
//here's the set of starting values, two prime numbers of similar bit length
System.out.println("Value of P?:");
valPt = reader.next();
valP = new BigInteger(valPt);
System.out.println("Value of Q?:");
valQt = reader.next();
valQ = new BigInteger(valQt);
//then find the value of N and the totient of N
valN= valQ.multiply(valP);
valsub = new BigInteger("1");
totN= (valQ.subtract(valsub)).multiply(valP.subtract(valsub));
System.out.println("Totient of N:" + totN.toString(10));
System.out.println("Value of E? (must be coprime to totient of N):");
//E is a number coprime to the totient of N
valEt = reader.next();
valE = new BigInteger(valEt);
//N and E are the public key
RSAPublicKeySpec pubKeyS;
pubKeyS = new RSAPublicKeySpec(valN,valE);
PublicKey pubKey = kF.generatePublic(pubKeyS);
String pubKeyProp = DatatypeConverter.printBase64Binary(pubKey.getEncoded());
byte[] encodedPubKey = Base64.getDecoder().decode(pubKeyProp);
//then I find the modular inverse of the totient modulus E.
valD = valE.modInverse(totN);
valPE = valD.mod(valP.subtract(valsub));
valQE = valD.mod(valQ.subtract(valsub));
valCrtC = (valQ.subtract(valsub)).mod(valP);
//N and D are the private key
RSAPrivateCrtKeySpec privKeyS;
privKeyS = new RSAPrivateCrtKeySpec(valN, valE, valD, valP, valQ, valPE, valQE, valCrtC);
PrivateKey privKey = kF.generatePrivate(privKeyS);
String privKeyProp = DatatypeConverter.printBase64Binary(privKey.getEncoded());
byte[] encodedPrivKey = Base64.getDecoder().decode(privKeyProp);
System.out.println("Value of the message?:");
valMt = reader.next();
//M is the message that is being encrypted
valM = new BigInteger(valMt);
//now for encryption/decryption
RSAPublicKeySpec pubKeySD;
pubKeySD = kF.getKeySpec(pubKey,RSAPublicKeySpec.class);
valND = pubKeySD.getModulus();
RSAPrivateCrtKeySpec privKeySD;
privKeySD = kF.getKeySpec(privKey,RSAPrivateCrtKeySpec.class);
valDD = privKeySD.getPrivateExponent();
//C is the encrypted form of the message
valED = pubKeySD.getPublicExponent();
valC= valM.modPow(valED,valND);
//now to decode the value of M from the value of C
valMD = valC.modPow(valDD,valND);
//M is the message, C is the encoded form, n and e are the public key, n and d are the private key
System.out.println("Message being encrypted: " + valM);
System.out.println("Encrypted form of message: " + valC);
System.out.println("Message after going through decrypting: " + valMD);
System.out.println();
System.out.println("Proper Private Key:");
System.out.println("-----BEGIN RSA PRIVATE KEY-----");
System.out.println(privKeyProp);
System.out.println("-----END RSA PRIVATE KEY-----");
System.out.println("Proper Public Key:");
System.out.println("-----BEGIN RSA PUBLIC KEY-----");
System.out.println(pubKeyProp);
System.out.println("-----END RSA PUBLIC KEY-----");
}
catch(NoSuchAlgorithmException e){
System.err.println("algorithm error");
}
catch(InvalidKeySpecException e){
System.err.println("keyspec error");
}
}
}