public static CryptoEngine getEngine() { boolean limitedEngine = false; try { limitedEngine = Cipher.getMaxAllowedKeyLength("AES") < STRONG_ENGINE_LIMIT; } catch (NoSuchAlgorithmException e) { LOG.error("No support for AES encryption", e); } LOG.debug("Creating crypto engine, can use strong keys: {}", !limitedEngine); return limitedEngine ? new BasicCryptoEngine() : new StrongCryptoEngine(); }
@Override public User getUser(String userName, String sourceHost, String password) throws JasDBStorageException { User user = userMetadataProvider.getUser(userName); LOG.debug("Expected host: {} actual: {}", user.getHost(), sourceHost); CryptoEngine cryptoEngine = CryptoFactory.getEngine(user.getEncryptionEngine()); if(user.getPasswordHash().equals(cryptoEngine.hash(user.getPasswordSalt(), password)) && (user.getHost().equals("*") || user.getHost().equals(sourceHost))) { LOG.debug("User: {} has been authenticated", user); return user; } else { throw new JasDBSecurityException("Could not authenticate, invalid credentials"); } }
@Override public String encrypt(String salt, String password, String textToEncrypt) throws JasDBSecurityException { String standardPass = getStandardizedPassword(password); PBEKeySpec keySpec = new PBEKeySpec(standardPass.toCharArray(), Hex.decode(salt), 1024, 128); try { byte[] iv = new byte[IV_SIZE]; secureRandom.nextBytes(iv); SecretKey secretKey = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(keySpec).getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv)); byte[] encrypted = cipher.doFinal(textToEncrypt.getBytes(UTF8)); return new String(Hex.encode(appendArrays(iv, encrypted))); } catch (InvalidKeySpecException e) { throw new JasDBSecurityException("Unable to encrypt", e); } catch (NoSuchAlgorithmException e) { throw new JasDBSecurityException("Unable to encrypt", e); } catch (NoSuchPaddingException e) { throw new JasDBSecurityException("Unable to encrypt", e); } catch (InvalidAlgorithmParameterException e) { throw new JasDBSecurityException("Unable to encrypt", e); } catch (InvalidKeyException e) { throw new JasDBSecurityException("Unable to encrypt", e); } catch (BadPaddingException e) { throw new JasDBSecurityException("Unable to encrypt", e); } catch (IllegalBlockSizeException e) { throw new JasDBSecurityException("Unable to encrypt", e); } }
@Override public String decrypt(String salt, String password, String encryptedText) throws JasDBSecurityException { String standardPass = getStandardizedPassword(password); byte[] encryptedData = Hex.decode(encryptedText); byte[] iv = new byte[IV_SIZE];
public SecureUserSession(UserSession userSession) { this.sessionId = userSession.getSessionId(); this.user = userSession.getUser(); this.encryptedContentKey = userSession.getEncryptedContentKey(); try { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); accessTokenHash = cryptoEngine.hash(sessionId, userSession.getAccessToken()); } catch(JasDBSecurityException e) { throw new RuntimeJasDBException("Unable to hash token", e); } }
public static CryptoEngine getEngine(String engineDescriptor) throws JasDBStorageException { if(StrongCryptoEngine.STRONG_CRYPTO.equals(engineDescriptor)) { return new StrongCryptoEngine(); } else if(BasicCryptoEngine.BASIC_CRYPTO.equals(engineDescriptor)) { return new BasicCryptoEngine(); } else { throw new JasDBStorageException("Unsupport encryption engine: " + engineDescriptor); } } }
@Override public UserSession startSession(Credentials credentials) throws JasDBStorageException { User user = userManager.authenticate(credentials); String sessionId = UUID.randomUUID().toString(); String token = UUID.randomUUID().toString(); CryptoEngine userEncryptionEngine = CryptoFactory.getEngine(user.getEncryptionEngine()); String encryptedContentKey = user.getEncryptedContentKey(); String contentKey = userEncryptionEngine.decrypt(user.getPasswordSalt(), credentials.getPassword(), encryptedContentKey); encryptedContentKey = userEncryptionEngine.encrypt(user.getPasswordSalt(), token, contentKey); UserSession session = new UserSessionImpl(sessionId, token, encryptedContentKey, user); userManager.authorize(session, "/", AccessMode.CONNECT); secureUserSessionMap.put(sessionId, new SecureUserSession(session)); return session; }
private GrantObject decrypt(UserSession session, EncryptedGrants encryptedGrants) throws JasDBStorageException { CryptoEngine contentCryptoEngine = CryptoFactory.getEngine(); String contentKey = contentCryptoEngine.decrypt(session.getUser().getPasswordSalt(), session.getAccessToken(), session.getEncryptedContentKey()); CryptoEngine cryptoEngine = CryptoFactory.getEngine(encryptedGrants.getEncryptionEngine()); String decryptedData = cryptoEngine.decrypt(encryptedGrants.getSalt(), contentKey, encryptedGrants.getEncryptedData()); return GrantObjectMeta.fromEntity(SimpleEntity.fromJson(decryptedData)); }
@Override public User addUser(UserSession currentSession, String userName, String allowedHost, String password) throws JasDBStorageException { authorize(currentSession, "/Users", AccessMode.WRITE); User currentUser = currentSession.getUser(); CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String contentKey = cryptoEngine.decrypt(currentUser.getPasswordSalt(), currentSession.getAccessToken(), currentSession.getEncryptedContentKey()); return credentialsProvider.addUser(userName, allowedHost, contentKey, password); }
@Override public User addUser(String userName, String allowedHost, String contentKey, String password) throws JasDBStorageException { if(!userMetadataProvider.hasUser(userName)) { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String salt = cryptoEngine.generateSalt(); String encryptedContentKey = cryptoEngine.encrypt(salt, password, contentKey); String passwordHash = cryptoEngine.hash(salt, password); User user = new UserMeta(userName, allowedHost, encryptedContentKey, salt, passwordHash, cryptoEngine.getDescriptor()); userMetadataProvider.addUser(user); return user; } else { return userMetadataProvider.getUser(userName); } } }
private EncryptedGrants encryptGrants(GrantObject grantObject, UserSession userSession) throws JasDBStorageException { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String contentKey = CryptoFactory.getEngine().decrypt(userSession.getUser().getPasswordSalt(), userSession.getAccessToken(), userSession.getEncryptedContentKey()); String salt = cryptoEngine.generateSalt(); String unencryptedData = SimpleEntity.toJson(GrantObjectMeta.toEntity(grantObject)); String encryptedData = cryptoEngine.encrypt(salt, contentKey, unencryptedData); return new EncryptedGrants(grantObject.getObjectName(), encryptedData, salt, cryptoEngine.getDescriptor()); }
private void checkToken(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws IOException, ServletException { try { String token = httpServletRequest.getHeader("oauth_token"); String sessionId = httpServletRequest.getHeader("sessionid"); LOG.debug("Token: {} for session: {}", token, sessionId); if(StringUtils.stringNotEmpty(token) && StringUtils.stringNotEmpty(sessionId)) { UserSession session = sessionManager.getSession(sessionId); if(session != null) { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String expectedTokenHash = cryptoEngine.hash(sessionId, token); if (expectedTokenHash.equals(session.getAccessToken())) { httpServletRequest.setAttribute("session", new UserSessionImpl(sessionId, token, session.getEncryptedContentKey(), session.getUser())); filterChain.doFilter(httpServletRequest, httpServletResponse); } else { handleErrorResponse(httpServletResponse, UNAUTHORIZED_CODE, "Invalid token"); } } else { handleErrorResponse(httpServletResponse, UNAUTHORIZED_CODE, "Invalid token"); } } else { handleErrorResponse(httpServletResponse, UNAUTHORIZED_CODE, "No token"); } } catch(JasDBStorageException e) { LOG.error("Unknown error happened when processing token", e); handleErrorResponse(httpServletResponse, 500, "Unknown error"); } }
private void createMandatoryAdminUser() throws JasDBStorageException { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String salt = cryptoEngine.generateSalt(); String contentKey = cryptoEngine.generateSalt(); String encryptedContentKey = cryptoEngine.encrypt(salt, "", contentKey); User user = new UserMeta("admin", "localhost", encryptedContentKey, salt, cryptoEngine.hash(salt, ""), cryptoEngine.getDescriptor()); userMetadataProvider.addUser(user); Grant grant = new GrantMeta("admin", AccessMode.ADMIN); GrantObjectMeta grantsMeta = new GrantObjectMeta(Constants.OBJECT_SEPARATOR, grant); String unencryptedGrants = SimpleEntity.toJson(GrantObjectMeta.toEntity(grantsMeta)); String encryptedGrants = cryptoEngine.encrypt(salt, contentKey, unencryptedGrants); EncryptedGrants grants = new EncryptedGrants(grantsMeta.getObjectName(), encryptedGrants, salt, cryptoEngine.getDescriptor()); grantMetadataProvider.persistGrant(grants); }