Skip to content

Instantly share code, notes, and snippets.

@Romain-P
Created October 23, 2017 22:43
Show Gist options
  • Select an option

  • Save Romain-P/b657a129b522510b74670701dcb1fe89 to your computer and use it in GitHub Desktop.

Select an option

Save Romain-P/b657a129b522510b74670701dcb1fe89 to your computer and use it in GitHub Desktop.
package org.heat.shared;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.crypto.Cipher;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* @Author: romain.pillot
* @Date: 06/10/2017
*/
public class RsaHandler {
private final PrivateKey privateKey;
private final PublicKey publicKey;
private final String instance;
public static final String RSA_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";
/**
* Create a new org.heat.shared.RsaHandler with a base64-encoded key-pair.
*
* @param publicKey a nullable rsa public key. Don't call decrypt methods if there is no public key provided.
* @param privateKey a nullable rsa private key. Don't call encrypt methods if there is not private key provided.
*/
public RsaHandler(@Nullable String publicKey, @Nullable String privateKey, @Nonnull String instance) throws Exception {
this.publicKey = publicKey != null ? parsePublicKey(publicKey) : null;
this.privateKey = privateKey != null ? parsePrivateKey(privateKey) : null;
this.instance = instance;
}
/**
* @param plaintext human readable text to encrypt.
* @return the text encrypted from the private key (key format must be PKCS8)
* @throws RuntimeException in case of no private key provided.
*/
public String encrypt(String plaintext) throws Exception {
return Base64.getEncoder().encodeToString(encrypt(plaintext.getBytes(Charset.forName("UTF-8"))));
}
public byte[] encrypt(byte[] plainbytes) throws Exception {
if (this.privateKey == null)
throw new RuntimeException("Can't encrypt the message, you didn't specify the public key.");
Cipher cipher = Cipher.getInstance(instance);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(plainbytes);
}
/**
* @param cipherText encrypted text to make human readable.
* @return the text decrypted from the public key (key format must be X509)
* @throws RuntimeException in case of no public key provided.
*/
public String decrypt(String cipherText) throws Exception {
return new String(decrypt(Base64.getDecoder().decode(cipherText)), Charset.forName("UTF-8"));
}
public byte[] decrypt(byte[] cipherBytes) throws Exception {
if (this.publicKey == null)
throw new RuntimeException("Can't decrypt the message, you didn't specify the private key.");
Cipher cipher = Cipher.getInstance(instance);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(cipherBytes);
}
private PublicKey parsePublicKey(String base64Key) throws Exception {
byte[] bytes = Base64.getDecoder().decode(base64Key.getBytes());
KeySpec spec = new X509EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePublic(spec);
}
private PrivateKey parsePrivateKey(String base64key) throws Exception {
byte[] bytes = Base64.getDecoder().decode(base64key.getBytes());
KeySpec spec = new PKCS8EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePrivate(spec);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment