All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.security.CryptoUtils Maven / Gradle / Ivy

There is a newer version: 5.10.9
Show newest version
package org.yamcs.security;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class CryptoUtils {

    private static final SecureRandom RNG = new SecureRandom();

    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";

    private static final String PASSWORD_CHARS;
    static {
        String lower = "abcdefghijklmnopqrstuvwxyz";
        String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String number = "0123456789";
        String misc = "!@#$%&*()_+-=[]?";
        PASSWORD_CHARS = lower + upper + number + misc;
    }

    /**
     * Generates a difficult to guess random key via SecureRandom using the HmacSHA1 algorithm
     */
    public static byte[] generateRandomSecretKey() {
        try {
            KeyGenerator keyGen = KeyGenerator.getInstance(HMAC_SHA1_ALGORITHM);
            keyGen.init(RNG);
            SecretKey secretKey = keyGen.generateKey();
            return secretKey.getEncoded();
        } catch (NoSuchAlgorithmException e) {
            // Should not happen. HmacSHA1 is available in any JDK
            throw new UnsupportedOperationException(e);
        }
    }

    /**
     * Generates a random strong password.
     */
    public static String generateRandomPassword(int length) {
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            int idx = RNG.nextInt(PASSWORD_CHARS.length());
            sb.append(PASSWORD_CHARS.charAt(idx));
        }
        return sb.toString();
    }

    /**
     * Calculates an hmac as specified in RFC2104.
     */
    public static byte[] calculateHmac(String data, byte[] secret) {
        return calculateHmac(data.getBytes(StandardCharsets.UTF_8), secret);
    }

    /**
     * Calculates an hmac as specified in RFC2104.
     */
    public static byte[] calculateHmac(byte[] data, byte[] secret) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(secret, HMAC_SHA1_ALGORITHM);
            Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
            mac.init(signingKey);
            return mac.doFinal(data);
        } catch (NoSuchAlgorithmException e) {
            // Should not happen. HmacSHA1 is available in any JDK
            throw new UnsupportedOperationException(e);
        } catch (InvalidKeyException e) {
            // Should not happen. Key is specified in this method
            throw new UnsupportedOperationException(e);
        }
    }

    /**
     * Generates an OAuth 2.0 Proof Key for Code Exchange (PKCE) code challenge and verifier (RFC6736)
     * 
     * 
     * code_challenge = BASE64URLENCODE(SHA256(ASCII(code_verifier)))
     * 
*/ public static PKCE generatePKCE() { byte[] codeVerifierBytes = new byte[32]; RNG.nextBytes(codeVerifierBytes); PKCE pkce = new PKCE(); pkce.codeVerifier = Base64.getUrlEncoder().withoutPadding().encodeToString(codeVerifierBytes); try { byte[] bytes = pkce.codeVerifier.getBytes(StandardCharsets.US_ASCII); MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(bytes, 0, bytes.length); byte[] codeChallengeBytes = messageDigest.digest(); pkce.codeChallenge = Base64.getUrlEncoder().withoutPadding().encodeToString(codeChallengeBytes); } catch (NoSuchAlgorithmException e) { throw new UnsupportedOperationException(e); } return pkce; } public static final class PKCE { public String codeChallenge; public String codeVerifier; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy