Guest User

GrooveSquid Deezer source

a guest
Jul 26th, 2015
4,568
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package com.groovesquid.service.hoster;
  2.  
  3. import com.eclipsesource.json.JsonArray;
  4. import com.eclipsesource.json.JsonObject;
  5. import com.groovesquid.model.Track;
  6. import com.groovesquid.util.Utils;
  7. import org.apache.commons.lang3.RandomStringUtils;
  8. import org.apache.commons.lang3.StringUtils;
  9. import org.apache.http.*;
  10. import org.apache.http.client.HttpResponseException;
  11. import org.apache.http.client.methods.HttpGet;
  12. import org.apache.http.message.BasicHeader;
  13. import org.apache.http.util.EntityUtils;
  14.  
  15. import javax.crypto.Cipher;
  16. import javax.crypto.spec.IvParameterSpec;
  17. import javax.crypto.spec.SecretKeySpec;
  18. import javax.xml.bind.DatatypeConverter;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.OutputStream;
  22. import java.io.UnsupportedEncodingException;
  23. import java.net.URLEncoder;
  24. import java.nio.ByteBuffer;
  25. import java.text.MessageFormat;
  26. import java.util.ArrayList;
  27. import java.util.Arrays;
  28. import java.util.List;
  29. import java.util.logging.Level;
  30.  
  31. import static java.lang.String.format;
  32.  
  33. public class Deezer extends Hoster {
  34.  
  35.     public Deezer() {
  36.         setName("Deezer");
  37.     }
  38.  
  39.     byte[] blowfishKey = new byte[16];
  40.     byte[] aesKey = "jo6aey6haid2Teih".getBytes();
  41.  
  42.     public String getDownloadUrl(Track track) {
  43.         String query = "";
  44.         if (track.getSong().getArtists().size() <= 2) {
  45.             query += track.getSong().getArtistNames().replaceAll(",", "");
  46.         } else {
  47.             query += track.getSong().getArtists().get(0);
  48.         }
  49.         query += " " + track.getSong().getName();
  50.  
  51.         String searchResponse = null;
  52.         try {
  53.             searchResponse = get("http://api.deezer.com/search?q=" + URLEncoder.encode(query, "UTF-8"), Arrays.asList(browserHeaders));
  54.         } catch (UnsupportedEncodingException e) {
  55.             e.printStackTrace();
  56.         }
  57.  
  58.         if (searchResponse != null) {
  59.             try {
  60.                 JsonArray dataArray = JsonObject.readFrom(searchResponse).get("data").asArray();
  61.                 if (dataArray.isEmpty()) {
  62.                     return null;
  63.                 }
  64.                 Long songId = dataArray.get(0).asObject().get("id").asLong();
  65.  
  66.                 String deezerHomeResponse = get("http://www.deezer.com/", Arrays.asList(browserHeaders));
  67.                 String apiToken = StringUtils.substringBetween(deezerHomeResponse, "checkForm = '", "'");
  68.  
  69.                 String trackResponse = post("http://www.deezer.com/ajax/gw-light.php?api_version=1.0&api_token=" + apiToken + "&input=3&cid=" + RandomStringUtils.randomAlphanumeric(18).toLowerCase(), "[{\"method\":\"song.getListData\",\"params\":{\"sng_ids\":[" + songId + "]}}]", Arrays.asList(browserHeaders));
  70.                 //System.out.println(trackResponse);
  71.                 JsonObject trackJson = JsonArray.readFrom(trackResponse).get(0).asObject().get("results").asObject().get("data").asArray().get(0).asObject();
  72.  
  73.                 String puid = trackJson.get("MD5_ORIGIN").asString();
  74.                 String proxyLetter = puid.substring(0, 1);
  75.                 String playerToken = StringUtils.substringBetween(deezerHomeResponse, "PLAYER_TOKEN = '", "'");
  76.                 String separator = "¤"; // such a nice seperator, isn't it?
  77.                 int format;
  78.                 if (Long.valueOf(trackJson.get("FILESIZE_MP3_320").asString()) > 0) {
  79.                     format = 3; // 320kbps
  80.                 } else if (Long.valueOf(trackJson.get("FILESIZE_MP3_256").asString()) > 0) {
  81.                     format = 5; // 256kbps
  82.                 } else {
  83.                     format = 1; // 128kbps
  84.                 }
  85.                 int mediaVersion = Integer.valueOf(trackJson.get("MEDIA_VERSION").asString());
  86.                 blowfishKey = getBlowfishKey(songId);
  87.  
  88.                 // let the magic do its work
  89.                 String data = puid + separator + format + separator + songId + separator + mediaVersion;
  90.                 String dataHash = new MD5().get(data);
  91.  
  92.                 data = dataHash + separator + data + separator;
  93.                 String dataEncrypted = DatatypeConverter.printHexBinary(new AES().encrypt(data.getBytes("ISO-8859-1"), aesKey)).toLowerCase();
  94.  
  95.                 String mp3Url = MessageFormat.format("http://cdn-proxy-{0}.deezer.com/mobile/1/{1}", proxyLetter, dataEncrypted);
  96.  
  97.                 List<Header> headers = new ArrayList<Header>(Arrays.asList(browserHeaders));
  98.                 headers.add(new BasicHeader("Referer", "https://deezer.com/"));
  99.  
  100.                 return mp3Url;
  101.             } catch (Exception ex) {
  102.                 log.log(Level.SEVERE, ex.getMessage(), ex);
  103.             }
  104.         }
  105.  
  106.         return null;
  107.     }
  108.  
  109.     public void download(Track track, OutputStream outputStream) throws IOException {
  110.         HttpGet httpGet = new HttpGet(track.getDownloadUrl());
  111.         httpGet.setHeaders(browserHeaders);
  112.         HttpResponse httpResponse = httpClient.execute(httpGet);
  113.         HttpEntity httpEntity = httpResponse.getEntity();
  114.         try {
  115.             StatusLine statusLine = httpResponse.getStatusLine();
  116.             int statusCode = statusLine.getStatusCode();
  117.             if (statusCode == HttpStatus.SC_OK) {
  118.                 track.setTotalBytes(httpEntity.getContentLength());
  119.  
  120.                 int chunkSize = 2048;
  121.                 int intervalChunk = 3;
  122.                 InputStream inputStream = httpEntity.getContent();
  123.  
  124.                 byte[] chunk = new byte[chunkSize];
  125.                 int chunks = (int) Math.ceil(httpEntity.getContentLength() / chunkSize);
  126.                 int read;
  127.                 int i = 0;
  128.                 while ((read = inputStream.read(chunk, 0, chunkSize)) != -1) {
  129.                     if (read < chunkSize && (i < chunks - 1)) {
  130.                         ByteBuffer buffer = ByteBuffer.allocate(chunkSize);
  131.                         buffer.put(ByteBuffer.wrap(chunk, 0, read));
  132.                         while (buffer.hasRemaining()) {
  133.                             byte[] temp = new byte[buffer.remaining()];
  134.                             int tempRead = inputStream.read(temp, 0, buffer.remaining());
  135.                             read += tempRead;
  136.                             buffer.put(temp, 0, tempRead);
  137.                         }
  138.                         chunk = buffer.array();
  139.                     }
  140.                     if (i % intervalChunk == 0) {
  141.                         chunk = decryptBlowfish(chunk, blowfishKey);
  142.                     }
  143.  
  144.                     outputStream.write(chunk, 0, read);
  145.                     i++;
  146.                 }
  147.  
  148.                 // need to close immediately otherwise we cannot write ID tags
  149.                 outputStream.close();
  150.                 outputStream = null;
  151.                 // write ID tags
  152.                 track.getStore().writeTrackInfo(track);
  153.             } else {
  154.                 throw new HttpResponseException(statusCode, format("%s: %d %s", track.getDownloadUrl(), statusCode, statusLine.getReasonPhrase()));
  155.             }
  156.         } finally {
  157.             try {
  158.                 EntityUtils.consume(httpEntity);
  159.             } catch (IOException ignore) {
  160.                 // ignored
  161.             }
  162.             Utils.closeQuietly(outputStream, track.getStore().getDescription());
  163.         }
  164.     }
  165.  
  166.     private byte[] getBlowfishKey(Long songId) {
  167.         String hash = Utils.md5(songId.toString());
  168.         String part1 = hash.substring(0, 16);
  169.         String part2 = hash.substring(16, 32);
  170.         String[] data = new String[]{"g4el58wc0zvf9na1", part1, part2};
  171.         String keyStr = getXor(data, 16);
  172.         return keyStr.getBytes();
  173.     }
  174.  
  175.     private String getXor(String[] data, int len) {
  176.         String result = "";
  177.         int i = 0;
  178.         while (i < len) {
  179.             int character = data[0].charAt(i);
  180.             int j = 1;
  181.             while (j < data.length) {
  182.                 character = character ^ data[j].charAt(i);
  183.                 j++;
  184.             }
  185.             result = result + (char) character;
  186.             i++;
  187.         }
  188.         return result;
  189.     }
  190.  
  191.     private byte[] decryptBlowfish(byte[] data, byte[] key) {
  192.         try {
  193.             SecretKeySpec keySpec = new SecretKeySpec(key, "Blowfish");
  194.             Cipher cipher = Cipher.getInstance("Blowfish/CBC/NoPadding");
  195.             cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(new byte[]{0, 1, 2, 3, 4, 5, 6, 7}));
  196.             return cipher.doFinal(data);
  197.         } catch (Exception ex) {
  198.             log.log(Level.SEVERE, ex.getMessage(), ex);
  199.         }
  200.         return null;
  201.     }
  202.  
  203.     private String decryptAes(String data, byte[] key) {
  204.         try {
  205.             SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
  206.             Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
  207.             cipher.init(Cipher.DECRYPT_MODE, keySpec);
  208.             return new String(cipher.doFinal(DatatypeConverter.parseHexBinary(data)));
  209.         } catch (Exception ex) {
  210.             log.log(Level.SEVERE, ex.getMessage(), ex);
  211.         }
  212.         return null;
  213.     }
  214.  
  215.     public String encryptAes(byte[] data, byte[] key) {
  216.         try {
  217.             SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
  218.             Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
  219.             cipher.init(Cipher.ENCRYPT_MODE, keySpec);
  220.             byte[] encrypted = cipher.doFinal(data);
  221.             return DatatypeConverter.printHexBinary(encrypted).toLowerCase();
  222.         } catch (Exception ex) {
  223.             log.log(Level.SEVERE, ex.getMessage(), ex);
  224.         }
  225.         return null;
  226.     }
  227.  
  228.     class MD5 {
  229.         private int chrsz = 8;
  230.  
  231.         public String get(String s) {
  232.             return binl2hex(core_md5(str2binl(s), s.length() * chrsz));
  233.         }
  234.  
  235.         private int[] str2binl(String str) {
  236.             int[] bin = new int[(((((str.length() * chrsz) + 64) >>> 9) << 4) + 14) + 1];
  237.             int mask = (1 << chrsz) - 1;
  238.             for (int i = 0; i < str.length() * chrsz; i += chrsz) {
  239.                 bin[i >> 5] |= (str.codePointAt(i / chrsz) & mask) << (i % 32);
  240.             }
  241.             return bin;
  242.         }
  243.  
  244.         private int getFromArrayWrap(int[] array, int index) {
  245.             if (array.length <= index) {
  246.                 return 0;
  247.             }
  248.             return array[index];
  249.         }
  250.  
  251.         private int[] core_md5(int[] x, int len) {
  252.             x[len >> 5] |= 0x80 << ((len) % 32);
  253.             x[(((len + 64) >>> 9) << 4) + 14] = len;
  254.  
  255.             int a = 1732584193;
  256.             int b = -271733879;
  257.             int c = -1732584194;
  258.             int d = 271733878;
  259.  
  260.             for (int i = 0; i < x.length; i += 16) {
  261.                 int olda = a;
  262.                 int oldb = b;
  263.                 int oldc = c;
  264.                 int oldd = d;
  265.  
  266.                 a = md5_ff(a, b, c, d, getFromArrayWrap(x, i + 0), 7, -680876936);
  267.                 d = md5_ff(d, a, b, c, getFromArrayWrap(x, i + 1), 12, -389564586);
  268.                 c = md5_ff(c, d, a, b, getFromArrayWrap(x, i + 2), 17, 606105819);
  269.                 b = md5_ff(b, c, d, a, getFromArrayWrap(x, i + 3), 22, -1044525330);
  270.                 a = md5_ff(a, b, c, d, getFromArrayWrap(x, i + 4), 7, -176418897);
  271.                 d = md5_ff(d, a, b, c, getFromArrayWrap(x, i + 5), 12, 1200080426);
  272.                 c = md5_ff(c, d, a, b, getFromArrayWrap(x, i + 6), 17, -1473231341);
  273.                 b = md5_ff(b, c, d, a, getFromArrayWrap(x, i + 7), 22, -45705983);
  274.                 a = md5_ff(a, b, c, d, getFromArrayWrap(x, i + 8), 7, 1770035416);
  275.                 d = md5_ff(d, a, b, c, getFromArrayWrap(x, i + 9), 12, -1958414417);
  276.                 c = md5_ff(c, d, a, b, getFromArrayWrap(x, i + 10), 17, -42063);
  277.                 b = md5_ff(b, c, d, a, getFromArrayWrap(x, i + 11), 22, -1990404162);
  278.                 a = md5_ff(a, b, c, d, getFromArrayWrap(x, i + 12), 7, 1804603682);
  279.                 d = md5_ff(d, a, b, c, getFromArrayWrap(x, i + 13), 12, -40341101);
  280.                 c = md5_ff(c, d, a, b, getFromArrayWrap(x, i + 14), 17, -1502002290);
  281.                 b = md5_ff(b, c, d, a, getFromArrayWrap(x, i + 15), 22, 1236535329);
  282.  
  283.                 a = md5_gg(a, b, c, d, getFromArrayWrap(x, i + 1), 5, -165796510);
  284.                 d = md5_gg(d, a, b, c, getFromArrayWrap(x, i + 6), 9, -1069501632);
  285.                 c = md5_gg(c, d, a, b, getFromArrayWrap(x, i + 11), 14, 643717713);
  286.                 b = md5_gg(b, c, d, a, getFromArrayWrap(x, i + 0), 20, -373897302);
  287.                 a = md5_gg(a, b, c, d, getFromArrayWrap(x, i + 5), 5, -701558691);
  288.                 d = md5_gg(d, a, b, c, getFromArrayWrap(x, i + 10), 9, 38016083);
  289.                 c = md5_gg(c, d, a, b, getFromArrayWrap(x, i + 15), 14, -660478335);
  290.                 b = md5_gg(b, c, d, a, getFromArrayWrap(x, i + 4), 20, -405537848);
  291.                 a = md5_gg(a, b, c, d, getFromArrayWrap(x, i + 9), 5, 568446438);
  292.                 d = md5_gg(d, a, b, c, getFromArrayWrap(x, i + 14), 9, -1019803690);
  293.                 c = md5_gg(c, d, a, b, getFromArrayWrap(x, i + 3), 14, -187363961);
  294.                 b = md5_gg(b, c, d, a, getFromArrayWrap(x, i + 8), 20, 1163531501);
  295.                 a = md5_gg(a, b, c, d, getFromArrayWrap(x, i + 13), 5, -1444681467);
  296.                 d = md5_gg(d, a, b, c, getFromArrayWrap(x, i + 2), 9, -51403784);
  297.                 c = md5_gg(c, d, a, b, getFromArrayWrap(x, i + 7), 14, 1735328473);
  298.                 b = md5_gg(b, c, d, a, getFromArrayWrap(x, i + 12), 20, -1926607734);
  299.  
  300.                 a = md5_hh(a, b, c, d, getFromArrayWrap(x, i + 5), 4, -378558);
  301.                 d = md5_hh(d, a, b, c, getFromArrayWrap(x, i + 8), 11, -2022574463);
  302.                 c = md5_hh(c, d, a, b, getFromArrayWrap(x, i + 11), 16, 1839030562);
  303.                 b = md5_hh(b, c, d, a, getFromArrayWrap(x, i + 14), 23, -35309556);
  304.                 a = md5_hh(a, b, c, d, getFromArrayWrap(x, i + 1), 4, -1530992060);
  305.                 d = md5_hh(d, a, b, c, getFromArrayWrap(x, i + 4), 11, 1272893353);
  306.                 c = md5_hh(c, d, a, b, getFromArrayWrap(x, i + 7), 16, -155497632);
  307.                 b = md5_hh(b, c, d, a, getFromArrayWrap(x, i + 10), 23, -1094730640);
  308.                 a = md5_hh(a, b, c, d, getFromArrayWrap(x, i + 13), 4, 681279174);
  309.                 d = md5_hh(d, a, b, c, getFromArrayWrap(x, i + 0), 11, -358537222);
  310.                 c = md5_hh(c, d, a, b, getFromArrayWrap(x, i + 3), 16, -722521979);
  311.                 b = md5_hh(b, c, d, a, getFromArrayWrap(x, i + 6), 23, 76029189);
  312.                 a = md5_hh(a, b, c, d, getFromArrayWrap(x, i + 9), 4, -640364487);
  313.                 d = md5_hh(d, a, b, c, getFromArrayWrap(x, i + 12), 11, -421815835);
  314.                 c = md5_hh(c, d, a, b, getFromArrayWrap(x, i + 15), 16, 530742520);
  315.                 b = md5_hh(b, c, d, a, getFromArrayWrap(x, i + 2), 23, -995338651);
  316.  
  317.                 a = md5_ii(a, b, c, d, getFromArrayWrap(x, i + 0), 6, -198630844);
  318.                 d = md5_ii(d, a, b, c, getFromArrayWrap(x, i + 7), 10, 1126891415);
  319.                 c = md5_ii(c, d, a, b, getFromArrayWrap(x, i + 14), 15, -1416354905);
  320.                 b = md5_ii(b, c, d, a, getFromArrayWrap(x, i + 5), 21, -57434055);
  321.                 a = md5_ii(a, b, c, d, getFromArrayWrap(x, i + 12), 6, 1700485571);
  322.                 d = md5_ii(d, a, b, c, getFromArrayWrap(x, i + 3), 10, -1894986606);
  323.                 c = md5_ii(c, d, a, b, getFromArrayWrap(x, i + 10), 15, -1051523);
  324.                 b = md5_ii(b, c, d, a, getFromArrayWrap(x, i + 1), 21, -2054922799);
  325.                 a = md5_ii(a, b, c, d, getFromArrayWrap(x, i + 8), 6, 1873313359);
  326.                 d = md5_ii(d, a, b, c, getFromArrayWrap(x, i + 15), 10, -30611744);
  327.                 c = md5_ii(c, d, a, b, getFromArrayWrap(x, i + 6), 15, -1560198380);
  328.                 b = md5_ii(b, c, d, a, getFromArrayWrap(x, i + 13), 21, 1309151649);
  329.                 a = md5_ii(a, b, c, d, getFromArrayWrap(x, i + 4), 6, -145523070);
  330.                 d = md5_ii(d, a, b, c, getFromArrayWrap(x, i + 11), 10, -1120210379);
  331.                 c = md5_ii(c, d, a, b, getFromArrayWrap(x, i + 2), 15, 718787259);
  332.                 b = md5_ii(b, c, d, a, getFromArrayWrap(x, i + 9), 21, -343485551);
  333.  
  334.                 a = safe_add(a, olda);
  335.                 b = safe_add(b, oldb);
  336.                 c = safe_add(c, oldc);
  337.                 d = safe_add(d, oldd);
  338.             }
  339.             int[] ret = new int[4];
  340.             ret[0] = a;
  341.             ret[1] = b;
  342.             ret[2] = c;
  343.             ret[3] = d;
  344.             return ret;
  345.         }
  346.  
  347.         private String binl2hex(int[] binarray) {
  348.             String hex_tab = "0123456789abcdef";
  349.             StringBuilder sb = new StringBuilder();
  350.             char str1;
  351.             char str2;
  352.             for (int i = 0; i < binarray.length * 4; i++) {
  353.                 str1 = hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF);
  354.                 str2 = hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
  355.                 sb.append(str1);
  356.                 sb.append(str2);
  357.             }
  358.             return sb.toString();
  359.         }
  360.  
  361.  
  362.         private int md5_cmn(int q, int a, int b, int x, int s, int t) {
  363.             return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
  364.         }
  365.  
  366.         private int md5_ff(int a, int b, int c, int d, int x, int s, int t) {
  367.             return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
  368.         }
  369.  
  370.         private int md5_gg(int a, int b, int c, int d, int x, int s, int t) {
  371.             return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
  372.         }
  373.  
  374.         private int md5_hh(int a, int b, int c, int d, int x, int s, int t) {
  375.             return md5_cmn(b ^ c ^ d, a, b, x, s, t);
  376.         }
  377.  
  378.         private int md5_ii(int a, int b, int c, int d, int x, int s, int t) {
  379.             return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
  380.         }
  381.  
  382.         private int safe_add(int x, int y) {
  383.             int lsw = (x & 0xFFFF) + (y & 0xFFFF);
  384.             int msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  385.             return (msw << 16) | (lsw & 0xFFFF);
  386.         }
  387.  
  388.         private int bit_rol(int num, int cnt) {
  389.             return (num << cnt) | (num >>> (32 - cnt));
  390.         }
  391.     }
  392.  
  393.     public class AES {
  394.  
  395.         private int Nb, Nk, Nr;
  396.         private byte[][] w;
  397.  
  398.         private int[] sbox = {0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F,
  399.                 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82,
  400.                 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C,
  401.                 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
  402.                 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23,
  403.                 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27,
  404.                 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52,
  405.                 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
  406.                 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58,
  407.                 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9,
  408.                 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92,
  409.                 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
  410.                 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E,
  411.                 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A,
  412.                 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0,
  413.                 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62,
  414.                 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E,
  415.                 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78,
  416.                 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B,
  417.                 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
  418.                 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98,
  419.                 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55,
  420.                 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41,
  421.                 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};
  422.  
  423.         private int[] inv_sbox = {0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5,
  424.                 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3,
  425.                 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4,
  426.                 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
  427.                 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1,
  428.                 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B,
  429.                 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4,
  430.                 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
  431.                 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D,
  432.                 0x84, 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4,
  433.                 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA,
  434.                 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
  435.                 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF,
  436.                 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD,
  437.                 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 0x47,
  438.                 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E,
  439.                 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79,
  440.                 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD,
  441.                 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27,
  442.                 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
  443.                 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B,
  444.                 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53,
  445.                 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1,
  446.                 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D};
  447.  
  448.         private int Rcon[] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
  449.                 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
  450.                 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
  451.                 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
  452.                 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
  453.                 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
  454.                 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
  455.                 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
  456.                 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
  457.                 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
  458.                 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
  459.                 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
  460.                 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
  461.                 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
  462.                 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
  463.                 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb};
  464.  
  465.         private byte[] xor_func(byte[] a, byte[] b) {
  466.             byte[] out = new byte[a.length];
  467.             for (int i = 0; i < a.length; i++) {
  468.                 out[i] = (byte) (a[i] ^ b[i]);
  469.             }
  470.             return out;
  471.  
  472.         }
  473.  
  474.         private byte[][] generateSubkeys(byte[] key) {
  475.             byte[][] tmp = new byte[Nb * (Nr + 1)][4];
  476.  
  477.             int i = 0;
  478.             while (i < Nk) {
  479.  
  480.                 tmp[i][0] = key[i * 4];
  481.                 tmp[i][1] = key[i * 4 + 1];
  482.                 tmp[i][2] = key[i * 4 + 2];
  483.                 tmp[i][3] = key[i * 4 + 3];
  484.                 i++;
  485.             }
  486.             i = Nk;
  487.             while (i < Nb * (Nr + 1)) {
  488.                 byte[] temp = new byte[4];
  489.                 System.arraycopy(tmp[i - 1], 0, temp, 0, 4);
  490.                 if (i % Nk == 0) {
  491.                     temp = SubWord(rotateWord(temp));
  492.                     temp[0] = (byte) (temp[0] ^ (Rcon[i / Nk] & 0xff));
  493.                 } else if (Nk > 6 && i % Nk == 4) {
  494.                     temp = SubWord(temp);
  495.                 }
  496.                 tmp[i] = xor_func(tmp[i - Nk], temp);
  497.                 i++;
  498.             }
  499.  
  500.             return tmp;
  501.         }
  502.  
  503.         private byte[] SubWord(byte[] in) {
  504.             byte[] tmp = new byte[in.length];
  505.  
  506.             for (int i = 0; i < tmp.length; i++)
  507.                 tmp[i] = (byte) (sbox[in[i] & 0x000000ff] & 0xff);
  508.  
  509.             return tmp;
  510.         }
  511.  
  512.         private byte[] rotateWord(byte[] input) {
  513.             byte[] tmp = new byte[input.length];
  514.             tmp[0] = input[1];
  515.             tmp[1] = input[2];
  516.             tmp[2] = input[3];
  517.             tmp[3] = input[0];
  518.  
  519.             return tmp;
  520.         }
  521.  
  522.         private byte[][] AddRoundKey(byte[][] state, byte[][] w, int round) {
  523.             byte[][] tmp = new byte[state.length][state[0].length];
  524.  
  525.             for (int c = 0; c < Nb; c++) {
  526.                 for (int l = 0; l < 4; l++)
  527.                     tmp[l][c] = (byte) (state[l][c] ^ w[round * Nb + c][l]);
  528.             }
  529.  
  530.             return tmp;
  531.         }
  532.  
  533.         private byte[][] SubBytes(byte[][] state) {
  534.             byte[][] tmp = new byte[state.length][state[0].length];
  535.             for (int row = 0; row < 4; row++)
  536.                 for (int col = 0; col < Nb; col++)
  537.                     tmp[row][col] = (byte) (sbox[(state[row][col] & 0x000000ff)] & 0xff);
  538.  
  539.             return tmp;
  540.         }
  541.  
  542.         private byte[][] InvSubBytes(byte[][] state) {
  543.             for (int row = 0; row < 4; row++)
  544.                 for (int col = 0; col < Nb; col++)
  545.                     state[row][col] = (byte) (inv_sbox[(state[row][col] & 0x000000ff)] & 0xff);
  546.  
  547.             return state;
  548.         }
  549.  
  550.         private byte[][] ShiftRows(byte[][] state) {
  551.             byte[] t = new byte[4];
  552.             for (int r = 1; r < 4; r++) {
  553.                 for (int c = 0; c < Nb; c++)
  554.                     t[c] = state[r][(c + r) % Nb];
  555.                 System.arraycopy(t, 0, state[r], 0, Nb);
  556.             }
  557.  
  558.             return state;
  559.         }
  560.  
  561.         private byte[][] InvShiftRows(byte[][] state) {
  562.             byte[] t = new byte[4];
  563.             for (int r = 1; r < 4; r++) {
  564.                 for (int c = 0; c < Nb; c++)
  565.                     t[(c + r) % Nb] = state[r][c];
  566.                 System.arraycopy(t, 0, state[r], 0, Nb);
  567.             }
  568.             return state;
  569.         }
  570.  
  571.         private byte[][] InvMixColumns(byte[][] s) {
  572.             int[] sp = new int[4];
  573.             byte b02 = (byte) 0x0e, b03 = (byte) 0x0b, b04 = (byte) 0x0d, b05 = (byte) 0x09;
  574.             for (int c = 0; c < 4; c++) {
  575.                 sp[0] = FFMul(b02, s[0][c]) ^ FFMul(b03, s[1][c]) ^ FFMul(b04, s[2][c]) ^ FFMul(b05, s[3][c]);
  576.                 sp[1] = FFMul(b05, s[0][c]) ^ FFMul(b02, s[1][c]) ^ FFMul(b03, s[2][c]) ^ FFMul(b04, s[3][c]);
  577.                 sp[2] = FFMul(b04, s[0][c]) ^ FFMul(b05, s[1][c]) ^ FFMul(b02, s[2][c]) ^ FFMul(b03, s[3][c]);
  578.                 sp[3] = FFMul(b03, s[0][c]) ^ FFMul(b04, s[1][c]) ^ FFMul(b05, s[2][c]) ^ FFMul(b02, s[3][c]);
  579.                 for (int i = 0; i < 4; i++) s[i][c] = (byte) (sp[i]);
  580.             }
  581.  
  582.             return s;
  583.         }
  584.  
  585.         private byte[][] MixColumns(byte[][] s) {
  586.             int[] sp = new int[4];
  587.             byte b02 = (byte) 0x02, b03 = (byte) 0x03;
  588.             for (int c = 0; c < 4; c++) {
  589.                 sp[0] = FFMul(b02, s[0][c]) ^ FFMul(b03, s[1][c]) ^ s[2][c] ^ s[3][c];
  590.                 sp[1] = s[0][c] ^ FFMul(b02, s[1][c]) ^ FFMul(b03, s[2][c]) ^ s[3][c];
  591.                 sp[2] = s[0][c] ^ s[1][c] ^ FFMul(b02, s[2][c]) ^ FFMul(b03, s[3][c]);
  592.                 sp[3] = FFMul(b03, s[0][c]) ^ s[1][c] ^ s[2][c] ^ FFMul(b02, s[3][c]);
  593.                 for (int i = 0; i < 4; i++) s[i][c] = (byte) (sp[i]);
  594.             }
  595.  
  596.             return s;
  597.         }
  598.  
  599.         public byte FFMul(byte a, byte b) {
  600.             byte aa = a, bb = b, r = 0, t;
  601.             while (aa != 0) {
  602.                 if ((aa & 1) != 0)
  603.                     r = (byte) (r ^ bb);
  604.                 t = (byte) (bb & 0x80);
  605.                 bb = (byte) (bb << 1);
  606.                 if (t != 0)
  607.                     bb = (byte) (bb ^ 0x1b);
  608.                 aa = (byte) ((aa & 0xff) >> 1);
  609.             }
  610.             return r;
  611.         }
  612.  
  613.         public byte[] encryptBloc(byte[] in) {
  614.             byte[] tmp = new byte[in.length];
  615.  
  616.  
  617.             byte[][] state = new byte[4][Nb];
  618.  
  619.             for (int i = 0; i < in.length; i++)
  620.                 state[i / 4][i % 4] = in[i % 4 * 4 + i / 4];
  621.  
  622.             state = AddRoundKey(state, w, 0);
  623.             for (int round = 1; round < Nr; round++) {
  624.                 state = SubBytes(state);
  625.                 state = ShiftRows(state);
  626.                 state = MixColumns(state);
  627.                 state = AddRoundKey(state, w, round);
  628.             }
  629.             state = SubBytes(state);
  630.             state = ShiftRows(state);
  631.             state = AddRoundKey(state, w, Nr);
  632.  
  633.             for (int i = 0; i < tmp.length; i++)
  634.                 tmp[i % 4 * 4 + i / 4] = state[i / 4][i % 4];
  635.  
  636.             return tmp;
  637.         }
  638.  
  639.         public byte[] decryptBloc(byte[] in) {
  640.             byte[] tmp = new byte[in.length];
  641.  
  642.             byte[][] state = new byte[4][Nb];
  643.  
  644.             for (int i = 0; i < in.length; i++)
  645.                 state[i / 4][i % 4] = in[i % 4 * 4 + i / 4];
  646.  
  647.             state = AddRoundKey(state, w, Nr);
  648.             for (int round = Nr - 1; round >= 1; round--) {
  649.                 state = InvSubBytes(state);
  650.                 state = InvShiftRows(state);
  651.                 state = AddRoundKey(state, w, round);
  652.                 state = InvMixColumns(state);
  653.  
  654.             }
  655.             state = InvSubBytes(state);
  656.             state = InvShiftRows(state);
  657.             state = AddRoundKey(state, w, 0);
  658.  
  659.             for (int i = 0; i < tmp.length; i++)
  660.                 tmp[i % 4 * 4 + i / 4] = state[i / 4][i % 4];
  661.  
  662.             return tmp;
  663.         }
  664.  
  665.         public byte[] encrypt(byte[] in, byte[] key) {
  666.  
  667.             Nb = 4;
  668.             Nk = key.length / 4;
  669.             Nr = Nk + 6;
  670.  
  671.  
  672.             int lenght = 0;
  673.             byte[] padding = new byte[1];
  674.             int i;
  675.             lenght = 16 - in.length % 16;
  676.             padding = new byte[lenght];
  677.             padding[0] = (byte) 0x80;
  678.  
  679.             for (i = 1; i < lenght; i++)
  680.                 padding[i] = 0;
  681.  
  682.             byte[] tmp = new byte[in.length + lenght];
  683.             byte[] bloc = new byte[16];
  684.  
  685.  
  686.             w = generateSubkeys(key);
  687.  
  688.             int count = 0;
  689.  
  690.             for (i = 0; i < in.length + lenght; i++) {
  691.                 if (i > 0 && i % 16 == 0) {
  692.                     bloc = encryptBloc(bloc);
  693.                     System.arraycopy(bloc, 0, tmp, i - 16, bloc.length);
  694.                 }
  695.                 if (i < in.length)
  696.                     bloc[i % 16] = in[i];
  697.                 else {
  698.                     bloc[i % 16] = padding[count % 16];
  699.                     count++;
  700.                 }
  701.             }
  702.             if (bloc.length == 16) {
  703.                 bloc = encryptBloc(bloc);
  704.                 System.arraycopy(bloc, 0, tmp, i - 16, bloc.length);
  705.             }
  706.  
  707.             return tmp;
  708.         }
  709.  
  710.         public byte[] decrypt(byte[] in, byte[] key) {
  711.             int i;
  712.             byte[] tmp = new byte[in.length];
  713.             byte[] bloc = new byte[16];
  714.  
  715.  
  716.             Nb = 4;
  717.             Nk = key.length / 4;
  718.             Nr = Nk + 6;
  719.             w = generateSubkeys(key);
  720.  
  721.  
  722.             for (i = 0; i < in.length; i++) {
  723.                 if (i > 0 && i % 16 == 0) {
  724.                     bloc = decryptBloc(bloc);
  725.                     System.arraycopy(bloc, 0, tmp, i - 16, bloc.length);
  726.                 }
  727.                 if (i < in.length)
  728.                     bloc[i % 16] = in[i];
  729.             }
  730.             bloc = decryptBloc(bloc);
  731.             System.arraycopy(bloc, 0, tmp, i - 16, bloc.length);
  732.  
  733.  
  734.             tmp = deletePadding(tmp);
  735.  
  736.             return tmp;
  737.         }
  738.  
  739.         private byte[] deletePadding(byte[] input) {
  740.             int count = 0;
  741.  
  742.             int i = input.length - 1;
  743.             while (input[i] == 0) {
  744.                 count++;
  745.                 i--;
  746.             }
  747.  
  748.             byte[] tmp = new byte[input.length - count - 1];
  749.             System.arraycopy(input, 0, tmp, 0, tmp.length);
  750.             return tmp;
  751.         }
  752.  
  753.     }
  754.  
  755. }
Advertisement
Add Comment
Please, Sign In to add comment