KeyPairGeneratorDefault.java
package org.linkedopenactors.rdfpub.adapter.driven;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.Key;
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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
class KeyPairGeneratorDefault implements org.linkedopenactors.rdfpub.app.actor.KeyPairGenerator {
private String keypairHomeDir;
private static final String algorithm = "RSA";
public KeyPairGeneratorDefault(@Value("${app.keypairHome}") String keypairHomeDir) {
this.keypairHomeDir = keypairHomeDir;
File dir = new File(keypairHomeDir);
if(!dir.exists()) {
dir.mkdirs();
}
}
@Override
public PublicKey generate(String identifier) {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(algorithm);
kpg.initialize(512);
KeyPair kp = kpg.generateKeyPair();
savePrivateKey(identifier, kp.getPrivate());
savePublicKey(identifier, kp.getPublic());
return getPublicKey(identifier);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("unable to generate keypair", e);
}
}
@Override
public PrivateKey getPrivateKey(String identifierParam) {
String identifier = encode(identifierParam);
try {
byte[] bytes = FileUtils.readFileToByteArray(new File(getPrivateKeyFileName(identifier)));
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePrivate(ks);
} catch (Exception e) {
String message = "unable to load private key file";
log.error(message, e);
throw new IllegalStateException(message, e);
}
}
@Override
public PublicKey getPublicKey(String identifier) {
try {
byte[] bytes = FileUtils.readFileToByteArray(new File(getPublicKeyFileName(identifier)));
X509EncodedKeySpec ks = new X509EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePublic(ks);
} catch (Exception e) {
String message = "unable to load public key file";
log.error(message, e);
throw new IllegalStateException(message, e);
}
}
@Override
public String getPublicKeyBase64Encoded(String identifierParam) {
String identifier = encode(identifierParam);
Base64.Encoder encoder = Base64.getEncoder();
String result = "-----BEGIN RSA PUBLIC KEY-----\n";
result += encoder.encodeToString(getPublicKey(identifier).getEncoded());
result += "\n-----END RSA PUBLIC KEY-----";
return result;
}
private String encode(String storeName) {
try {
String encoded = URLEncoder.encode(storeName, StandardCharsets.UTF_8.toString());
log.debug("encoded: " + encoded);
return encoded;
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Unable to encode storeName: " + storeName, e);
}
}
private String savePublicKey(String identifier, Key publicKey) {
try {
String outFile = getPublicKeyFileName(identifier);
OutputStream out = new FileOutputStream(new File(outFile));
out.write(publicKey.getEncoded());
out.close();
return outFile;
} catch (Exception e) {
log.error("unable to save private key", e);
throw new IllegalStateException("unable to save private key", e);
}
}
private String savePrivateKey(String identifier, Key pvt) {
try {
String outFile = getPrivateKeyFileName(identifier);
FileOutputStream out = new FileOutputStream(outFile);
out.write(pvt.getEncoded());
out.close();
return outFile;
} catch (Exception e) {
String message = "unable to save private key";
log.error(message, e);
throw new IllegalStateException(message, e);
}
}
public String getPrivateKeyFileName(String identifier) {
String outFile = keypairHomeDir + "/" + identifier + ".private.key";
return outFile;
}
private String getPublicKeyFileName(String identifier) {
String outFile = keypairHomeDir + "/" + identifier + ".public.key";
return outFile;
}
}