API para MEGA
Publicado: 04 Oct 2013, 17:17
por adwind
Me encontré con este código para interactuar con MEGA podemos listar los archivos que tiene la cuenta y descargarlos.
Se le pueden modificar ciertas cosas para descargar de otras cuentas.
Deben agregar la libreria de JSON.
Modo de uso
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);
}
}