RSA encryption / decryption with java 8

environment

background

I want to encrypt / decrypt RSA with java8! It is assumed that the Wicket-encrypted request will be decrypted later.

2048bit key preparation

--Private key generation

console


openssl genrsa -out rsa_2048_priv.pem 2048

--Public key generation

console


openssl rsa -pubout -in rsa_2048_priv.pem -out rsa_2048_pub.pem

Save the generated file in the resource folder

Encryption / decryption class

RSAUtil.java


public final class RSAUtil {

	public static final Logger logger = LoggerFactory.getLogger(RSAUtil.class);
	public static ConcurrentHashMap<String, PublicKey> pubCache = new ConcurrentHashMap<String, PublicKey>();
	public static ConcurrentHashMap<Object, PrivateKey> priCache = new ConcurrentHashMap<Object, PrivateKey>();

	/**
	 *RSA encryption with public key
	 * @param plain
	 * @param key
	 * @return
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 * @throws UnsupportedEncodingException
	 * @throws InvalidKeyException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 */
	public static String encryptWithPublicKey(String plain, PublicKey key) throws IllegalBlockSizeException,
			BadPaddingException, UnsupportedEncodingException, InvalidKeyException,
			NoSuchAlgorithmException, NoSuchPaddingException {

		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, key);

		byte[] plainBytes = plain.getBytes("UTF-8");
		String result = Base64.encodeBase64String(cipher.doFinal(plainBytes));
		return result;
	}

	/**
	 *RSA decryption with private key
	 * @param encrypted
	 * @param key
	 * @return
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 * @throws UnsupportedEncodingException
	 * @throws InvalidKeyException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 */
	public static String decryptWithPrivateKey(String encrypted, PrivateKey key) throws IllegalBlockSizeException,
			BadPaddingException, UnsupportedEncodingException, InvalidKeyException,
			NoSuchAlgorithmException, NoSuchPaddingException {

		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, key);

		byte[] encryptedBytes = Base64.decodeBase64(encrypted);
		String result = new String(cipher.doFinal(encryptedBytes), "UTF-8");
		return result;
	}

	/**
	 *Read the public key from the pem file
	 * @param filename
	 * @return
	 */
	public static PublicKey readPublicKeyFromPem(String filename) {
		PublicKey key = null;
		InputStream is = null;

		// check cache
		if (pubCache.containsKey(filename)) {
			key = (PublicKey) pubCache.get(filename);
			if (key != null) {
				return key;
			}
		}

		try {
			is = RSAUtil.class.getClassLoader().getResourceAsStream(filename);
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			StringBuilder sb = new StringBuilder();
			boolean inKey = false;

			for (String line = br.readLine(); line != null; line = br.readLine()) {
				if (!inKey) {
					if (line.startsWith("-----BEGIN ") && line.endsWith(" PUBLIC KEY-----")) {
						inKey = true;
					}
					continue;
				}
				else {
					if (line.startsWith("-----BEGIN ") && line.endsWith(" PUBLIC KEY-----")) {
						inKey = false;
						break;
					}
					else {
						sb.append(line);
					}
				}
			}
			byte[] decoded = DatatypeConverter.parseBase64Binary(sb.toString());
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
			KeyFactory kf = KeyFactory.getInstance("RSA");
			key = kf.generatePublic(keySpec);

			pubCache.put(filename, key);
		}
		catch (Exception e) {
			StringWriter sw = new StringWriter();
			e.printStackTrace(new PrintWriter(sw));
			logger.error("ERROR:\n"+sw.toString());
		}
		finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {}
			}
		}
		return key;
	}

	/**
	 *Read the private key from the pem file
	 * @param filename
	 * @return
	 */
	public static PrivateKey readPrvateKeyFromPem(String filename) {
		PrivateKey key = null;
		InputStream is = null;
		boolean isRSAKey = false;

		if (priCache.containsKey(filename)) {
			key = (PrivateKey) priCache.get(filename);
			if (key != null) {
				return key;
			}
		}

		try {
			is = RSAUtil.class.getClassLoader().getResourceAsStream(filename);
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			StringBuilder sb = new StringBuilder();
			boolean inKey = false;

			for (String line = br.readLine(); line != null; line = br.readLine()) {
				if (!inKey) {
					if (line.startsWith("-----BEGIN ") && line.endsWith(" PRIVATE KEY-----")) {
						inKey = true;
						isRSAKey = line.contains("RSA");
					}
					continue;
				}
				else {
					if (line.startsWith("-----BEGIN ") && line.endsWith(" PRIVATE KEY-----")) {
						inKey = false;
						isRSAKey = line.contains("RSA");
						break;
					}
					else {
						sb.append(line);
					}
				}
			}
			byte[] decoded = DatatypeConverter.parseBase64Binary(sb.toString());
			KeySpec keySpec = null;
			if (isRSAKey) {
				DerInputStream derReader = new DerInputStream(decoded);
				DerValue[] seq = derReader.getSequence(0);
				if (seq.length < 9) {
					throw new GeneralSecurityException("Could not parse a PKCS1 private key.");
				}
				// skip version seq[0]
				BigInteger modulus = seq[1].getBigInteger();
				BigInteger publicExp = seq[2].getBigInteger();
				BigInteger privateExp = seq[3].getBigInteger();
				BigInteger prime1 = seq[4].getBigInteger();
				BigInteger prime2 = seq[5].getBigInteger();
				BigInteger exponent1 = seq[6].getBigInteger();
				BigInteger exponent2 = seq[7].getBigInteger();
				BigInteger crtCoef = seq[8].getBigInteger();

				keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2,
						exponent1, exponent2, crtCoef);
			} else {
				keySpec = new PKCS8EncodedKeySpec(decoded);
			}
			KeyFactory kf = KeyFactory.getInstance("RSA");
			key = kf.generatePrivate(keySpec);

			priCache.put(filename, key);
		}
		catch (Exception e) {
			StringWriter sw = new StringWriter();
			e.printStackTrace(new PrintWriter(sw));
			logger.error("ERROR:\n"+sw.toString());
		}
		finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {}
			}
		}
		return key;
	}
}

Try using

TestRSAEncryptDecrypt.java


public class TestRSAEncryptDecrypt {

	public static void main(String[] args) {

		final String prvPemfile = "rsa_2048_priv.pem";
		final String pubPemFile = "rsa_2048_pub.pem";

		final String plain = "THIS is a test.";

		PublicKey pubKey = RSAUtil.readPublicKeyFromPem(pubPemFile);
		PrivateKey prvKey = RSAUtil.readPrvateKeyFromPem(prvPemfile);

		String encrypted = "";
		try {
			encrypted = RSAUtil.encryptWithPublicKey(plain, pubKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("Encrypted:" + encrypted);

		String decrypted = "";
		try {
			decrypted = RSAUtil.decryptWithPrivateKey(encrypted, prvKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("Decrypted:" + decrypted);
	}

}

result

console


Encrypted:P3X8B1A+N+MEt7+oSLZ+FsbpS1ddkXIz1zpiDAuTf6/EDEPK9ozPZ+VGeaKvDucj3tkVX5YLvXU4psApuyt/NGHlzbAQryaArUGxK7Ol8Nfpp+l5yUwwi2EG6J85QZWtigH8ITmjvIf+lO8676kyg7snF2MXsIx2fNoen4A8bO8gDJ5/Dh4RkPFT8AUZFz4chVQ4whl1vdegHNO2qWj8x3+2UegqGO7QIE6P57BHGbsyF/3Dpept7Gr1NFUpN43DYA/h+IgRu0OeLCx6sss0MWokK1C+1OOam59pEpNhefIV8wzCaag7N+SfSBXGKViGN25vBfOUhC7dZfYheX7BUQ==
Decrypted:THIS is a test.

Recommended Posts

RSA encryption / decryption with java 8
RSA key pair creation / encryption / decryption sample (JAVA)
KMS) Envelope encryption with openssl and java decryption
Java encryption and decryption PDF
Java encryption, decryption of Word documents
Achieve OpenSSL compatible encryption with Java / PHP
Install java with Homebrew
Change seats with java
Install Java with Ansible
Comfortable download with JAVA
Switch java with direnv
Download Java with Ansible
Let's scrape with Java! !!
Build Java with Wercker
Endian conversion with JAVA
[Java] How to encrypt with AES encryption with standard library
Easy BDD with (Java) Spectrum?
Use Lambda Layers with Java
Java multi-project creation with Gradle
Getting Started with Java Collection
Java Config with Spring MVC
Basic Authentication with Java 11 HttpClient
Run batch with docker-compose with Java batch
[Template] MySQL connection with Java
Install Java 7 with Homebrew (cask)
[Java] JSON communication with jackson
Try DB connection with Java
Enable Java EE with NetBeans 9
[Java] JavaConfig with Static InnerClass
Try gRPC with Java, Maven
Let's operate Excel with Java! !!
Version control Java with SDKMAN
Paging PDF with Java + PDFBox.jar
Sort strings functionally with java
Object-oriented (java) with Strike Gundam
[Java] Content acquisition with HttpCliient
Java version control with jenv
Troubleshooting with Java Flight Recorder
Streamline Java testing with Spock
Connect to DB with Java
Connect to MySQL 8 with Java
Error when playing with java
Using Mapper with Java (Spring)
Java study memo 2 with Progate
Getting Started with Java Basics
Seasonal display with Java switch
Use SpatiaLite with Java / JDBC
Study Java with Progate Note 1
Compare Java 8 Optional with Swift
HTML parsing with JAVA (scraping)
Run Java VM with WebAssembly
Screen transition with swing, java
Java unit tests with Mockito
How to encrypt and decrypt with RSA public key in Java
Create an immutable class with JAVA
Java lambda expressions learned with Comparator
SpringSecurity TextEncryptor: Common key encryption / decryption
[Java, Scala] Image resizing with ImageIO
Build a Java project with Gradle
Install java with Ubuntu 16.04 based Docker
Java to learn with ramen [Part 1]