Package net.chrislongo.hls

Source Code of net.chrislongo.hls.Crypto

/*
* Copyright (c) Christopher A Longo
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package net.chrislongo.hls;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.security.Security;

public class Crypto {
    private Cipher cipher;
    private String baseUrl;
    private String keyUrl;
    private byte[] key;
    private byte[] iv;

    boolean forceKey = false;

    public Crypto(String baseUrl) {
        this(baseUrl, null);
    }

    public Crypto(String baseUrl, String key) {
        this.baseUrl = baseUrl;

        if (key != null) {
            this.key = unpackHexString(key);
            forceKey = true;
        }
    }

    public CipherInputStream wrapInputStream(InputStream in) {
        return new CipherInputStream(in, cipher);
    }

    public boolean hasKey() {
        return (key != null);
    }

    public String getCurrentKey() {
        return arrayToString(key);
    }

    public String getCurrentIV() {
        return arrayToString(iv);
    }

    public void updateKeyString(String keyString) throws CryptoException {
        String[] parts = keyString.split(",");

        String newKeyUrl = parts[1].split("\"")[1];

        if (parts.length > 2) {
            String ivString = parts[2].split("0x")[1];
            iv = unpackHexString(ivString);
        } else {
            iv = new byte[16];
        }

        try {
            if (!forceKey && !newKeyUrl.equals(keyUrl)) {
                if (newKeyUrl.startsWith("http")) {
                    keyUrl = newKeyUrl;
                } else {
                    keyUrl = baseUrl + newKeyUrl;
                }

                fetchKey();
            }
        } catch (IOException e) {
            throw new CryptoException(e);
        }

        initCipher();
    }

    private void fetchKey() throws IOException {
        this.key = new byte[16];

        URLConnection con = new URL(this.keyUrl).openConnection();
        InputStream in = new BufferedInputStream(con.getInputStream());

        int read = 0;
        int offset = 0;

        while (offset < 16) {
            if ((read = in.read(this.key, offset, key.length - offset)) == -1)
                break;

            offset += read;
        }

        in.close();
    }

    private void initCipher() throws CryptoException {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        try {
            SecretKey secretKey = new SecretKeySpec(key, "AES");

            cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
        } catch (Exception e) {
            throw new CryptoException(e);
        }
    }

    private byte[] unpackHexString(String hexString) {
        byte[] array = new byte[16];

        BigInteger bigInt = new BigInteger(hexString, 16);
        BigInteger andValue = new BigInteger("ff", 16);

        for (int i = 0, index = 15; i < 16; i++, index--) {
            BigInteger shift = bigInt.shiftRight(i * 8);
            shift = shift.and(andValue);
            array[index] = shift.byteValue();
        }

        return array;
    }

    private String arrayToString(byte[] array) {
        StringBuilder sb = new StringBuilder();

        if (array != null) {
            for (byte b : array)
                sb.append(String.format("%02x", b));
        }

        return sb.toString();
    }

    @Override
    public String toString() {
        return "net.chrislongo.hls.Crypto{" +
                "cipher=" + cipher +
                ", keyUrl='" + keyUrl + '\'' +
                ", key=" + arrayToString(key) +
                ", iv=" + arrayToString(iv) +
                '}';
    }
}
TOP

Related Classes of net.chrislongo.hls.Crypto

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.