ECKeyAgreement in Generating public and private key using ecc - java

I am working on a concept of encryption and decryption using ecc.
I already generated public and private key. While I am encrypting the text I am getting this error:
java.security.InvalidKeyException: ECKeyAgreement requires ECPrivateKey
at
org.bouncycastle.jce.provider.JCEECDHKeyAgreement.engineInit(JCEECDHKeyAgreement.java:121)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:462)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:436)
at rbl2015.encryec.main(encryec.java:67)
This is my encryption Java file:
import java.io.File;
import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.ECParameterSpec;
import java.security.spec.EllipticCurve;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Scanner;
import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class encryec
{
KeyPairGenerator kpg;
EllipticCurve curve;
ECParameterSpec ecSpec;
KeyPair aKeyPair;
static KeyAgreement aKeyAgree;
KeyPair bKeyPair;
KeyAgreement bKeyAgree;
KeyFactory keyFac;
static String msg;
public static void main(String args[])
{
Security.addProvider(new BouncyCastleProvider());
Scanner ss=new Scanner(System.in);
try{
String path = "D:\\rp";
File filePublicKey = new File(path+"\\public.key");
FileInputStream fis = new FileInputStream(path+"\\public.key");
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(path+"\\private.key");
fis = new FileInputStream(path+"\\private.key");
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
KeyFactory keyFactory = KeyFactory.getInstance("ECDH");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
aKeyAgree = KeyAgreement.getInstance("ECDH", "BC");
aKeyAgree.init(privateKey); // exception line
aKeyAgree.doPhase(publicKey, true);
byte[] aBys = aKeyAgree.generateSecret();
KeySpec aKeySpec = new DESKeySpec(aBys);
SecretKeyFactory aFactory = SecretKeyFactory.getInstance("DES");
Key aSecretKey = aFactory.generateSecret(aKeySpec);
Cipher aCipher = Cipher.getInstance(aSecretKey.getAlgorithm());
aCipher.init(Cipher.ENCRYPT_MODE, aSecretKey);
byte[] encText = aCipher.doFinal("Its Rahul".getBytes());
System.out.println(Base64.encodeBase64String(encText));
System.out.println(encText);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
I don't know what I am missing. I tried everything that I can to get the ECPrivateKey.
This is the code for generating the public and private key:
import java.io.*;
import java.security.*;
import java.security.spec.*;
public class Rahul {
public static void main(String args[]) {
Rahul rahul = new Rahul();
try {
String path = "D:\\rp";
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(1024);
KeyPair generatedKeyPair = keyGen.genKeyPair();
System.out.println("Generated Key Pair");
rahul.dumpKeyPair(generatedKeyPair);
rahul.SaveKeyPair(path, generatedKeyPair);
KeyPair loadedKeyPair = rahul.LoadKeyPair(path, "DSA");
System.out.println("Loaded Key Pair");
rahul.dumpKeyPair(loadedKeyPair);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private void dumpKeyPair(KeyPair keyPair) {
PublicKey pub = keyPair.getPublic();
System.out.println("Public Key: " + getHexString(pub.getEncoded()));
PrivateKey priv = keyPair.getPrivate();
System.out.println("Private Key: " + getHexString(priv.getEncoded()));
}
private String getHexString(byte[] b) {
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public void SaveKeyPair(String path, KeyPair keyPair) throws IOException {
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(path + "/public.key");
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream(path + "/private.key");
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
public KeyPair LoadKeyPair(String path, String algorithm)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
// Read Public Key.
File filePublicKey = new File(path + "/public.key");
FileInputStream fis = new FileInputStream(path + "/public.key");
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(path + "/private.key");
fis = new FileInputStream(path + "/private.key");
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return new KeyPair(publicKey, privateKey);
}
}

You should try and create an EC(DH) key pair instead of a DSA key pair. Although the general method of operation is identical (both ECDSA and DSA are based on the Diffie-Hellman problem) the key types are certainly not.

Related

RSA -OAEP encryption and decryption of Symmetric Key file

I am trying to encrypt and decrypt a symmetric key file (256 and 128) using RSAES - OAEP but I am getting error while encrypting :
File Sizes to encrypt: 256 and 128
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.Arrays;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.generateKeyPair();
String inputPath = "/home/roxane/Music/test_09";
String inFile = "/home/roxane/Downloads/s_key";
String encfile = "/home/roxane/Music/s_key.enc";
// get key pair
PublicKey pub = kp.getPublic();
PrivateKey PrivateKey = kp.getPrivate();
// Write Key Pair
try (FileOutputStream out = new FileOutputStream(inputPath + ".key")) {
out.write(kp.getPrivate().getEncoded());
}
try (FileOutputStream out = new FileOutputStream(inputPath + ".pub")) {
out.write(kp.getPublic().getEncoded());
}
//restore kEys
byte[] pubbytes = Files.readAllBytes(Paths.get(inputPath + ".pub"));
X509EncodedKeySpec ks = new X509EncodedKeySpec(pubbytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pub1 = kf.generatePublic(ks);
byte[] privbytes = Files.readAllBytes(Paths.get(inputPath + ".key"));
PKCS8EncodedKeySpec ks1 = new PKCS8EncodedKeySpec(privbytes);
KeyFactory kf1 = KeyFactory.getInstance("RSA");
PrivateKey pvt = kf1.generatePrivate(ks1);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pvt);
try (FileInputStream in = new FileInputStream(inFile);
FileOutputStream out = new FileOutputStream(encfile)) {
processFile(cipher, in, out);
}
}
static private void processFile(Cipher ci,InputStream in,OutputStream out)
throws javax.crypto.IllegalBlockSizeException,
javax.crypto.BadPaddingException,
java.io.IOException
{
byte[] ibuf = new byte[1024];
int len;
while ((len = in.read(ibuf)) != -1) {
byte[] obuf = ci.update(ibuf, 0, len);
if ( obuf != null ) out.write(obuf);
}
byte[] obuf = ci.doFinal();
if ( obuf != null ) out.write(obuf);
}
Error: Exception in thread "main" java.security.InvalidKeyException: OAEP cannot be used to sign or verify signatures
Requesting help in the code encrytption and decryption of the files compatible with openssl. I am open to use bouncycastle if required

Java RSA decryption with private key gives BadPaddingException

today, I wrote some code to encrypt a String with AES and encrypt the key with RSA. When I try to decrypt the everything, Java gives me a BadPaddingException.
Here is my code:
Test.java:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Scanner;
public class Test {
private static String publicName = null;
private static String privateName = null;
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Choose an option: \n(1) Decrypt \n(2) Encrypt \n(3) Generate Keypair");
int choice = scanner.nextInt();
if(choice == 1) decrypt();
else if(choice == 2) encrypt();
else if(choice == 3) makeKeypair();
}
private static void makeKeypair() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the name of your public key: ");
publicName = scanner.nextLine() + ".key";
System.out.println("Enter the name of your private key: ");
privateName = scanner.nextLine() + ".key";
KeyMaker keyMaker = new KeyMaker(publicName, privateName);
keyMaker.generateKeys();
}
public static void encrypt() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the text you want to encrypt: ");
String toEncrypt = scanner.nextLine();
System.out.println("Enter the name of the public key you want to use: ");
publicName = scanner.nextLine() + ".key";
Encrypter encrypter = new Encrypter(publicName);
Key key = generateKey();
String encryptedWithAES = encryptAES(toEncrypt, key);
String encodedKey = java.util.Base64.getEncoder().encodeToString(key.getEncoded());
String encryptedKey = encrypter.rsaEncrypt(encodedKey);
String finalOutput = encryptedKey + encryptedWithAES;
System.out.println("Enter the name of the file encrypted file which will be created: ");
String fileName = scanner.nextLine();
PrintWriter out = new PrintWriter(fileName + ".txt");
out.println(finalOutput);
out.close();
System.out.println("DONE - saved as: " + fileName + ".txt");
scanner.close();
}
public static void decrypt() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the name of your encrypted file: ");
String fileName = scanner.nextLine() + ".txt";
String givenInput = null;
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null) {
givenInput = givenInput + line;
}
}
assert givenInput != null;
String encryptedKey = givenInput.substring(0,172);
String encryptedWithAES = givenInput.replace(encryptedKey, "");
System.out.println("Enter the name of your private key: ");
privateName = scanner.nextLine() + ".key";
Decrypter decrypter = new Decrypter(privateName);
String decryptedKey = decrypter.rsaDecrypt(encryptedKey);
byte[] decodedKey = java.util.Base64.getDecoder().decode(decryptedKey);
Key originalKey = new SecretKeySpec(decodedKey, "AES");
String decryptedWithAES = decryptAES(encryptedWithAES, originalKey);
System.out.println(decryptedWithAES);
scanner.close();
}
public static Key generateKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
kg.init(random);
return kg.generateKey();
}
private static String encryptAES(String message, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] stringBytes = message.getBytes();
byte[] raw = cipher.doFinal(stringBytes);
return Base64.encodeBase64String(raw);
}
public static String decryptAES(String encrypted, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] raw = Base64.decodeBase64(encrypted);
byte[] stringBytes = cipher.doFinal(raw);
return new String(stringBytes, "UTF8");
}
}
KeyMaker.java:
import java.io.FileOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class KeyMaker {
String publicName;
String privateName;
public KeyMaker(String publicName, String privateName) {
this.publicName = publicName;
this.privateName = privateName;
}
public void generateKeys() throws Exception{
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
PrivateKey privateKey = kp.getPrivate();
PublicKey publicKey = kp.getPublic();
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(publicName);
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream(privateName);
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
}
Encrypter.java:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
public class Encrypter {
String keyFileName;
public Encrypter(String keyFileName) {
this.keyFileName = keyFileName;
}
public String rsaEncrypt(String data) throws Exception {
PublicKey pubKey = readPublicKeyFromFile(keyFileName);
byte[] utf8 = data.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] enc = cipher.doFinal(Base64.encodeBase64(utf8));
return Base64.encodeBase64String(enc);
}
private PublicKey readPublicKeyFromFile(String keyFileName) throws Exception {
File filePublicKey = new File(keyFileName);
FileInputStream fis = new FileInputStream(keyFileName);
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
return pubKey;
}
}
Decrypter.java:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
public class Decrypter {
String keyFileName;
public Decrypter(String keyFileName) {
this.keyFileName = keyFileName;
}
public String rsaDecrypt(String str) throws Exception {
PrivateKey privateKey = readPrivateKeyFromFile(keyFileName);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dec = Base64.decodeBase64(str);
byte[] utf8 = cipher.doFinal(Base64.decodeBase64(dec));
return Base64.encodeBase64String(utf8);
}
private PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
File filePrivateKey = new File(keyFileName);
FileInputStream fis = new FileInputStream(keyFileName);
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}
}
In your Decrypter, you decode the Base64-encoded String into bytes, but then you decode that again. In your Encrypter, you take the bytes encrypted, and encode that into Base64 once. This is likely where your problem lies.
Strangely enough, you seem to perform more Base64 operations than necessary. For example, in Encrypter, you get the bytes of the string to encrypt. Why do you Base64-encode those bytes again?

Encrypting and decrypting with public and private RSA keys in JAVA

I am trying to do a simple encrypt/decrypt with asymmetric keys in JAVA using RSA keys and i have some troubles. This is my code :
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
public class AsymmetricCipherTestFiles
{
public static void main(String[] unused) throws Exception
{
// 1. Generating keys
System.out.println("Generating keys ...");
PublicKey publicKey;
PrivateKey privateKey;
// generateKeys(512);
// 2. read them from file
System.out.println("Read from file");
publicKey = readPublicKeyFromFile("public.key");
privateKey = readPrivateKeyFromFileTest("private.key");
System.exit(0);
// 3. encrypt data
System.out.println("Encrypt data");
byte[] dataBytes = "some string to encrypt".getBytes();
byte[] encBytes = encrypt(dataBytes, publicKey, "RSA");
printByteArray(encBytes);
// 4. decrypt data
byte[] decBytes = decrypt(encBytes, privateKey, "RSA");
printByteArray(decBytes);
// String decryptedThing = convert(decBytes);
}
public static void generateKeys(int keySize) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
// Create key
// System.out.println("Generating keys");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(keySize);
KeyPair kp = kpg.genKeyPair();
/*
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
*/
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(),RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(),RSAPrivateKeySpec.class);
saveKeyToFile("bin/public.key", pub.getModulus(), pub.getPublicExponent());
saveKeyToFile("bin/private.key", priv.getModulus(),priv.getPrivateExponent());
// System.out.println("Keys generated");
}
private static byte[] encrypt(byte[] inpBytes, PublicKey key,String xform) throws Exception
{
Cipher cipher = Cipher.getInstance(xform);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(inpBytes);
}
private static byte[] decrypt(byte[] inpBytes, PrivateKey key,String xform) throws Exception
{
Cipher cipher = Cipher.getInstance(xform);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(inpBytes);
}
public static String convert(byte[] data)
{
StringBuilder sb = new StringBuilder(data.length);
for (int i = 0; i < data.length; ++ i)
{
if (data[i] < 0) throw new IllegalArgumentException();
sb.append((char) data[i]);
}
return sb.toString();
}
public static PublicKey readPublicKeyFromFile(String keyFileName) throws IOException
{
InputStream in = (InputStream) AsymmetricCipherTestFiles.class.getResourceAsStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream( in ));
try
{
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
}
catch (Exception e)
{
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
public static PrivateKey readPrivateKeyFromFile(String keyFileName) throws IOException
{
InputStream in = (InputStream) AsymmetricCipherTestFiles.class.getResourceAsStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream( in ));
try
{
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
byte[] byteArray = new byte[512];
byteArray = m.toByteArray();
KeySpec keySpec = new PKCS8EncodedKeySpec(byteArray);
// RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privateKey = fact.generatePrivate(keySpec);
return privateKey;
}
catch (Exception e)
{
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
public static PrivateKey readPrivateKeyFromFileTest(String filename) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
RandomAccessFile raf = new RandomAccessFile(filename, "r");
byte[] buf = new byte[(int)raf.length()];
raf.readFully(buf);
raf.close();
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(kspec);
return privKey;
}
public static void saveKeyToFile(String fileName,BigInteger mod, BigInteger exp) throws IOException
{
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
try
{
oout.writeObject(mod);
oout.writeObject(exp);
}
catch (Exception e)
{
throw new IOException("Unexpected error", e);
}
finally
{
oout.close();
}
}
public static void printByteArray(byte[] byteArray)
{
int increment = 0;
for(byte b : byteArray)
{
System.out.println("B["+increment+"] = "+b);
increment++;
}
}
}
When i run it it gives me this error :
Generating keys ...
Read from file
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=109, too big.
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
at java.security.KeyFactory.generatePrivate(Unknown Source)
at AsymmetricCipherTestFiles.readPrivateKeyFromFileTest(AsymmetricCipherTestFiles.java:160)
at AsymmetricCipherTestFiles.main(AsymmetricCipherTestFiles.java:40)
Caused by: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=109, too big.
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source)
at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source)
... 4 more
The thing is that at generating/reading/encrypting with public key everything works smoothly, the error occurs when reading private key and trying to get it into an PrivateKey object.
What i am doing wrong and how i may solve this?
Thanks.
You're saving the key with two writeObject() calls but retreiving it with a single readFully() call. You need to either:
save the key with write(byte[]), supplying the result of getEncoded(), and read it with readFully(), or
save it with writeObject() and read it with readObject().
Not a mixture of the two.

How do you generate, sign and read digital signatures in java?

I am becoming intermediate java programmer. I have tried hard to find out how to sign and read digital signatures in java for a net program i have been working on. I have been able to generate private and public keys with the tutorial at http://docs.oracle.com/javase/tutorial/security/apisign/index.html but have not been able to do anything with them. Although I know how to generate keys i didn't put it in because i wasn't sure if i had done them correctly.
Here is a simplified version of my code:
Main class:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Main main = new Main();
Scanner s = new Scanner(System.in);
while (true) {
//This is where i added a command detector so that the program can be in one class
System.out.println("Choose a command from the following:\nGenerate keys\nSign message\nRead message");
String command = s.nextLine();
if (command.equalsIgnoreCase("Generate key")
|| command.equalsIgnoreCase("Generate")) {
/* The code for generating the keys is here */
File f = new File("C:\\Users\\spencer\\Documents\\Stack ex\\src\\app","public.key");
File fi = new File("C:\\Users\\spencer\\Documents\\Stack ex\\src\\app","private.key");
if(!f.isFile()||!fi.isFile()) {
Make make =new Make();
Make.main(args);
}
else{
try {
String path = "C:\\Users\\spencer\\Documents\\ds test 3\\src\\app";
KeyPair loadedKeyPair = main.LoadKeyPair(path, "DSA");
System.out.println("Key pair already exists!");
System.out.println("Loaded Key Pair:");
main.dumpKeyPair(loadedKeyPair);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
if (command.equalsIgnoreCase("Sign message")
|| command.equalsIgnoreCase("Sign")) {
long signature = 0;
System.out.println("What is your private key");
String pkey = s.nextLine();
long prkey = Long.parseLong(pkey);
System.out.println("What is you message");
String message = s.nextLine();
/* The code for signing the message goes here */
System.out.println("Signature:"+signature);
} else if (command.equalsIgnoreCase("Read message")
|| command.equalsIgnoreCase("Read")) {
String message = null;
System.out.println("What is the signature");
String sign = s.nextLine();
long signature = Long.parseLong(sign);
/* The code for reading the message goes here */
System.out.println(message);
}
}
}
private void dumpKeyPair(KeyPair keyPair) {
PublicKey pub = keyPair.getPublic();
System.out.println("Public Key: " + getHexString(pub.getEncoded()));
PrivateKey priv = keyPair.getPrivate();
System.out.println("Private Key: " + getHexString(priv.getEncoded()));
}
private String getHexString(byte[] b) {
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public KeyPair LoadKeyPair(String path, String algorithm)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
// Read Public Key.
File filePublicKey = new File(path + "/public.key");
FileInputStream fis = new FileInputStream(path + "/public.key");
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(path + "/private.key");
fis = new FileInputStream(path + "/private.key");
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return new KeyPair(publicKey, privateKey);
}
}
Make class:
import java.io.*;
import java.security.*;
import java.security.spec.*;
public class Make {
public static void main(String args[]) {
Make adam = new Make();
try {
String path = "C:\\Users\\spencer\\Documents\\Stack ex\\src\\app";
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(512);
KeyPair generatedKeyPair = keyGen.genKeyPair();
System.out.println("Generated Key Pair");
adam.dumpKeyPair(generatedKeyPair);
adam.SaveKeyPair(path, generatedKeyPair);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private void dumpKeyPair(KeyPair keyPair) {
PublicKey pub = keyPair.getPublic();
System.out.println("Public Key: " + getHexString(pub.getEncoded()));
PrivateKey priv = keyPair.getPrivate();
System.out.println("Private Key: " + getHexString(priv.getEncoded()));
}
private String getHexString(byte[] b) {
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public void SaveKeyPair(String path, KeyPair keyPair) throws IOException {
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(path + "/public.key");
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream(path + "/private.key");
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
}
I need a little help with signing and reading the signature.

Load RSA public key from file

I've generated a private key with:
openssl genrsa [-out file] –des3
After this I've generated a public key with:
openssl rsa –pubout -in private.key [-out file]
I want to sign some messages with my private key, and verify some other messages with my public key, using code like this:
public String sign(String message) throws SignatureException{
try {
Signature sign = Signature.getInstance("SHA1withRSA");
sign.initSign(privateKey);
sign.update(message.getBytes("UTF-8"));
return new String(Base64.encodeBase64(sign.sign()),"UTF-8");
} catch (Exception ex) {
throw new SignatureException(ex);
}
}
public boolean verify(String message, String signature) throws SignatureException{
try {
Signature sign = Signature.getInstance("SHA1withRSA");
sign.initVerify(publicKey);
sign.update(message.getBytes("UTF-8"));
return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
} catch (Exception ex) {
throw new SignatureException(ex);
}
}
I found a solution to convert my private key to PKCS8 format and load it. It works with some code like this:
public PrivateKey getPrivateKey(String filename) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf =
KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
And finally my question is: How do I load my RSA Public Key from a file?
I think maybe I need to convert my public key file to x509 format, and use X509EncodedKeySpec. But how can I do this?
Below is the relevant information from the link which Zaki provided.
Generate a 2048-bit RSA private key
$ openssl genrsa -out private_key.pem 2048
Convert private Key to PKCS#8 format (so Java can read it)
$ openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt
Output public key portion in DER format (so Java can read it)
$ openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der
Private key
import java.nio.file.*;
import java.security.*;
import java.security.spec.*;
public class PrivateKeyReader {
public static PrivateKey get(String filename)
throws Exception {
byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
}
Public key
import java.nio.file.*;
import java.security.*;
import java.security.spec.*;
public class PublicKeyReader {
public static PublicKey get(String filename)
throws Exception {
byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
X509EncodedKeySpec spec =
new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
}
This program is doing almost everything with Public and private keys.
The der format can be obtained but saving raw data ( without encoding base64).
I hope this helps programmers.
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import sun.security.pkcs.PKCS8Key;
import sun.security.pkcs10.PKCS10;
import sun.security.x509.X500Name;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* #author Desphilboy
* DorOd bar shomA barobach
*
*/
public class csrgenerator {
private static PublicKey publickey= null;
private static PrivateKey privateKey=null;
//private static PKCS8Key privateKey=null;
private static KeyPairGenerator kpg= null;
private static ByteArrayOutputStream bs =null;
private static csrgenerator thisinstance;
private KeyPair keypair;
private static PKCS10 pkcs10;
private String signaturealgorithm= "MD5WithRSA";
public String getSignaturealgorithm() {
return signaturealgorithm;
}
public void setSignaturealgorithm(String signaturealgorithm) {
this.signaturealgorithm = signaturealgorithm;
}
private csrgenerator() {
try {
kpg = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.out.print("No such algorithm RSA in constructor csrgenerator\n");
}
kpg.initialize(2048);
keypair = kpg.generateKeyPair();
publickey = keypair.getPublic();
privateKey = keypair.getPrivate();
}
/** Generates a new key pair
*
* #param int bits
* this is the number of bits in modulus must be 512, 1024, 2048 or so on
*/
public KeyPair generateRSAkys(int bits)
{
kpg.initialize(bits);
keypair = kpg.generateKeyPair();
publickey = keypair.getPublic();
privateKey = keypair.getPrivate();
KeyPair dup= keypair;
return dup;
}
public static csrgenerator getInstance() {
if (thisinstance == null)
thisinstance = new csrgenerator();
return thisinstance;
}
/**
* Returns a CSR as string
* #param cn Common Name
* #param OU Organizational Unit
* #param Org Organization
* #param LocName Location name
* #param Statename State/Territory/Province/Region
* #param Country Country
* #return returns csr as string.
* #throws Exception
*/
public String getCSR(String commonname, String organizationunit, String organization,String localname, String statename, String country ) throws Exception {
byte[] csr = generatePKCS10(commonname, organizationunit, organization, localname, statename, country,signaturealgorithm);
return new String(csr);
}
/** This function generates a new Certificate
* Signing Request.
*
* #param CN
* Common Name, is X.509 speak for the name that distinguishes
* the Certificate best, and ties it to your Organization
* #param OU
* Organizational unit
* #param O
* Organization NAME
* #param L
* Location
* #param S
* State
* #param C
* Country
* #return byte stream of generated request
* #throws Exception
*/
private static byte[] generatePKCS10(String CN, String OU, String O,String L, String S, String C,String sigAlg) throws Exception {
// generate PKCS10 certificate request
pkcs10 = new PKCS10(publickey);
Signature signature = Signature.getInstance(sigAlg);
signature.initSign(privateKey);
// common, orgUnit, org, locality, state, country
//X500Name(String commonName, String organizationUnit,String organizationName,Local,State, String country)
X500Name x500Name = new X500Name(CN, OU, O, L, S, C);
pkcs10.encodeAndSign(x500Name,signature);
bs = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bs);
pkcs10.print(ps);
byte[] c = bs.toByteArray();
try {
if (ps != null)
ps.close();
if (bs != null)
bs.close();
} catch (Throwable th) {
}
return c;
}
public PublicKey getPublicKey() {
return publickey;
}
/**
* #return
*/
public PrivateKey getPrivateKey() {
return privateKey;
}
/**
* saves private key to a file
* #param filename
*/
public void SavePrivateKey(String filename)
{
PKCS8EncodedKeySpec pemcontents=null;
pemcontents= new PKCS8EncodedKeySpec( privateKey.getEncoded());
PKCS8Key pemprivatekey= new PKCS8Key( );
try {
pemprivatekey.decode(pemcontents.getEncoded());
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File file=new File(filename);
try {
file.createNewFile();
FileOutputStream fos=new FileOutputStream(file);
fos.write(pemprivatekey.getEncoded());
fos.flush();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Saves Certificate Signing Request to a file;
* #param filename is a String containing full path to the file which will be created containing the CSR.
*/
public void SaveCSR(String filename)
{
FileOutputStream fos=null;
PrintStream ps=null;
File file;
try {
file = new File(filename);
file.createNewFile();
fos = new FileOutputStream(file);
ps= new PrintStream(fos);
}catch (IOException e)
{
System.out.print("\n could not open the file "+ filename);
}
try {
try {
pkcs10.print(ps);
} catch (SignatureException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ps.flush();
ps.close();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.print("\n cannot write to the file "+ filename);
e.printStackTrace();
}
}
/**
* Saves both public key and private key to file names specified
* #param fnpub file name of public key
* #param fnpri file name of private key
* #throws IOException
*/
public static void SaveKeyPair(String fnpub,String fnpri) throws IOException {
// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publickey.getEncoded());
FileOutputStream fos = new FileOutputStream(fnpub);
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
fos = new FileOutputStream(fnpri);
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
/**
* Reads a Private Key from a pem base64 encoded file.
* #param filename name of the file to read.
* #param algorithm Algorithm is usually "RSA"
* #return returns the privatekey which is read from the file;
* #throws Exception
*/
public PrivateKey getPemPrivateKey(String filename, String algorithm) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String temp = new String(keyBytes);
String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----", "");
privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
//System.out.println("Private key\n"+privKeyPEM);
BASE64Decoder b64=new BASE64Decoder();
byte[] decoded = b64.decodeBuffer(privKeyPEM);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePrivate(spec);
}
/**
* Saves the private key to a pem file.
* #param filename name of the file to write the key into
* #param key the Private key to save.
* #return String representation of the pkcs8 object.
* #throws Exception
*/
public String SavePemPrivateKey(String filename) throws Exception {
PrivateKey key=this.privateKey;
File f = new File(filename);
FileOutputStream fos = new FileOutputStream(f);
DataOutputStream dos = new DataOutputStream(fos);
byte[] keyBytes = key.getEncoded();
PKCS8Key pkcs8= new PKCS8Key();
pkcs8.decode(keyBytes);
byte[] b=pkcs8.encode();
BASE64Encoder b64=new BASE64Encoder();
String encoded = b64.encodeBuffer(b);
encoded= "-----BEGIN PRIVATE KEY-----\r\n" + encoded + "-----END PRIVATE KEY-----";
dos.writeBytes(encoded);
dos.flush();
dos.close();
//System.out.println("Private key\n"+privKeyPEM);
return pkcs8.toString();
}
/**
* Saves a public key to a base64 encoded pem file
* #param filename name of the file
* #param key public key to be saved
* #return string representation of the pkcs8 object.
* #throws Exception
*/
public String SavePemPublicKey(String filename) throws Exception {
PublicKey key=this.publickey;
File f = new File(filename);
FileOutputStream fos = new FileOutputStream(f);
DataOutputStream dos = new DataOutputStream(fos);
byte[] keyBytes = key.getEncoded();
BASE64Encoder b64=new BASE64Encoder();
String encoded = b64.encodeBuffer(keyBytes);
encoded= "-----BEGIN PUBLIC KEY-----\r\n" + encoded + "-----END PUBLIC KEY-----";
dos.writeBytes(encoded);
dos.flush();
dos.close();
//System.out.println("Private key\n"+privKeyPEM);
return encoded.toString();
}
/**
* reads a public key from a file
* #param filename name of the file to read
* #param algorithm is usually RSA
* #return the read public key
* #throws Exception
*/
public PublicKey getPemPublicKey(String filename, String algorithm) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String temp = new String(keyBytes);
String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
BASE64Decoder b64=new BASE64Decoder();
byte[] decoded = b64.decodeBuffer(publicKeyPEM);
X509EncodedKeySpec spec =
new X509EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePublic(spec);
}
public static void main(String[] args) throws Exception {
csrgenerator gcsr = csrgenerator.getInstance();
gcsr.setSignaturealgorithm("SHA512WithRSA");
System.out.println("Public Key:\n"+gcsr.getPublicKey().toString());
System.out.println("Private Key:\nAlgorithm: "+gcsr.getPrivateKey().getAlgorithm().toString());
System.out.println("Format:"+gcsr.getPrivateKey().getFormat().toString());
System.out.println("To String :"+gcsr.getPrivateKey().toString());
System.out.println("GetEncoded :"+gcsr.getPrivateKey().getEncoded().toString());
BASE64Encoder encoder= new BASE64Encoder();
String s=encoder.encodeBuffer(gcsr.getPrivateKey().getEncoded());
System.out.println("Base64:"+s+"\n");
String csr = gcsr.getCSR( "desphilboy#yahoo.com","baxshi az xodam", "Xodam","PointCook","VIC" ,"AU");
System.out.println("CSR Request Generated!!");
System.out.println(csr);
gcsr.SaveCSR("c:\\testdir\\javacsr.csr");
String p=gcsr.SavePemPrivateKey("c:\\testdir\\java_private.pem");
System.out.print(p);
p=gcsr.SavePemPublicKey("c:\\testdir\\java_public.pem");
privateKey= gcsr.getPemPrivateKey("c:\\testdir\\java_private.pem", "RSA");
BASE64Encoder encoder1= new BASE64Encoder();
String s1=encoder1.encodeBuffer(gcsr.getPrivateKey().getEncoded());
System.out.println("Private Key in Base64:"+s1+"\n");
System.out.print(p);
}
}
Once you have your key stored in a PEM file, you can read it back easily using PemObject and PemReader classes provided by BouncyCastle, as shown in this this tutorial.
Create a PemFile class that encapsulates file handling:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
public class PemFile {
private PemObject pemObject;
public PemFile(String filename) throws FileNotFoundException, IOException {
PemReader pemReader = new PemReader(new InputStreamReader(
new FileInputStream(filename)));
try {
this.pemObject = pemReader.readPemObject();
} finally {
pemReader.close();
}
}
public PemObject getPemObject() {
return pemObject;
}
}
Then instantiate private and public keys as usual:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Main {
protected final static Logger LOGGER = Logger.getLogger(Main.class);
public final static String RESOURCES_DIR = "src/main/resources/rsa-sample/";
public static void main(String[] args) throws FileNotFoundException,
IOException, NoSuchAlgorithmException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());
LOGGER.info("BouncyCastle provider added.");
KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
try {
PrivateKey priv = generatePrivateKey(factory, RESOURCES_DIR
+ "id_rsa");
LOGGER.info(String.format("Instantiated private key: %s", priv));
PublicKey pub = generatePublicKey(factory, RESOURCES_DIR
+ "id_rsa.pub");
LOGGER.info(String.format("Instantiated public key: %s", pub));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
private static PrivateKey generatePrivateKey(KeyFactory factory,
String filename) throws InvalidKeySpecException,
FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename);
byte[] content = pemFile.getPemObject().getContent();
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
return factory.generatePrivate(privKeySpec);
}
private static PublicKey generatePublicKey(KeyFactory factory,
String filename) throws InvalidKeySpecException,
FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename);
byte[] content = pemFile.getPemObject().getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return factory.generatePublic(pubKeySpec);
}
}
Hope this helps.
#Value("${spring.security.oauth2.resourceserver.jwt.key-value}")
RSAPublicKey key;
key-value can be uri (i.e. "classpath:keys/pub.pcks8.pem") or pem content.
you must include the following deps:
compile project(':spring-security-config')
compile project(':spring-security-oauth2-jose')
compile project(':spring-security-oauth2-resource-server')
Below code works absolutely fine to me and working. This code will read RSA private and public key though java code. You can refer to http://snipplr.com/view/18368/
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class Demo {
public static final String PRIVATE_KEY="/home/user/private.der";
public static final String PUBLIC_KEY="/home/user/public.der";
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
//get the private key
File file = new File(PRIVATE_KEY);
FileInputStream fis = new FileInputStream(file);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) file.length()];
dis.readFully(keyBytes);
dis.close();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(spec);
System.out.println("Exponent :" + privKey.getPrivateExponent());
System.out.println("Modulus" + privKey.getModulus());
//get the public key
File file1 = new File(PUBLIC_KEY);
FileInputStream fis1 = new FileInputStream(file1);
DataInputStream dis1 = new DataInputStream(fis1);
byte[] keyBytes1 = new byte[(int) file1.length()];
dis1.readFully(keyBytes1);
dis1.close();
X509EncodedKeySpec spec1 = new X509EncodedKeySpec(keyBytes1);
KeyFactory kf1 = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) kf1.generatePublic(spec1);
System.out.println("Exponent :" + pubKey.getPublicExponent());
System.out.println("Modulus" + pubKey.getModulus());
}
}

Categories

Resources