Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.
public final class Crypto
- Object
- Crypto
Fields
public static final int PASSWORD_ITERATIONS = 210000 | PBKDF2 iterations for a stored password. |
public static final String SHA1 = "SHA-1" | The digest names hmac and pbkdf2 take. |
public static final String SHA256 = "SHA-256" | |
public static final String SHA384 = "SHA-384" | |
public static final String SHA512 = "SHA-512" | |
public static final String RS256 = "RS256" | RSASSA-PKCS1-v1_5 over SHA-256, SHA-384 and SHA-512: the same bytes for the same key and message, every time. |
public static final String RS384 = "RS384" | |
public static final String RS512 = "RS512" | |
public static final String PS256 = "PS256" | RSASSA-PSS over SHA-256 with MGF1-SHA-256 and a 32 byte salt. |
public static final String ES256 = "ES256" | ECDSA over P-256 with SHA-256, and over P-384 with SHA-384. |
public static final String ES384 = "ES384" |
Methods
Inherited methods
Field details
PASSWORD_ITERATIONS
public static final int PASSWORD_ITERATIONS = 210000SHA1
public static final String SHA1 = "SHA-1"SHA256
public static final String SHA256 = "SHA-256"SHA384
public static final String SHA384 = "SHA-384"SHA512
public static final String SHA512 = "SHA-512"RS256
public static final String RS256 = "RS256"RS384
public static final String RS384 = "RS384"RS512
public static final String RS512 = "RS512"PS256
public static final String PS256 = "PS256"ES256
public static final String ES256 = "ES256"ES384
public static final String ES384 = "ES384"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 and tokens through hmacSha256. 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)sha1.pbkdf2Sha256
public static byte[] pbkdf2Sha256(byte[] password, byte[] salt, int iterations, int length)
throws IOExceptionhashPassword does not let a caller choose.Throws
hmacSha256
public static byte[] hmacSha256(byte[] key, byte[] data)randomBytes
public static byte[] randomBytes(int length)
throws IOExceptionThrows
equalsConstantTime
public static boolean equalsConstantTime(byte[] a, byte[] b)hashPassword
public static String hashPassword(String password)
throws IOExceptionThrows
verifyPassword
public static boolean verifyPassword(String password, String stored)sha384
public static byte[] sha384(byte[] data)sha512
public static byte[] sha512(byte[] data)hmac
public static byte[] hmac(String digest, byte[] key, byte[] data)SHA1, SHA256, SHA384 and SHA512. 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
key or data is nullThrows
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 IOExceptionSHA1, SHA256, SHA384 and SHA512,
on the password’s bytes as they are given.Throws
IOException- when a count is not positive or derivation fails
sign
public static byte[] sign(String algorithm, byte[] privateKey, byte[] data)
throws IOExceptionSigns data with a private key in PKCS#8 DER, under one of RS256,
RS384, RS512, PS256, ES256 and ES384.
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.Der converts.
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 IOExceptionsign, and
an ECDSA signature is given as ASN.1 DER.Returns
signature is that key’s signature of data; false
when it is not, whatever is wrong with itThrows
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
public static byte[] generateRsaKey(int bits)
throws IOExceptionA 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
bitsint- 2048 to 8192
Throws
aesGcmEncrypt
public static byte[] aesGcmEncrypt(byte[] key, byte[] iv, byte[] aad, byte[] plaintext)
throws IOExceptionAES-GCM. The result is the ciphertext followed by the 16 byte tag.
The nonce must never repeat under one key: 12 bytes from randomBytes
for each call is the ordinary way, stored beside the result.
Parameters
keybyte[]- 16, 24 or 32 bytes
ivbyte[]- the nonce; 12 bytes unless a protocol says otherwise
aadbyte[]- data that is authenticated and not encrypted; null for none
plaintextbyte[]- Not documented.
Throws
aesGcmDecrypt
public static byte[] aesGcmDecrypt(byte[] key, byte[] iv, byte[] aad, byte[] sealed)
throws IOExceptionaesGcmEncrypt sealed.Returns
Throws
IOException- when the sizes are not ones AES-GCM has