UGEncrypt Library

A Java library implementing RSA encryption with OAEP padding restricted to 2048-bit keys and provided for pedagogical purposes. It should not be used in production.

Download

The library is available here UGEncrypt.java.

Key Generation

The first step is to generate a pair of keys (public and private) using the static generate() method:

var keyPair = UGEncrypt.KeyPairRSA.generate();
var publicKey = keyPair.publicKey();   // For encryption
var privateKey = keyPair.privateKey(); // For decryption

This generates a 2048-bit RSA key pair.

Message Encryption

With a public key, you can encrypt messages:

ByteBuffer message = StandardCharsets.UTF_8.encode("Hello, RSA!");
ByteBuffer encrypted = ByteBuffer.allocate(UGEncrypt.KEY_SIZE_BYTES);
publicKey.encrypt(message, encrypted);
Important: Due to OAEP padding with SHA-256, messages must not exceed 190 bytes (UGEncrypt.MAX_ENCRYPT_BLOCK_SIZE).

Message Decryption

The holder of the private key can decrypt messages:

ByteBuffer decrypted = ByteBuffer.allocate(UGEncrypt.KEY_SIZE_BYTES);
privateKey.decrypt(encrypted.flip(), decrypted);
String result = StandardCharsets.UTF_8.decode(decrypted.flip()).toString();

Key Serialization

Keys can be serialized to and from ByteBuffers for storage or transmission:

Public Key (X.509 Format)

Public keys are encoded using the X.509 format as specified in RFC 5280:

// Serialize public key
ByteBuffer pubBuffer = ByteBuffer.allocate(UGEncrypt.MAX_PUBLIC_KEY_SIZE);
publicKey.to(pubBuffer);

// Deserialize public key
PublicKeyRSA recoveredPubKey = PublicKeyRSA.from(pubBuffer.flip());

Private Key (PKCS#8 Format)

Private keys are encoded using the PKCS#8 format as specified in RFC 5208:

// Serialize private key
ByteBuffer privBuffer = ByteBuffer.allocate(UGEncrypt.MAX_PRIVATE_KEY_SIZE);
privateKey.to(privBuffer);

// Deserialize private key
PrivateKeyRSA recoveredPrivKey = PrivateKeyRSA.from(privBuffer.flip());
Security Note: The encryption is non-deterministic due to OAEP padding. Encrypting the same message twice will produce different ciphertexts, but both will decrypt to the original message.