Example usage for javax.crypto Mac doFinal

List of usage examples for javax.crypto Mac doFinal

Introduction

In this page you can find the example usage for javax.crypto Mac doFinal.

Prototype

public final byte[] doFinal() throws IllegalStateException 

Source Link

Document

Finishes the MAC operation.

Usage

From source file:org.cryptomator.crypto.aes256.Aes256Cryptor.java

@Override
public Long encryptFile(InputStream plaintextFile, SeekableByteChannel encryptedFile) throws IOException {
    // truncate file
    encryptedFile.truncate(0);/*from   w  w  w . j a  va  2 s .c  o m*/

    // use an IV, whose last 8 bytes store a long used in counter mode and write initial value to file.
    final ByteBuffer countingIv = ByteBuffer.wrap(randomData(AES_BLOCK_LENGTH));
    countingIv.putLong(AES_BLOCK_LENGTH - Long.BYTES, 0l);
    countingIv.position(0);
    encryptedFile.write(countingIv);

    // init crypto stuff:
    final Mac mac = this.hmacSha256(hMacMasterKey);
    final Cipher cipher = this.aesCtrCipher(primaryMasterKey, countingIv.array(), Cipher.ENCRYPT_MODE);

    // init mac buffer and skip 32 bytes
    final ByteBuffer macBuffer = ByteBuffer.allocate(mac.getMacLength());
    encryptedFile.write(macBuffer);

    // init filesize buffer and skip 16 bytes
    final ByteBuffer encryptedFileSizeBuffer = ByteBuffer.allocate(AES_BLOCK_LENGTH);
    encryptedFile.write(encryptedFileSizeBuffer);

    // write content:
    final OutputStream out = new SeekableByteChannelOutputStream(encryptedFile);
    final OutputStream macOut = new MacOutputStream(out, mac);
    final OutputStream cipheredOut = new CipherOutputStream(macOut, cipher);
    final OutputStream blockSizeBufferedOut = new BufferedOutputStream(cipheredOut, AES_BLOCK_LENGTH);
    final Long plaintextSize = IOUtils.copyLarge(plaintextFile, blockSizeBufferedOut);

    // ensure total byte count is a multiple of the block size, in CTR mode:
    final int remainderToFillLastBlock = AES_BLOCK_LENGTH - (int) (plaintextSize % AES_BLOCK_LENGTH);
    blockSizeBufferedOut.write(new byte[remainderToFillLastBlock]);

    // append a few blocks of fake data:
    final int numberOfPlaintextBlocks = (int) Math.ceil(plaintextSize / AES_BLOCK_LENGTH);
    final int upToTenPercentFakeBlocks = (int) Math.ceil(Math.random() * 0.1 * numberOfPlaintextBlocks);
    final byte[] emptyBytes = new byte[AES_BLOCK_LENGTH];
    for (int i = 0; i < upToTenPercentFakeBlocks; i += AES_BLOCK_LENGTH) {
        blockSizeBufferedOut.write(emptyBytes);
    }
    blockSizeBufferedOut.flush();

    // write MAC of total ciphertext:
    macBuffer.position(0);
    macBuffer.put(mac.doFinal());
    macBuffer.position(0);
    encryptedFile.position(16); // right behind the IV
    encryptedFile.write(macBuffer); // 256 bit MAC

    // encrypt and write plaintextSize
    try {
        final ByteBuffer fileSizeBuffer = ByteBuffer.allocate(Long.BYTES);
        fileSizeBuffer.putLong(plaintextSize);
        final Cipher sizeCipher = aesEcbCipher(primaryMasterKey, Cipher.ENCRYPT_MODE);
        final byte[] encryptedFileSize = sizeCipher.doFinal(fileSizeBuffer.array());
        encryptedFileSizeBuffer.position(0);
        encryptedFileSizeBuffer.put(encryptedFileSize);
        encryptedFileSizeBuffer.position(0);
        encryptedFile.position(48); // right behind the IV and MAC
        encryptedFile.write(encryptedFileSizeBuffer);
    } catch (IllegalBlockSizeException | BadPaddingException e) {
        throw new IllegalStateException(
                "Block size must be valid, as padding is requested. BadPaddingException not possible in encrypt mode.",
                e);
    }

    return plaintextSize;
}

From source file:com.cloud.user.AccountManagerImpl.java

@Override
public UserAccount authenticateUser(String username, String password, Long domainId, String loginIpAddress,
        Map<String, Object[]> requestParameters) {
    UserAccount user = null;/*from   www . jav  a  2s.c  o  m*/
    if (password != null) {
        user = getUserAccount(username, password, domainId, requestParameters);
    } else {
        String key = _configDao.getValue("security.singlesignon.key");
        if (key == null) {
            // the SSO key is gone, don't authenticate
            return null;
        }

        String singleSignOnTolerance = _configDao.getValue("security.singlesignon.tolerance.millis");
        if (singleSignOnTolerance == null) {
            // the SSO tolerance is gone (how much time before/after system time we'll allow the login request to be
            // valid),
            // don't authenticate
            return null;
        }

        long tolerance = Long.parseLong(singleSignOnTolerance);
        String signature = null;
        long timestamp = 0L;
        String unsignedRequest = null;

        // - build a request string with sorted params, make sure it's all lowercase
        // - sign the request, verify the signature is the same
        List<String> parameterNames = new ArrayList<String>();

        for (Object paramNameObj : requestParameters.keySet()) {
            parameterNames.add((String) paramNameObj); // put the name in a list that we'll sort later
        }

        Collections.sort(parameterNames);

        try {
            for (String paramName : parameterNames) {
                // parameters come as name/value pairs in the form String/String[]
                String paramValue = ((String[]) requestParameters.get(paramName))[0];

                if ("signature".equalsIgnoreCase(paramName)) {
                    signature = paramValue;
                } else {
                    if ("timestamp".equalsIgnoreCase(paramName)) {
                        String timestampStr = paramValue;
                        try {
                            // If the timestamp is in a valid range according to our tolerance, verify the request
                            // signature, otherwise return null to indicate authentication failure
                            timestamp = Long.parseLong(timestampStr);
                            long currentTime = System.currentTimeMillis();
                            if (Math.abs(currentTime - timestamp) > tolerance) {
                                if (s_logger.isDebugEnabled()) {
                                    s_logger.debug("Expired timestamp passed in to login, current time = "
                                            + currentTime + ", timestamp = " + timestamp);
                                }
                                return null;
                            }
                        } catch (NumberFormatException nfe) {
                            if (s_logger.isDebugEnabled()) {
                                s_logger.debug("Invalid timestamp passed in to login: " + timestampStr);
                            }
                            return null;
                        }
                    }

                    if (unsignedRequest == null) {
                        unsignedRequest = paramName + "="
                                + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20");
                    } else {
                        unsignedRequest = unsignedRequest + "&" + paramName + "="
                                + URLEncoder.encode(paramValue, "UTF-8").replaceAll("\\+", "%20");
                    }
                }
            }

            if ((signature == null) || (timestamp == 0L)) {
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Missing parameters in login request, signature = " + signature
                            + ", timestamp = " + timestamp);
                }
                return null;
            }

            unsignedRequest = unsignedRequest.toLowerCase();

            Mac mac = Mac.getInstance("HmacSHA1");
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            mac.init(keySpec);
            mac.update(unsignedRequest.getBytes());
            byte[] encryptedBytes = mac.doFinal();
            String computedSignature = new String(Base64.encodeBase64(encryptedBytes));
            boolean equalSig = signature.equals(computedSignature);
            if (!equalSig) {
                s_logger.info("User signature: " + signature + " is not equaled to computed signature: "
                        + computedSignature);
            } else {
                user = _userAccountDao.getUserAccount(username, domainId);
            }
        } catch (Exception ex) {
            s_logger.error("Exception authenticating user", ex);
            return null;
        }
    }

    if (user != null) {
        //don't allow to authenticate system user
        if (user.getId() == User.UID_SYSTEM) {
            s_logger.error("Failed to authenticate user: " + username + " in domain " + domainId);
            return null;
        }

        if (s_logger.isDebugEnabled()) {
            s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in");
        }
        if (NetUtils.isValidIp(loginIpAddress)) {
            EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(),
                    EventTypes.EVENT_USER_LOGIN, "user has logged in from IP Address " + loginIpAddress);
        } else {
            EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(),
                    EventTypes.EVENT_USER_LOGIN, "user has logged in. The IP Address cannot be determined");
        }
        return user;
    } else {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("User: " + username + " in domain " + domainId + " has failed to log in");
        }
        return null;
    }
}

From source file:com.cloud.server.ManagementServerImpl.java

private String signRequest(String request, String key) {
    try {/*from   w w  w  .  j a va  2  s  .com*/
        s_logger.info("Request: " + request);
        s_logger.info("Key: " + key);

        if (key != null && request != null) {
            Mac mac = Mac.getInstance("HmacSHA1");
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            mac.init(keySpec);
            mac.update(request.getBytes());
            byte[] encryptedBytes = mac.doFinal();
            return new String((Base64.encodeBase64(encryptedBytes)));
        }
    } catch (Exception ex) {
        s_logger.error("unable to sign request", ex);
    }
    return null;
}