package utils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
public class Util {
/**
* 密钥
*/
private final static byte[] PASSKEY = new byte[]{0x55, (byte) 0x8B, (byte) 0xEC, 0x51, 0x53, 0x56, (byte) 0x8B,
0x75, 0x08, 0x56, (byte) 0xB8, 0x7C, 0x26, 0x00, 0x01,
(byte) 0xC7};
public static <K, V> Map<K, V> newMap() {
return new HashMap<>();
}
public static <K, V> Map<K, V> newMTMap() {
return new ConcurrentHashMap<>();
}
public static <T> List<T> newList() {
return new ArrayList<>();
}
public static <T> Collection<T> newMTList() {
return new ConcurrentLinkedQueue<>();
}
static public void createDir(String dir) throws IOException {
final File f = new File(dir);
if (!f.exists() && !f.mkdirs())
throw new IOException("Failed to create Dir:" + dir);
if (!f.isDirectory())
throw new IOException("Must be directory!Dir:" + dir);
}
static public String smartMove(File srcFile, String dstDir) {
final String base = FilenameUtils.getBaseName(srcFile.getName());
final String ext = FilenameUtils.getExtension(srcFile.getName());
String fileName = String.format("%s/%s.%s", dstDir, base, ext);
// for (int i = 0; i < 10; ++i)
int i = 1;
do {
try {
FileUtils.moveFile(srcFile, new File(fileName));
break;
} catch (final IOException e) {
fileName = String.format("%s/%s(%d).%s", dstDir, base, i, ext);
i++;
}
} while (true);
return fileName;
}
static public String hex2Str(byte[] data) {
final String HEX = "0123456789ABCDEF";
final StringBuilder sb = new StringBuilder();
for (final byte b : data) {
sb.append(HEX.charAt((b >> 4) & 0x0F));
sb.append(HEX.charAt(b & 0x0F));
}
return sb.toString();
}
public static byte[] encrypt(byte[] buf) throws Exception {
final byte[] pass = PASSKEY;
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final IvParameterSpec dps = new IvParameterSpec(buf, 0, 16);
final SecretKeySpec skeySpec = new SecretKeySpec(pass, "AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, dps);
return cipher.doFinal(buf, 16, buf.length - 16);
}
/**
* 加密
*
* @param buf 字节数组
* @return 解密后的字节数组
* @throws Exception
*/
public static byte[] decrypt(byte[] buf) throws Exception {
final byte[] pass = PASSKEY;
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final IvParameterSpec dps = new IvParameterSpec(buf, 0, 16);
final SecretKeySpec skeySpec = new SecretKeySpec(pass, "AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, dps);
return cipher.doFinal(buf, 16, buf.length - 16);
}
/**
* 获取证书的MD5
*
* @param cert 证书
* @return 证书MD5
*/
static public String getCertMd5(Certificate cert) {
try {
final MessageDigest md = MessageDigest.getInstance("MD5");
md.update(cert.getEncoded());
return hex2Str(md.digest());
} catch (final Exception e) {
e.printStackTrace();
}
return "";
}
static public Certificate[] getJarCerts(File file) {
Certificate[] certs = null;
try {
certs = getCertWithZipFile(file);
} catch (final IOException e) {
try {
certs = getCertWithZipstream(file);
} catch (final IOException e1) {
}
}
return certs;
}
static public Certificate[] getJarCerts(byte[] apkByte) {
Certificate[] certs = null;
try {
certs = getCertWithZipByte(apkByte);
} catch (final IOException e) {
}
return certs;
}
static public String getCertInfo(Certificate cert) {
try {
final CertificateFactory cf = CertificateFactory.getInstance("X.509");
final X509Certificate x509Certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getEncoded()));
return x509Certificate.getSubjectDN().getName();
} catch (final CertificateException e) {
e.printStackTrace();
}
return "";
}
static public String getCertDetail(Certificate cert) {
try {
final CertificateFactory cf = CertificateFactory.getInstance("X.509");
final X509Certificate xcert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getEncoded()));
return xcert.toString();
} catch (final CertificateException e) {
e.printStackTrace();
}
return "";
}
static private Certificate[] getCertWithZipFile(File file) throws IOException {
Certificate[] certs = null;
final byte[] readBuffer = new byte[1024 * 8];
final JarFile jarFile = new JarFile(file);
final Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry je = entries.nextElement();
if (je.isDirectory())
continue;
if (je.getName().startsWith("META-INF/"))
continue;
final InputStream is = jarFile.getInputStream(je);
certs = loadCertificates(is, je, readBuffer);
if (certs != null)
break;
}
jarFile.close();
return certs;
}
static private Certificate[] getCertWithZipstream(File file) throws IOException {
Certificate[] certs = null;
final byte[] readBuffer = new byte[1024 * 8];
final JarInputStream zis = new JarInputStream(new FileInputStream(file));
for (JarEntry je = zis.getNextJarEntry(); je != null; je = zis.getNextJarEntry()) {
if (je.isDirectory())
continue;
if (je.getName().startsWith("META-INF/"))
continue;
certs = loadCertificates(zis, je, readBuffer);
if (certs != null)
break;
}
zis.close();
return certs;
}
static private Certificate[] getCertWithZipByte(byte[] apkByte) throws IOException {
Certificate[] certs = null;
final byte[] readBuffer = new byte[1024 * 8];
final JarInputStream zis = new JarInputStream(new ByteArrayInputStream(apkByte));
for (JarEntry je = zis.getNextJarEntry(); je != null; je = zis.getNextJarEntry()) {
if (je.isDirectory())
continue;
if (je.getName().startsWith("META-INF/"))
continue;
certs = loadCertificates(zis, je, readBuffer);
if (certs != null)
break;
}
zis.close();
return certs;
}
private static Certificate[] loadCertificates(InputStream is, JarEntry je, byte[] readBuffer) {
try {
// We must read the stream for the JarEntry to retrieve
// its certificates.
while (is.read(readBuffer, 0, readBuffer.length) != -1) {
// not using
}
return je.getCertificates();
} catch (final IOException e) {
System.out.printf("Exception reading %s in %s:%s", je.getName(), je.getName(), e);
} catch (final RuntimeException e) {
System.out.printf("Exception reading %s in %s:%s", je.getName(), je.getName(), e);
}
return null;
}
}