Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

Commit

Permalink
java: Add AesException
Browse files Browse the repository at this point in the history
  • Loading branch information
M3DZIK committed Oct 22, 2023
1 parent 8e762e9 commit d530a9e
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 46 deletions.
41 changes: 21 additions & 20 deletions java/src/main/java/dev/medzik/libcrypto/Aes.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package dev.medzik.libcrypto;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;

public final class Aes {
Expand All @@ -20,12 +14,14 @@ public final class Aes {

/**
* Encrypts the given clear bytes using AES with the given key and random IV.
*
* @param type AES type to use
* @param key secret key to use for encryption
* @param clearBytes clear bytes to encrypt (UTF-8)
* @return Encrypted cipher (hex encoded)
* @throws AesException if encryption fails
*/
public static String encrypt(AesType type, byte[] key, byte[] clearBytes) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
public static String encrypt(AesType type, byte[] key, byte[] clearBytes) throws AesException {
// generate random IV
byte[] iv = Random.randBytes(type.getIvLength());

Expand All @@ -37,28 +33,32 @@ public static String encrypt(AesType type, byte[] key, byte[] clearBytes) throws
try {
cipher = Cipher.getInstance(type.getMode());
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
} catch (InvalidAlgorithmParameterException |
NoSuchPaddingException |
NoSuchAlgorithmException e) {
// never happen
throw new RuntimeException(e);
} catch (Exception e) {
throw new AesException("Failed to init cipher", e);
}

// encrypt
byte[] cipherBytes = cipher.doFinal(clearBytes);
byte[] cipherBytes;
try {
cipherBytes = cipher.doFinal(clearBytes);
} catch (Exception e) {
throw new AesException("Failed to finalize encryption", e);
}

// return IV + cipher text as hex string
return Hex.encode(iv) + Hex.encode(cipherBytes);
}

/**
* Decrypts the given cipher text using AES with the given key.
*
* @param type AES type to use
* @param key secret key to use for decryption
* @param cipherText cipher text to decrypt (hex encoded)
* @return Decrypted bytes
* @throws AesException if decryption fails
*/
public static byte[] decrypt(AesType type, byte[] key, String cipherText) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
public static byte[] decrypt(AesType type, byte[] key, String cipherText) throws AesException {
// get IV length in hex string
int ivLength = type.getIvLength() * 2;

Expand All @@ -74,15 +74,16 @@ public static byte[] decrypt(AesType type, byte[] key, String cipherText) throws
try {
cipher = Cipher.getInstance(type.getMode());
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec);
} catch (InvalidAlgorithmParameterException |
NoSuchPaddingException |
NoSuchAlgorithmException e) {
// never happen
throw new RuntimeException(e);
} catch (Exception e) {
throw new AesException("Failed to init cipher", e);
}

// decrypt
return cipher.doFinal(cipherBytes);
try {
return cipher.doFinal(cipherBytes);
} catch (Exception e) {
throw new AesException("Failed to finalize decryption", e);
}
}

private static AlgorithmParameterSpec getParameterSpec(AesType type, byte[] iv) {
Expand Down
7 changes: 7 additions & 0 deletions java/src/main/java/dev/medzik/libcrypto/AesException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package dev.medzik.libcrypto;

public class AesException extends Exception {
public AesException(String message, Exception cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public final class Argon2EncodingUtils {

/**
* Encodes the given hash and parameters to a string.
*
* @param hash hash to encode
* @return encoded hash in argon2 format
*/
Expand Down Expand Up @@ -42,6 +43,7 @@ public static String encode(Argon2Hash hash) {

/**
* Decodes the given Argon2 encoded hash.
*
* @param encodedHash encoded hash in argon2 format
* @return {@link Argon2Hash}
*/
Expand Down
4 changes: 1 addition & 3 deletions java/src/main/java/dev/medzik/libcrypto/Argon2Hash.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package dev.medzik.libcrypto;

/**
* Object representation of argon2 hash.
*/
/** Object representation of argon2 hash. */
public final class Argon2Hash {
private final Argon2Type type;
private final int version;
Expand Down
4 changes: 2 additions & 2 deletions java/src/main/java/dev/medzik/libcrypto/Argon2Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public Argon2 toPassword4jType() {
return Argon2.I;
case ID:
return Argon2.ID;
default:
throw new IllegalStateException("Unexpected value: " + this);
}
// never happens
return null;
}
}
5 changes: 4 additions & 1 deletion java/src/main/java/dev/medzik/libcrypto/Hex.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ public static String encode(byte[] bytes) {
return result.toString();
}

/** Decodes a hex string to a byte array. */
/**
* Decodes a hex string to a byte array.
* @throws IllegalArgumentException if the input is not hexadecimal
*/
public static byte[] decode(String hex) {
if (hex.length() % 2 != 0) {
throw new IllegalArgumentException("Expected a string of even length");
Expand Down
9 changes: 3 additions & 6 deletions java/src/main/java/dev/medzik/libcrypto/Random.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
import java.security.SecureRandom;

public final class Random {
/**
* Generate a random byte array.
* @param size length of salt slice in bytes
*/
public static byte[] randBytes(int size) {
/** Generate a random byte array. */
public static byte[] randBytes(int length) {
SecureRandom rd = new SecureRandom();
byte[] salt = new byte[size];
byte[] salt = new byte[length];
rd.nextBytes(salt);
return salt;
}
Expand Down
3 changes: 1 addition & 2 deletions java/src/main/java/dev/medzik/libcrypto/X25519.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ public static byte[] generatePrivateKey() {
* @return 32-byte shared secret
* @throws InvalidKeyException when {@code ourPrivate} is not 32-byte or {@code theirPublic} is invalid.
*/
public static byte[] computeSharedSecret(byte[] ourPrivate, byte[] theirPublic)
throws InvalidKeyException {
public static byte[] computeSharedSecret(byte[] ourPrivate, byte[] theirPublic) throws InvalidKeyException {
if (ourPrivate.length != Field25519.FIELD_LEN) {
throw new InvalidKeyException("Private key must have 32 bytes.");
}
Expand Down
12 changes: 4 additions & 8 deletions java/src/test/java/dev/medzik/libcrypto/AesTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@

import org.junit.jupiter.api.Test;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import java.security.InvalidKeyException;

import static org.junit.jupiter.api.Assertions.assertEquals;

public final class AesTests {
@Test
public void testCBCEncryptAndDecrypt() throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
public void testCBCEncryptAndDecrypt() throws AesException {
byte[] secretKey = Hex.decode("82fd4cefd6efde36171900b469bae4e06863cb70f80b4e216e44eeb0cf30460b");

String input = "Hello World!";
Expand All @@ -21,7 +17,7 @@ public void testCBCEncryptAndDecrypt() throws IllegalBlockSizeException, BadPadd
}

@Test
public void testCBCDecrypt() throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
public void testCBCDecrypt() throws AesException {
byte[] secretKey = Hex.decode("82fd4cefd6efde36171900b469bae4e06863cb70f80b4e216e44eeb0cf30460b");

String cipherText = "ae77d812f4494a766a94b5dff8e7aa3c8408544b9fd30cd13b886cc5dd1b190e";
Expand All @@ -31,7 +27,7 @@ public void testCBCDecrypt() throws IllegalBlockSizeException, BadPaddingExcepti
}

@Test
public void testGCMEncryptAndDecrypt() throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
public void testGCMEncryptAndDecrypt() throws AesException {
byte[] secretKey = Hex.decode("82fd4cefd6efde36171900b469bae4e06863cb70f80b4e216e44eeb0cf30460b");

String input = "Hello World!";
Expand All @@ -42,7 +38,7 @@ public void testGCMEncryptAndDecrypt() throws IllegalBlockSizeException, BadPadd
}

@Test
void testGCMDecrypt() throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
void testGCMDecrypt() throws AesException {
byte[] secretKey = Hex.decode("82fd4cefd6efde36171900b469bae4e06863cb70f80b4e216e44eeb0cf30460b");

String cipherText = "0996c65a72a60e748415dc6d32da1d4dcb65f41c71d4bec9554424218839b5d4b9d9195e5eea9d";
Expand Down
6 changes: 2 additions & 4 deletions java/src/test/java/dev/medzik/libcrypto/ReadmeTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

import org.junit.jupiter.api.Test;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import java.security.InvalidKeyException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public final class ReadmeTests {
@Test
public void testAesGcmEncryptDecryption() throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
public void testAesGcmEncryptDecryption() throws AesException {
String clearText = "hello world";
// Key used for encryption (for example, argon2 hash in hex string)
String secretKey = "82fd4cefd6efde36171900b469bae4e06863cb70f80b4e216e44eeb0cf30460b";
Expand Down Expand Up @@ -47,7 +45,7 @@ public void testArgon2Hash() {
}

@Test
public void testX25519ExchangeKeys() throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
public void testX25519ExchangeKeys() throws InvalidKeyException, AesException {
// Generate private key for Bob
byte[] bobPrivateKey = X25519.generatePrivateKey();
byte[] bobPublicKey = X25519.publicFromPrivate(bobPrivateKey);
Expand Down

0 comments on commit d530a9e

Please sign in to comment.