Class Crypto
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringECDSA over P-256 with SHA-256, and over P-384 with SHA-384.static final Stringstatic final intPBKDF2 iterations for a stored password.static final StringRSASSA-PSS over SHA-256 with MGF1-SHA-256 and a 32 byte salt.static final StringRSASSA-PKCS1-v1_5 over SHA-256, SHA-384 and SHA-512: the same bytes for the same key and message, every time.static final Stringstatic final Stringstatic final StringThe digest nameshmac(String, byte[], byte[])andpbkdf2(String, byte[], byte[], int, int)take.static final Stringstatic final Stringstatic final String -
Method Summary
Modifier and TypeMethodDescriptionstatic byte[]aesGcmDecrypt(byte[] key, byte[] iv, byte[] aad, byte[] sealed) Opens whataesGcmEncrypt(byte[], byte[], byte[], byte[])sealed.static byte[]aesGcmEncrypt(byte[] key, byte[] iv, byte[] aad, byte[] plaintext) AES-GCM.static booleanequalsConstantTime(byte[] a, byte[] b) Compares without leaking where two values first differ.static byte[]generateRsaKey(int bits) A new RSA private key as PKCS#8 DER, with the public exponent 65537.static StringhashPassword(String password) Hashes a password for storage.static byte[]static byte[]hmacSha256(byte[] key, byte[] data) static byte[]md5(byte[] data) MD5, for PostgreSQL's md5 authentication method.static byte[]static byte[]pbkdf2Sha256(byte[] password, byte[] salt, int iterations, int length) PBKDF2-HMAC-SHA-256.static byte[]randomBytes(int length) Cryptographically secure bytes.static byte[]sha1(byte[] data) SHA-1, for the wire protocols that specify it by name: MySQL's mysql_native_password, and the RFC 6455 4.2.2 websocket handshake, where the digest of the client key and a fixed GUID becomes Sec-WebSocket-Accept.static byte[]sha256(byte[] data) static byte[]sha384(byte[] data) SHA-384; null for null.static byte[]sha512(byte[] data) SHA-512; null for null.static byte[]static booleanChecks a signature against a public key in SubjectPublicKeyInfo DER.static booleanverifyPassword(String password, String stored) False for any malformed stored value rather than throwing.
-
Field Details
-
PASSWORD_ITERATIONS
public static final int PASSWORD_ITERATIONSPBKDF2 iterations for a stored password. Deliberately expensive: the cost is paid once per login and multiplied by every guess an attacker makes against a stolen table.- See Also:
-
SHA1
The digest nameshmac(String, byte[], byte[])andpbkdf2(String, byte[], byte[], int, int)take.- See Also:
-
SHA256
- See Also:
-
SHA384
- See Also:
-
SHA512
- See Also:
-
RS256
RSASSA-PKCS1-v1_5 over SHA-256, SHA-384 and SHA-512: the same bytes for the same key and message, every time.- See Also:
-
RS384
- See Also:
-
RS512
- See Also:
-
PS256
RSASSA-PSS over SHA-256 with MGF1-SHA-256 and a 32 byte salt.- See Also:
-
ES256
ECDSA over P-256 with SHA-256, and over P-384 with SHA-384.- See Also:
-
ES384
- See Also:
-
-
Method Details
-
sha256
public static byte[] sha256(byte[] data) -
sha1
public static byte[] sha1(byte[] data) SHA-1, for the wire protocols that specify it by name: MySQL's mysql_native_password, and the RFC 6455 4.2.2 websocket handshake, where the digest of the client key and a fixed GUID becomes Sec-WebSocket-Accept.
Never for anything this code CHOOSES: passwords go through
hashPassword(String)and tokens throughhmacSha256(byte[], byte[]). Both callers here are standards quoting the algorithm, and in neither is the result standing in for a signature -- the handshake value is a replay guard against caches and proxies, not an authenticator. -
md5
public static byte[] md5(byte[] data) MD5, for PostgreSQL's md5 authentication method. Seesha1(byte[]). -
pbkdf2Sha256
public static byte[] pbkdf2Sha256(byte[] password, byte[] salt, int iterations, int length) throws IOException PBKDF2-HMAC-SHA-256. Exposed because SCRAM-SHA-256 -- how PostgreSQL authenticates by default -- is defined in terms of it with the server's iteration count, whichhashPassword(String)does not let a caller choose.- Throws:
IOException
-
hmacSha256
public static byte[] hmacSha256(byte[] key, byte[] data) -
randomBytes
Cryptographically secure bytes. Throws rather than returning weak ones.- Throws:
IOException
-
equalsConstantTime
public static boolean equalsConstantTime(byte[] a, byte[] b) Compares without leaking where two values first differ. An early exit on the first differing byte lets a MAC be forged one byte at a time. -
hashPassword
Hashes a password for storage. Returns "pbkdf2$iterations$salt$hash" with both binary parts base64url-encoded, so the iteration count travels with the hash and can be raised later without invalidating existing rows.- Throws:
IOException
-
verifyPassword
-
sha384
public static byte[] sha384(byte[] data) SHA-384; null for null. -
sha512
public static byte[] sha512(byte[] data) SHA-512; null for null. -
hmac
HMAC over one ofSHA1,SHA256,SHA384andSHA512. SHA-1 is here for what specifies it by name -- a TOTP secret an authenticator application already holds, Spring's oldest password format -- and not for anything new.- Returns:
- the tag, or null when
keyordatais null - Throws:
IllegalArgumentException- for a digest that is not one of the four
-
pbkdf2
public static byte[] pbkdf2(String digest, byte[] password, byte[] salt, int iterations, int length) throws IOException PBKDF2 over HMAC with one ofSHA1,SHA256,SHA384andSHA512, on the password's bytes as they are given.- Throws:
IOException- when a count is not positive or derivation fails
-
sign
Signs
datawith a private key in PKCS#8 DER, under one ofRS256,RS384,RS512,PS256,ES256andES384.The key has to be of the kind the algorithm is defined over: an RSA key for the first four, a P-256 key for ES256, a P-384 key for ES384. Any other pairing is refused rather than adapted to.
An ECDSA signature is returned as ASN.1 DER, the SEQUENCE of r and s both OpenSSL and the JDK produce. JOSE wants the two numbers side by side instead;
com.codename1.backend.security.crypto.Derconverts.- Throws:
IOException- when the key cannot be read, does not fit the algorithm, or signing fails
-
verify
public static boolean verify(String algorithm, byte[] publicKey, byte[] data, byte[] signature) throws IOException Checks a signature against a public key in SubjectPublicKeyInfo DER. The algorithms and the pairing of key and algorithm are those ofsign(String, byte[], byte[]), and an ECDSA signature is given as ASN.1 DER.- Returns:
- true when
signatureis that key's signature ofdata; false when it is not, whatever is wrong with it - Throws:
IOException- when the question could not be asked: the key cannot be read or does not fit the algorithm. A key that is broken is never reported as a signature that is forged.
-
generateRsaKey
A new RSA private key as PKCS#8 DER, with the public exponent 65537.
For a development profile, so a server that signs tokens starts without a key file. A key made at start-up is gone at the next one, and every token signed with it stops verifying: a deployed server loads its key.
- Parameters:
bits- 2048 to 8192- Throws:
IOException
-
aesGcmEncrypt
public static byte[] aesGcmEncrypt(byte[] key, byte[] iv, byte[] aad, byte[] plaintext) throws IOException AES-GCM. The result is the ciphertext followed by the 16 byte tag.
The nonce must never repeat under one key: 12 bytes from
randomBytes(int)for each call is the ordinary way, stored beside the result.- Parameters:
key- 16, 24 or 32 bytesiv- the nonce; 12 bytes unless a protocol says otherwiseaad- data that is authenticated and not encrypted; null for none- Throws:
IOException
-
aesGcmDecrypt
public static byte[] aesGcmDecrypt(byte[] key, byte[] iv, byte[] aad, byte[] sealed) throws IOException Opens whataesGcmEncrypt(byte[], byte[], byte[], byte[])sealed.- Returns:
- the plaintext, or null when the tag does not match: the key, the nonce, the associated data or the sealed bytes are not the ones it was made with
- Throws:
IOException- when the sizes are not ones AES-GCM has
-