JAVA-8282: Moved 5 articles from core-java-security-2 module to new
module core-java-security-algorithms
This commit is contained in:
parent
37961b7d27
commit
da99f980b8
|
@ -0,0 +1,52 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>core-java-security-algorithms</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>core-java-security-algorithms</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
|
<artifactId>core-java-modules</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>${commons-codec.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
|
<version>${bouncycastle.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj-core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
<version>${jaxb-api.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- util -->
|
||||||
|
<bouncycastle.version>1.60</bouncycastle.version>
|
||||||
|
<commons-codec.version>1.11</commons-codec.version>
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj-core.version>3.18.0</assertj-core.version>
|
||||||
|
<jaxb-api.version>2.3.1</jaxb-api.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,156 @@
|
||||||
|
package com.baeldung.aes;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.KeyGenerator;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.SealedObject;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.spec.KeySpec;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class AESUtil {
|
||||||
|
|
||||||
|
public static String encrypt(String algorithm, String input, SecretKey key, IvParameterSpec iv)
|
||||||
|
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
|
||||||
|
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance(algorithm);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
||||||
|
byte[] cipherText = cipher.doFinal(input.getBytes());
|
||||||
|
return Base64.getEncoder()
|
||||||
|
.encodeToString(cipherText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decrypt(String algorithm, String cipherText, SecretKey key, IvParameterSpec iv)
|
||||||
|
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
|
||||||
|
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance(algorithm);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
||||||
|
byte[] plainText = cipher.doFinal(Base64.getDecoder()
|
||||||
|
.decode(cipherText));
|
||||||
|
return new String(plainText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SecretKey generateKey(int n) throws NoSuchAlgorithmException {
|
||||||
|
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||||
|
keyGenerator.init(n);
|
||||||
|
SecretKey key = keyGenerator.generateKey();
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SecretKey getKeyFromPassword(String password, String salt)
|
||||||
|
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||||
|
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||||
|
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 256);
|
||||||
|
SecretKey secret = new SecretKeySpec(factory.generateSecret(spec)
|
||||||
|
.getEncoded(), "AES");
|
||||||
|
return secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IvParameterSpec generateIv() {
|
||||||
|
byte[] iv = new byte[16];
|
||||||
|
new SecureRandom().nextBytes(iv);
|
||||||
|
return new IvParameterSpec(iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void encryptFile(String algorithm, SecretKey key, IvParameterSpec iv,
|
||||||
|
File inputFile, File outputFile) throws IOException, NoSuchPaddingException,
|
||||||
|
NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException,
|
||||||
|
BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance(algorithm);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
||||||
|
FileInputStream inputStream = new FileInputStream(inputFile);
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(outputFile);
|
||||||
|
byte[] buffer = new byte[64];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
byte[] output = cipher.update(buffer, 0, bytesRead);
|
||||||
|
if (output != null) {
|
||||||
|
outputStream.write(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] outputBytes = cipher.doFinal();
|
||||||
|
if (outputBytes != null) {
|
||||||
|
outputStream.write(outputBytes);
|
||||||
|
}
|
||||||
|
inputStream.close();
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void decryptFile(String algorithm, SecretKey key, IvParameterSpec iv,
|
||||||
|
File encryptedFile, File decryptedFile) throws IOException, NoSuchPaddingException,
|
||||||
|
NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException,
|
||||||
|
BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance(algorithm);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
||||||
|
FileInputStream inputStream = new FileInputStream(encryptedFile);
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(decryptedFile);
|
||||||
|
byte[] buffer = new byte[64];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
byte[] output = cipher.update(buffer, 0, bytesRead);
|
||||||
|
if (output != null) {
|
||||||
|
outputStream.write(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] output = cipher.doFinal();
|
||||||
|
if (output != null) {
|
||||||
|
outputStream.write(output);
|
||||||
|
}
|
||||||
|
inputStream.close();
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SealedObject encryptObject(String algorithm, Serializable object, SecretKey key,
|
||||||
|
IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException,
|
||||||
|
InvalidAlgorithmParameterException, InvalidKeyException, IOException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance(algorithm);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
||||||
|
SealedObject sealedObject = new SealedObject(object, cipher);
|
||||||
|
return sealedObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Serializable decryptObject(String algorithm, SealedObject sealedObject, SecretKey key,
|
||||||
|
IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException,
|
||||||
|
InvalidAlgorithmParameterException, InvalidKeyException, ClassNotFoundException,
|
||||||
|
BadPaddingException, IllegalBlockSizeException, IOException {
|
||||||
|
Cipher cipher = Cipher.getInstance(algorithm);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
||||||
|
Serializable unsealObject = (Serializable) sealedObject.getObject(cipher);
|
||||||
|
return unsealObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encryptPasswordBased(String plainText, SecretKey key, IvParameterSpec iv)
|
||||||
|
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
|
||||||
|
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
||||||
|
return Base64.getEncoder()
|
||||||
|
.encodeToString(cipher.doFinal(plainText.getBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decryptPasswordBased(String cipherText, SecretKey key, IvParameterSpec iv)
|
||||||
|
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
|
||||||
|
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
||||||
|
return new String(cipher.doFinal(Base64.getDecoder()
|
||||||
|
.decode(cipherText)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.aes;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class Student implements Serializable {
|
||||||
|
private String name;
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
public Student(String name, int age) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
Student student = (Student) o;
|
||||||
|
return age == student.age && Objects.equals(name, student.name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.baeldung.aes;
|
||||||
|
|
||||||
|
import org.assertj.core.api.WithAssertions;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.crypto.SealedObject;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
|
||||||
|
class AESUtilUnitTest implements WithAssertions {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenEncrypt_thenSuccess()
|
||||||
|
throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException,
|
||||||
|
BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException {
|
||||||
|
// given
|
||||||
|
String input = "baeldung";
|
||||||
|
SecretKey key = AESUtil.generateKey(128);
|
||||||
|
IvParameterSpec ivParameterSpec = AESUtil.generateIv();
|
||||||
|
String algorithm = "AES/CBC/PKCS5Padding";
|
||||||
|
|
||||||
|
// when
|
||||||
|
String cipherText = AESUtil.encrypt(algorithm, input, key, ivParameterSpec);
|
||||||
|
String plainText = AESUtil.decrypt(algorithm, cipherText, key, ivParameterSpec);
|
||||||
|
|
||||||
|
// then
|
||||||
|
Assertions.assertEquals(input, plainText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenFile_whenEncrypt_thenSuccess()
|
||||||
|
throws NoSuchAlgorithmException, IOException, IllegalBlockSizeException, InvalidKeyException,
|
||||||
|
BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException {
|
||||||
|
// given
|
||||||
|
SecretKey key = AESUtil.generateKey(128);
|
||||||
|
String algorithm = "AES/CBC/PKCS5Padding";
|
||||||
|
IvParameterSpec ivParameterSpec = AESUtil.generateIv();
|
||||||
|
File inputFile = Paths.get("src/test/resources/baeldung.txt")
|
||||||
|
.toFile();
|
||||||
|
File encryptedFile = new File("classpath:baeldung.encrypted");
|
||||||
|
File decryptedFile = new File("document.decrypted");
|
||||||
|
|
||||||
|
// when
|
||||||
|
AESUtil.encryptFile(algorithm, key, ivParameterSpec, inputFile, encryptedFile);
|
||||||
|
AESUtil.decryptFile(algorithm, key, ivParameterSpec, encryptedFile, decryptedFile);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(inputFile).hasSameTextualContentAs(decryptedFile);
|
||||||
|
encryptedFile.delete();
|
||||||
|
decryptedFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenObject_whenEncrypt_thenSuccess()
|
||||||
|
throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException,
|
||||||
|
InvalidAlgorithmParameterException, NoSuchPaddingException, IOException, BadPaddingException,
|
||||||
|
ClassNotFoundException {
|
||||||
|
// given
|
||||||
|
Student student = new Student("Baeldung", 20);
|
||||||
|
SecretKey key = AESUtil.generateKey(128);
|
||||||
|
IvParameterSpec ivParameterSpec = AESUtil.generateIv();
|
||||||
|
String algorithm = "AES/CBC/PKCS5Padding";
|
||||||
|
|
||||||
|
// when
|
||||||
|
SealedObject sealedObject = AESUtil.encryptObject(algorithm, student, key, ivParameterSpec);
|
||||||
|
Student object = (Student) AESUtil.decryptObject(algorithm, sealedObject, key, ivParameterSpec);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(student).isEqualTo(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenPassword_whenEncrypt_thenSuccess()
|
||||||
|
throws InvalidKeySpecException, NoSuchAlgorithmException, IllegalBlockSizeException,
|
||||||
|
InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException {
|
||||||
|
// given
|
||||||
|
String plainText = "www.baeldung.com";
|
||||||
|
String password = "baeldung";
|
||||||
|
String salt = "12345678";
|
||||||
|
IvParameterSpec ivParameterSpec = AESUtil.generateIv();
|
||||||
|
SecretKey key = AESUtil.getKeyFromPassword(password, salt);
|
||||||
|
|
||||||
|
// when
|
||||||
|
String cipherText = AESUtil.encryptPasswordBased(plainText, key, ivParameterSpec);
|
||||||
|
String decryptedCipherText = AESUtil.decryptPasswordBased(cipherText, key, ivParameterSpec);
|
||||||
|
|
||||||
|
// then
|
||||||
|
Assertions.assertEquals(plainText, decryptedCipherText);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.baeldung.cipher;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class AvailableCiphersUnitTest {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(AvailableCiphersUnitTest.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetServices_thenGetAllCipherAlgorithms() {
|
||||||
|
for (Provider provider : Security.getProviders()) {
|
||||||
|
for (Provider.Service service : provider.getServices()) {
|
||||||
|
logger.info(service.getAlgorithm());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetServicesWithFilter_thenGetAllCompatibleCipherAlgorithms() {
|
||||||
|
List<String> algorithms = Arrays.stream(Security.getProviders())
|
||||||
|
.flatMap(provider -> provider.getServices().stream())
|
||||||
|
.filter(service -> "Cipher".equals(service.getType()))
|
||||||
|
.map(Provider.Service::getAlgorithm)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
algorithms.forEach(logger::info);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package com.baeldung.des;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class TripleDESUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void given3DesKey_whenEncryptAndDecryptString_thenCompareResults() throws Exception {
|
||||||
|
byte[] secretKey = "9mng65v8jf4lxn93nabf981m".getBytes();
|
||||||
|
byte[] iv = "a76nb5h9".getBytes();
|
||||||
|
|
||||||
|
String secretMessage = "Baeldung secret message";
|
||||||
|
|
||||||
|
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "DESede");
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
Cipher encryptCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
|
||||||
|
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
|
||||||
|
byte[] secretMessagesBytes = secretMessage.getBytes(StandardCharsets.UTF_8);
|
||||||
|
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessagesBytes);
|
||||||
|
|
||||||
|
Cipher decryptCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
|
||||||
|
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
|
||||||
|
byte[] decryptedMessageBytes = decryptCipher.doFinal(encryptedMessageBytes);
|
||||||
|
String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
Assertions.assertEquals(secretMessage, decryptedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void given3DesKey_whenEncryptAndDecryptFile_thenCompareResults() throws Exception {
|
||||||
|
byte[] secretKey = "9mng65v8jf4lxn93nabf981m".getBytes();
|
||||||
|
byte[] iv = "a76nb5h9".getBytes();
|
||||||
|
|
||||||
|
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "DESede");
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
|
||||||
|
String originalContent = "some secret message";
|
||||||
|
Path tempFile = Files.createTempFile("temp", "txt");
|
||||||
|
writeString(tempFile, originalContent);
|
||||||
|
|
||||||
|
byte[] fileBytes = Files.readAllBytes(tempFile);
|
||||||
|
Cipher encryptCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
|
||||||
|
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
|
||||||
|
byte[] encryptedFileBytes = encryptCipher.doFinal(fileBytes);
|
||||||
|
try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
|
||||||
|
stream.write(encryptedFileBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedFileBytes = Files.readAllBytes(tempFile);
|
||||||
|
Cipher decryptCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
|
||||||
|
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
|
||||||
|
byte[] decryptedFileBytes = decryptCipher.doFinal(encryptedFileBytes);
|
||||||
|
try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
|
||||||
|
stream.write(decryptedFileBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileContent = readString(tempFile);
|
||||||
|
|
||||||
|
Assertions.assertEquals(originalContent, fileContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeString(Path path, String content) throws Exception {
|
||||||
|
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
|
||||||
|
writer.write(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readString(Path path) throws Exception {
|
||||||
|
StringBuilder resultStringBuilder = new StringBuilder();
|
||||||
|
try (BufferedReader br = new BufferedReader(new FileReader(path.toFile()))) {
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
resultStringBuilder.append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultStringBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.baeldung.rsa;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
public class RsaUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRsaKeyPair_whenEncryptAndDecryptString_thenCompareResults() throws Exception {
|
||||||
|
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
|
||||||
|
generator.initialize(2048);
|
||||||
|
KeyPair pair = generator.generateKeyPair();
|
||||||
|
PrivateKey privateKey = pair.getPrivate();
|
||||||
|
PublicKey publicKey = pair.getPublic();
|
||||||
|
|
||||||
|
String secretMessage = "Baeldung secret message";
|
||||||
|
Cipher encryptCipher = Cipher.getInstance("RSA");
|
||||||
|
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
byte[] secretMessageBytes = secretMessage.getBytes(StandardCharsets.UTF_8);
|
||||||
|
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
|
||||||
|
|
||||||
|
Cipher decryptCipher = Cipher.getInstance("RSA");
|
||||||
|
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
|
byte[] decryptedMessageBytes = decryptCipher.doFinal(encryptedMessageBytes);
|
||||||
|
String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
Assertions.assertEquals(secretMessage, decryptedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRsaKeyPair_whenEncryptAndDecryptFile_thenCompareResults() throws Exception {
|
||||||
|
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
|
||||||
|
generator.initialize(2048);
|
||||||
|
KeyPair pair = generator.generateKeyPair();
|
||||||
|
PrivateKey privateKey = pair.getPrivate();
|
||||||
|
PublicKey publicKey = pair.getPublic();
|
||||||
|
|
||||||
|
String originalContent = "some secret message";
|
||||||
|
Path tempFile = Files.createTempFile("temp", "txt");
|
||||||
|
writeString(tempFile, originalContent);
|
||||||
|
|
||||||
|
byte[] fileBytes = Files.readAllBytes(tempFile);
|
||||||
|
Cipher encryptCipher = Cipher.getInstance("RSA");
|
||||||
|
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
byte[] encryptedFileBytes = encryptCipher.doFinal(fileBytes);
|
||||||
|
try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
|
||||||
|
stream.write(encryptedFileBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedFileBytes = Files.readAllBytes(tempFile);
|
||||||
|
Cipher decryptCipher = Cipher.getInstance("RSA");
|
||||||
|
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
|
byte[] decryptedFileBytes = decryptCipher.doFinal(encryptedFileBytes);
|
||||||
|
try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
|
||||||
|
stream.write(decryptedFileBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileContent = readString(tempFile);
|
||||||
|
|
||||||
|
Assertions.assertEquals(originalContent, fileContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeString(Path path, String content) throws Exception {
|
||||||
|
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
|
||||||
|
writer.write(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readString(Path path) throws Exception {
|
||||||
|
StringBuilder resultStringBuilder = new StringBuilder();
|
||||||
|
try (BufferedReader br = new BufferedReader(new FileReader(path.toFile()))) {
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
resultStringBuilder.append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultStringBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue