Standard library Encryption Signatures

Cryptography

klyn.cryptography provides secure random generation, message digests, HMAC, PBKDF2, authenticated AES encryption, and RSA encryption and signatures. Prefer the concrete algorithm classes so security choices remain visible in source code.

Choose the Correct Primitive
GoalRecommended API
Random token, key, IV, or saltSecureRandom or a key generator
Content fingerprintSHA256, SHA512, or a SHA-3 digest
Authenticate a message with a shared secretHmac
Derive key material from a passwordPBKDF2 and PBEKeySpec
Encrypt application data symmetricallyCipher.aesGcmEncrypt()
Sign data with an RSA private keyRSAPSSSignature
Encoding is not encryption

Base64 and hexadecimal only represent bytes as text. They provide no confidentiality, integrity, password protection, or authenticity.

Generate Security-Sensitive Random Values
import klyn.cryptography

random = SecureRandom()

csrfToken = random.nextUrlBase64(32)
salt = random.nextBase64(16)
identifier = random.nextHex(16)

print(csrfToken)

Sizes are expressed in random bytes before encoding. nextUrlBase64() is convenient for URLs and cookies; nextHex() is convenient for identifiers. Never substitute klyn.math.Random for this class.

Hash Text and Files
import klyn.cryptography

digest = SHA256().digestInfo("hello")

print(digest.hex)
print(digest.base64)
assert digest.sizeBits == 256

fileDigest = SHA3_256().digestFileInfo("release.kar")
print(fileDigest.hex)

digest() returns raw Byte[]; digestInfo() returns a Digest with hexadecimal and Base64 representations. update() accepts several text chunks and the buffer is reset after the digest is produced.

Legacy algorithms

MD5 and SHA1 remain available for compatibility checks, not for signatures, password storage, certificates, or adversarial integrity. Prefer SHA-256, SHA-512, or SHA-3 for new code.

Authenticate Messages with HMAC
import klyn.cryptography

mac = Hmac(SHA256())
mac.init("application-secret")
signature = mac.doFinal("payload")

verifier = Hmac(SHA256())
verifier.init("application-secret")
assert verifier.verify("payload", signature.hex)

The key encoding defaults to UTF-8 and may be set to hex, base64, or base64url. Use independent secret keys for independent protocols; do not reuse an encryption key as an HMAC key.

Derive Keys from Passwords
import klyn.cryptography

random = SecureRandom()
salt = random.nextBase64(16)

spec = PBEKeySpec(
    "correct horse battery staple",
    salt,
    iterations=100000,
    sizeBytes=32,
    saltEncoding="base64"
)

derivedKey = PBKDF2(SHA256()).generateSecret(spec)
print(derivedKey)

Store the salt, iteration count, output size, and algorithm with the derived value. Salts are public and must be unique; passwords and derived keys are secrets. Select the iteration count from a measured security policy and raise it as deployment hardware evolves.

Encrypt with AES-GCM
import klyn.cryptography

generator = AESKeyGenerator()
generator.initialize(256)
key = generator.generateKey()

payload = Cipher.aesGcmEncrypt(
    "confidential text",
    key,
    aad="article:42"
)

plainText = Cipher.aesGcmDecrypt(
    payload,
    key,
    aad="article:42"
)

assert plainText == "confidential text"
assert payload.authenticated

The generated key and payload fields are transport-safe strings. A random nonce is generated when no IV is supplied. AES-GCM authenticates both ciphertext and optional additional data; decryption fails if the key, nonce, tag, ciphertext, or AAD differs.

Prefer authenticated encryption

CBC and CTR modes are available for protocol compatibility but do not authenticate their ciphertext by themselves. Use GCM for new application formats unless an externally specified protocol requires another construction and supplies its own integrity protection.

Generate and Use RSA Keys
import klyn.cryptography

generator = RSAKeyPairGenerator()
generator.initialize(2048)
keys = generator.generateKeyPair()

signer = RSAPSSSignature(SHA256())
signer.initSign(keys.privateKeyPem)
token = signer.sign("release manifest")

verifier = RSAPSSSignature(SHA256())
verifier.initVerify(keys.publicKeyPem)
assert verifier.verify(token, "release manifest")

RSA keys are returned in PEM format. RSA-PSS is the preferred signature mode for new formats; RSAPKCS1Signature supports protocols that require PKCS#1 v1.5 signatures. The separate Cipher.rsaEncrypt() API defaults to OAEP with SHA-256 and is intended for small payloads, not bulk data.

Encode Text Safely
import klyn.cryptography

base64 = Base64.encodeText("Klyn")
hex = Hex.encodeText("Klyn")

assert Base64.decodeToText(base64) == "Klyn"
assert Hex.decodeToText(hex) == "Klyn"

These helpers are text-oriented. Crypto result objects already expose appropriate encoded fields; avoid decoding arbitrary binary ciphertext as text.

Operational Security Rules
  • Keep private keys, passwords, and symmetric keys out of source control and logs.
  • Use independent keys for encryption, MAC, signing, and separate application domains.
  • Never reuse an AES-GCM nonce with the same key.
  • Authenticate before acting on decrypted or received data.
  • Preserve the original CryptoException when an operation fails; do not return unauthenticated fallback data.
  • Rotate keys and version encrypted formats so older data can be migrated deliberately.