Se le pueden modificar ciertas cosas para descargar de otras cuentas.
Deben agregar la libreria de JSON.
/*******************************************************************************
* Copyright (c) 2013 Ale46.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* @NT2005 - initial API and implementation
******************************************************************************/
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class MegaCrypt {
private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
private static final int[] IA = new int[256];
static {
Arrays.fill(IA, -1);
for (int i = 0, iS = CA.length; i < iS; i++)
IA[CA[i]] = i;
IA['='] = 0;
}
public static long[] prepare_key_pw(String password) {
return prepare_key(str_to_a32(password));
}
public static long[] prepare_key(long[] password) {
long[] pkey = {0x93C467E3, 0x7DB0C7A4, 0xD1BE3F81, 0x0152CB56};
for (int r = 0; r < 0x10000; r++) {
for (int j = 0; j < password.length; j += 4) {
long[] key = {0, 0, 0, 0};
for (int i = 0; i < 4; i++) {
if (i + j < password.length) {
key[i] = password[i + j];
}
}
pkey = aes_cbc_encrypt_a32(pkey, key);
}
}
return pkey;
}
public static String stringhash(String email, long[] aeskey) {
long[] s32 = str_to_a32(email);
long[] h32 = {0, 0, 0, 0};
for (int i = 0; i < s32.length; i++) {
h32[i % 4] ^= s32[i];
}
for (int r = 0; r < 0x4000; r++) {
h32 = aes_cbc_encrypt_a32(h32, aeskey);
}
long[] h32Part = new long[2];
h32Part[0] = h32[0];
h32Part[1] = h32[2];
return a32_to_base64(h32Part);
}
public static byte[] aes_cbc_encrypt(byte[] data, byte[] key) {
String iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
byte[] output = null;
try {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
output = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return output;
}
public static long[] aes_cbc_encrypt_a32(long[] idata, long[] ikey) {
try {
byte[] data = a32_to_str(idata).getBytes("ISO-8859-1");
byte[] key = a32_to_str(ikey).getBytes("ISO-8859-1");
byte[] encrypt = aes_cbc_encrypt(data, key);
return str_to_a32(new String(encrypt, "ISO-8859-1"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new long[0];
}
public static byte[] aes_cbc_decrypt(byte[] data, byte[] key) {
String iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
byte[] output = null;
try {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
output = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return output;
}
public static long[] aes_cbc_decrypt_a32(long[] idata, long[] ikey) {
try {
byte[] data = a32_to_str(idata).getBytes("ISO-8859-1");
byte[] key = a32_to_str(ikey).getBytes("ISO-8859-1");
byte[] decrypt = aes_cbc_decrypt(data, key);
return str_to_a32(new String(decrypt, "ISO-8859-1"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new long[0];
}
public static long[] decrypt_key(long[] a, long[] key) {
long[] sum = new long[a.length];
for (int i = 0; i < a.length; i += 4) {
long[] part = aes_cbc_decrypt_a32(Arrays.copyOfRange(a, i, i + 4), key);
for (int j = i; j < i + 4; j++) {
sum[j] = part[j - i];
}
}
return sum;
}
public static long[] str_to_a32(String string) {
if (string.length() % 4 != 0) {
string += new String(new char[4 - string.length() % 4]);
}
long[] data = new long[string.length() / 4];
byte[] part = new byte[8];
for (int k = 0, i = 0; i < string.length(); i += 4, k++) {
String sequence = string.substring(i, i + 4);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(sequence.getBytes("ISO-8859-1"));
System.arraycopy(baos.toByteArray(), 0, part, 4, 4);
ByteBuffer bb = ByteBuffer.wrap(part);
data[k] = bb.getLong();
} catch (IOException e) {
data[k] = 0;
}
}
return data;
}
public static String a32_to_str(long[] data) {
byte[] part = null;
StringBuilder builder = new StringBuilder();
ByteBuffer bb = ByteBuffer.allocate(8);
for (int i = 0; i < data.length; i++) {
bb.putLong(data[i]);
part = Arrays.copyOfRange(bb.array(), 4, 8);
bb.clear();
ByteArrayInputStream bais = new ByteArrayInputStream(part);
while (bais.available() > 0) {
builder.append((char) bais.read());
}
}
return builder.toString();
}
public static String base64_url_encode(String data) {
try {
data = new String(base64_url_encode_byte((data.getBytes("ISO-8859-1")),true), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
data = data.replaceAll("\\+", "-");
data = data.replaceAll("/", "_");
data = data.replaceAll("=", "");
return data;
}
/* public static String base64_url_decode(String data) {
data = data.replaceAll("-", "\\+");
data = data.replaceAll("_", "/");
data = data.replaceAll(",", "");
//for (int i = 0;i<4-(data.length()%4);++i)
data += "==";
try {
return new String(Base64.decodeBase64(data.getBytes("ISO-8859-1")), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}*/
public static String a32_to_base64(long[] a) {
return base64_url_encode(a32_to_str(a));
}
public static long[] base64_to_a32(String s) throws UnsupportedEncodingException {
return str_to_a32(base64_url_decode(s));
}
public static BigInteger mpi_to_int(String private_key) throws IOException {
String hex = encodeHexString(private_key.substring(2));
return new BigInteger(hex, 16);
}
public static String decrypt_attr(String attributes, long[] key) {
try {
return new String(aes_cbc_decrypt(attributes.getBytes("ISO-8859-1"), a32_to_str(key).getBytes("ISO-8859-1")), "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
public static byte[] aInt_to_aByte(int... intKey) {
byte[] buffer = new byte[intKey.length * 4];
ByteBuffer bb = ByteBuffer.wrap(buffer);
for (int i = 0; i < intKey.length; i++) {
bb.putInt(intKey[i]);
}
return bb.array();
}
public static int[] aByte_to_aInt(byte[] bytes) {
ByteBuffer bb = ByteBuffer.wrap(bytes);
int[] res = new int[bytes.length / 4];
for (int i = 0; i < res.length; i++) {
res[i] = bb.getInt(i * 4);
}
return res;
}
public final static String base64_url_decode(String str) throws UnsupportedEncodingException{
return new String((base64_url_decode_byte(str)), "ISO-8859-1");
}
public final static byte[] base64_url_decode_byte(String str){
str += "==".substring((2 - str.length() * 3) & 3);
str = str.replace("-", "+").replace("_", "/").replace(",", "");
// Check special case
int sLen = str != null ? str.length() : 0;
if (sLen == 0)
return new byte[0];
// Count illegal characters (including '\r', '\n') to know what size the returned array will be,
// so we don't have to reallocate & copy it later.
int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
if (IA[str.charAt(i)] < 0)
sepCnt++;
// Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
if ((sLen - sepCnt) % 4 != 0)
return null;
// Count '=' at end
int pad = 0;
for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;)
if (str.charAt(i) == '=')
pad++;
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
for (int s = 0, d = 0; d < len;) {
// Assemble three bytes into an int from four "valid" characters.
int i = 0;
for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
int c = IA[str.charAt(s++)];
if (c >= 0)
i |= c << (18 - j * 6);
else
j--;
}
// Add the bytes
dArr[d++] = (byte) (i >> 16);
if (d < len) {
dArr[d++]= (byte) (i >> 8);
if (d < len)
dArr[d++] = (byte) i;
}
}
return dArr;
}
public final static byte[] base64_url_encode_byte(byte[] sArr, boolean lineSep)
{
// Check special case
int sLen = sArr != null ? sArr.length : 0;
if (sLen == 0)
return new byte[0];
int eLen = (sLen / 3) * 3; // Length of even 24-bits.
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
byte[] dArr = new byte[dLen];
// Encode even 24-bits
for (int s = 0, d = 0, cc = 0; s < eLen;) {
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
// Encode the int into four chars
dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
dArr[d++] = (byte) CA[i & 0x3f];
// Add optional line separator
if (lineSep && ++cc == 19 && d < dLen - 2) {
dArr[d++] = '\r';
dArr[d++] = '\n';
cc = 0;
}
}
// Pad and encode last bits if source isn't an even 24 bits.
int left = sLen - eLen; // 0 - 2.
if (left > 0) {
// Prepare the int
int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
// Set last four chars
dArr[dLen - 4] = (byte) CA[i >> 12];
dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
dArr[dLen - 1] = '=';
}
return dArr;
}
public static String encodeHexString(String s) throws IOException {
return DatatypeConverter.printHexBinary(s.getBytes("ISO-8859-1"));
}
public static byte[] decodeHexString(String s) {
return DatatypeConverter.parseHexBinary(s);
}
public static void print(Object o) {
System.out.println(o);
}
}
/*******************************************************************************
* Copyright (c) 2013 Ale46.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* @NT2005 - initial API and implementation
******************************************************************************/
public class MegaFile {
private String uid, name, h;
private long[] key;
private boolean isDir = false;
public String getName() {
if (name == null) return "NO NAME"; else return name;
//return name;
}
public void setKey(long[] k){
key = k;
}
public long[] getKey(){
return key;
}
public void setHandle(String h){
this.h = h;
}
public String getHandle(){
return h;
}
public void setName(String name) {
this.name = name;
}
public String getUID() {
return uid;
}
public void setUID(String uid) {
this.uid = uid;
}
public void setAttributes(String attributes) {
if (attributes.contains("MEGA")){
this.name = attributes.substring(10,attributes.lastIndexOf("\""));
}else
this.name = attributes;
}
public void setDirectory(boolean d){
isDir = d;
}
public boolean isDirectory(){
return isDir;
}
}
/*******************************************************************************
* Copyright (c) 2013 Ale46.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* @NT2005 - initial API and implementation
******************************************************************************/
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.RSAPrivateKeySpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
public class MegaHandler {
private String email, password, sid;
private int sequence_number;
private long[] master_key;
private BigInteger[] rsa_private_key;
private long[] password_aes;
HashMap<String,long[]> user_keys = new HashMap<String,long[]>();
public MegaHandler(String email, String password) {
this.email = email;
this.password = password;
Random rg = new Random();
sequence_number = rg.nextInt(Integer.MAX_VALUE);
}
public int login() throws IOException {
password_aes = MegaCrypt.prepare_key_pw(password);
String uh = MegaCrypt.stringhash(email, password_aes);
JSONObject json = new JSONObject();
try {
json.put("a", "us");
json.put("user", email);
json.put("uh", uh);
} catch (JSONException e) {
e.printStackTrace();
}
while (true) {
String response = api_request(json.toString());
if (isInteger(response))
return Integer.parseInt(response);
try {
if (login_process(new JSONObject(response), password_aes) != -2) {
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return 0;
}
private int login_process(JSONObject json, long[] password_aes) throws IOException {
String master_key_b64 = null;
try {
master_key_b64 = json.getString("k");
} catch (JSONException e) {
e.printStackTrace();
}
if (master_key_b64 == null || master_key_b64.isEmpty())
return -1;
long[] encrypted_master_key = MegaCrypt.base64_to_a32(master_key_b64);
master_key = MegaCrypt.decrypt_key(encrypted_master_key, password_aes);
if (json.has("csid")) {
String encrypted_rsa_private_key_b64 = null;
try {
encrypted_rsa_private_key_b64 = json.getString("privk");
} catch (JSONException e) {
e.printStackTrace();
}
long[] encrypted_rsa_private_key = MegaCrypt.base64_to_a32(encrypted_rsa_private_key_b64);
long[] rsa_private_key = MegaCrypt.decrypt_key(encrypted_rsa_private_key, master_key);
String private_key = MegaCrypt.a32_to_str(rsa_private_key);
this.rsa_private_key = new BigInteger[4];
for (int i = 0; i < 4; i++) {
int l = ((((int) private_key.charAt(0)) * 256 + ((int) private_key.charAt(1)) + 7) / 8) + 2;
this.rsa_private_key[i] = MegaCrypt.mpi_to_int(private_key.substring(0, l));
private_key = private_key.substring(l);
}
BigInteger encrypted_sid = null;
try {
encrypted_sid = MegaCrypt.mpi_to_int(MegaCrypt.base64_url_decode(json.getString("csid")));
} catch (JSONException e) {
e.printStackTrace();
}
BigInteger modulus = this.rsa_private_key[0].multiply(this.rsa_private_key[1]);
BigInteger privateExponent = this.rsa_private_key[2];
BigInteger sid = null;
try {
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, privateExponent));
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// PyCrypt can handle >256 bit length... what the fuck... sometimes i get 257
if (encrypted_sid.toByteArray().length > 256) {
Random rg = new Random();
sequence_number = rg.nextInt(Integer.MAX_VALUE);
return -2; // lets get a new seession
}
sid = new BigInteger(cipher.doFinal(encrypted_sid.toByteArray()));
} catch (Exception e) {
e.printStackTrace();
return -1;
}
String sidS = sid.toString(16);
if (sidS.length() % 2 != 0)
sidS = "0" + sidS;
try {
byte[] sidsnohex = MegaCrypt.decodeHexString(sidS);
this.sid = MegaCrypt.base64_url_encode(new String(sidsnohex, "ISO-8859-1").substring(0, 43));
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
return 0;
}
public String add_user(String email) {
JSONObject json = new JSONObject();
try {
json.put("a", "ur");
json.put("u", email);
json.put("l", 1);
} catch (JSONException e) {
e.printStackTrace();
}
return api_request(json.toString());
}
public long get_quota() {
JSONObject json = new JSONObject();
try {
json.put("a", "uq");
json.put("xfer", 1);
} catch (JSONException e) {
e.printStackTrace();
}
return new JSONObject(api_request(json.toString())).getLong("mstrg");
}
public String get_user() {
JSONObject json = new JSONObject();
try {
json.put("a", "ug");
} catch (JSONException e) {
e.printStackTrace();
}
return api_request(json.toString());
}
public ArrayList<MegaFile> get_files() throws UnsupportedEncodingException {
JSONObject json = new JSONObject();
try {
json.put("a", "f");
json.put("c", "1");
} catch (JSONException e) {
e.printStackTrace();
}
String files = api_request(json.toString());
// TODO check for negativ error
//print(json.toString());
ArrayList<MegaFile> megaFiles = new ArrayList<MegaFile>();
JSONArray array = null;
try {
json = new JSONObject(files);
array = json.getJSONArray("f");
for (int i = 0; i < array.length(); i++) {
//print(array.get(i).toString());
megaFiles.add(process_file(new JSONObject(array.get(i).toString())));
}
} catch (JSONException e) {
e.printStackTrace();
return null;
}
return megaFiles;
}
private MegaFile process_file(JSONObject jsonFile) throws UnsupportedEncodingException {
MegaFile file = new MegaFile();
try {
if (jsonFile.getInt("t") < 2) {
String key = "";
String uid = jsonFile.getString("u");
String h =(jsonFile.getString("h"));
file.setUID(uid);
file.setHandle(h);
//print (h);
if (jsonFile.getString("k").contains("/")){
String[] keys = jsonFile.getString("k").split("/");
int start = keys[0].indexOf(":")+1;
key = keys[0].substring(start);
}
String attributes = MegaCrypt.base64_url_decode(jsonFile.getString("a"));
long[] k = new long[4];
if (!key.isEmpty()){
long[] keys_a32 = MegaCrypt.decrypt_key(MegaCrypt.base64_to_a32(key), master_key);
if (jsonFile.getInt("t") == 0) {
k[0] = keys_a32[0] ^ keys_a32[4];
k[1] = keys_a32[1] ^ keys_a32[5];
k[2] = keys_a32[2] ^ keys_a32[6];
k[3] = keys_a32[3] ^ keys_a32[7];
} else {
k[0] = keys_a32[0];
k[1] = keys_a32[1];
k[2] = keys_a32[2];
k[3] = keys_a32[3];
file.setDirectory(true);
}
file.setKey(k);
file.setAttributes(MegaCrypt.decrypt_attr(attributes, k));
}else if(!jsonFile.isNull("su") && !jsonFile.isNull("sk") && jsonFile.getString("k").contains(":")){
long[] keyS;
user_keys.put(jsonFile.getString("u"), MegaCrypt.decrypt_key(MegaCrypt.base64_to_a32(jsonFile.getString("sk")), master_key));
//print("ShareKey->"+jsonFile.getString("sk"));
int dd1 = jsonFile.getString("k").indexOf(':');
String sk = jsonFile.getString("k").substring(dd1 + 1);
keyS = MegaCrypt.decrypt_key(MegaCrypt.base64_to_a32(sk) ,user_keys.get(jsonFile.getString("u")));
if (jsonFile.getInt("t") == 0){
long[] keys_a32S = keyS;
k[0] = keys_a32S[0] ^ keys_a32S[4];
k[1] = keys_a32S[1] ^ keys_a32S[5];
k[2] = keys_a32S[2] ^ keys_a32S[6];
k[3] = keys_a32S[3] ^ keys_a32S[7];
}else{
k = keyS;
file.setDirectory(true);
}
file.setKey(k);
file.setAttributes(MegaCrypt.decrypt_attr(attributes, k));
}else if (!jsonFile.isNull("u") && jsonFile.getString("k").contains(":") && user_keys.containsKey(jsonFile.getString("u"))) {
int dd1 = jsonFile.getString("k").indexOf(':');
String sk = jsonFile.getString("k").substring(dd1 + 1);
//print(user_keys.get(jsonFile.getString("u")));
long[] keyS = MegaCrypt.decrypt_key(MegaCrypt.base64_to_a32(sk) ,user_keys.get(jsonFile.getString("u")));
if (jsonFile.getInt("t") == 0){
long[] keys_a32S = keyS;
k[0] = keys_a32S[0] ^ keys_a32S[4];
k[1] = keys_a32S[1] ^ keys_a32S[5];
k[2] = keys_a32S[2] ^ keys_a32S[6];
k[3] = keys_a32S[3] ^ keys_a32S[7];
}else{
k = keyS;
file.setDirectory(true);
}
file.setKey(k);
file.setAttributes(MegaCrypt.decrypt_attr(attributes, k));
}else if (!jsonFile.isNull("k")){
int dd1 = jsonFile.getString("k").indexOf(':');
key = jsonFile.getString("k").substring(dd1 + 1);
long[] keys_a32S = MegaCrypt.decrypt_key(MegaCrypt.base64_to_a32(key), master_key);
if (jsonFile.getInt("t") == 0){
k[0] = keys_a32S[0] ^ keys_a32S[4];
k[1] = keys_a32S[1] ^ keys_a32S[5];
k[2] = keys_a32S[2] ^ keys_a32S[6];
k[3] = keys_a32S[3] ^ keys_a32S[7];
file.setDirectory(true);
}/*else{
k = keys_a32S;
file.setDirectory(true);
}*/
file.setKey(k);
file.setAttributes(MegaCrypt.decrypt_attr(attributes, k));
}else{
file.setAttributes(jsonFile.toString());
}
} else if (jsonFile.getInt("t") == 2) {
file.setName("Cloud Drive");
} else if (jsonFile.getInt("t") == 3) {
file.setName("Cloud Inbox");
} else if (jsonFile.getInt("t") == 4) {
file.setName("Rubbish Bin");
} else {
file.setName(jsonFile.toString());
}
return file;
} catch (JSONException e) {
e.printStackTrace();
}
//file.setAttributes(jsonFile.toString());
return file;
}
public String get_url(MegaFile f){
if ( f.getHandle() == null || f.getKey() == null)
return "Error";
JSONObject json = new JSONObject();
try {
json.put("a", "l");
json.put("n", f.getHandle());
} catch (JSONException e) {
e.printStackTrace();
}
String public_handle = api_request(json.toString());
if (public_handle.equals("-11"))
return "Shared file, no public url";
return "https://mega.co.nz/#!"+public_handle.substring(1, public_handle.length()-1)+"!"+MegaCrypt.a32_to_base64(f.getKey());
}
private String api_request(String data) {
HttpURLConnection connection = null;
try {
String urlString = "https://g.api.mega.co.nz/cs?id=" + sequence_number;
if (sid != null)
urlString += "&sid=" + sid;
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST"); //use post method
connection.setDoOutput(true); //we will send stuff
connection.setDoInput(true); //we want feedback
connection.setUseCaches(false); //no caches
connection.setAllowUserInteraction(false);
connection.setRequestProperty("Content-Type", "text/xml");
OutputStream out = connection.getOutputStream();
try {
OutputStreamWriter wr = new OutputStreamWriter(out);
wr.write("[" + data + "]"); //data is JSON object containing the api commands
wr.flush();
wr.close();
} catch (IOException e) {
e.printStackTrace();
} finally { //in this case, we are ensured to close the output stream
if (out != null)
out.close();
}
InputStream in = connection.getInputStream();
StringBuffer response = new StringBuffer();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = rd.readLine()) != null) {
response.append(line);
}
rd.close(); //close the reader
} catch (IOException e) {
e.printStackTrace();
} finally { //in this case, we are ensured to close the input stream
if (in != null)
in.close();
}
return response.toString().substring(1, response.toString().length() - 1);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
public static boolean isInteger(String string) {
if (string == null || string.isEmpty()) {
return false;
}
int length = string.length();
int i = 0;
if (string.charAt(i) == '[') {
if (length == 1)
return false;
i++;
}
if (string.charAt(i) == '-') {
if (length == 1 + i)
return false;
i++;
}
for (; i < length; i++) {
char c = string.charAt(i);
if (c <= '/' || c >= ':') {
return false;
}
}
return true;
}
public void download(String url, String path) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IOException, IllegalBlockSizeException, BadPaddingException{
//TODO DOWNLOAD mismatch?
print("Download started");
String[] s = url.split("!");
String file_id = s[1];
byte[] file_key = MegaCrypt.base64_url_decode_byte(s[2]);
int[] intKey = MegaCrypt.aByte_to_aInt(file_key);
JSONObject json = new JSONObject();
try {
json.put("a", "g");
json.put("g", "1");
json.put("p", file_id);
} catch (JSONException e) {
e.printStackTrace();
}
JSONObject file_data = new JSONObject(api_request(json.toString()));
int[] keyNOnce = new int[] { intKey[0] ^ intKey[4], intKey[1] ^ intKey[5], intKey[2] ^ intKey[6], intKey[3] ^ intKey[7], intKey[4], intKey[5] };
byte[] key = MegaCrypt.aInt_to_aByte(keyNOnce[0], keyNOnce[1], keyNOnce[2], keyNOnce[3]);
int[] iiv = new int[] { keyNOnce[4], keyNOnce[5], 0, 0 };
byte[] iv = MegaCrypt.aInt_to_aByte(iiv);
@SuppressWarnings("unused")
int file_size = file_data.getInt("s");
String attribs = (file_data.getString("at"));
attribs = new String(MegaCrypt.aes_cbc_decrypt(MegaCrypt.base64_url_decode_byte(attribs), key));
String file_name = attribs.substring(10,attribs.lastIndexOf("\""));
print(file_name);
final IvParameterSpec ivSpec = new IvParameterSpec(iv);
final SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CTR/nopadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
InputStream is = null;
String file_url = file_data.getString("g");
FileOutputStream fos = new FileOutputStream(path+File.separator+file_name);
final OutputStream cos = new CipherOutputStream(fos, cipher);
final Cipher decipher = Cipher.getInstance("AES/CTR/NoPadding");
decipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
int read = 0;
final byte[] buffer = new byte[32767];
try {
URLConnection urlConn = new URL(file_url).openConnection();
print(file_url);
is = urlConn.getInputStream();
while ((read = is.read(buffer)) > 0) {
cos.write(buffer, 0, read);
}
} finally {
try {
cos.close();
if (is != null) {
is.close();
}
} finally {
if (fos != null) {
fos.close();
}
}
}
print("Download finished");
}
public static void print(Object o) {
System.out.println(o);
}
}
Modo de uso
public static void main(String[] args) {
MegaHandler m=new MegaHandler("email", "contrasea");
try {
int t= m.login();
System.out.println(t);
ArrayList<MegaFile> _files = m.get_files();
for(int i=0; i<_files.size(); i++){
System.out.println(_files.get(i).getName());
System.out.println(m.get_url(_files.get(i)));
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}