Class Crypto
java.lang.Object
com.codename1.backend.Crypto
The crypto a server needs to authenticate a request. Every primitive comes from
OpenSSL, which the backend already links for outbound TLS - none of it is
implemented here, because hand-rolled HMAC and hand-rolled password hashing are
the two most reliable ways to ship an authentication system that looks correct
and is not.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intPBKDF2 iterations for a stored password. -
Method Summary
Modifier and TypeMethodDescriptionstatic booleanequalsConstantTime(byte[] a, byte[] b) Compares without leaking where two values first differ.static StringhashPassword(String password) Hashes a password for storage.static byte[]hmacSha256(byte[] key, byte[] data) static byte[]md5(byte[] data) MD5, for PostgreSQL's md5 authentication method.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 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:
-
-
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
-