1. 帮助工具

1.1. 图片上传Demo

业务中提供了图片文件上传接口,为了方便第三方业务集成图片文件上传接口,固此提供Demo示例:

1.1.1. Java版本

import com.megvii.bbu.common.util.bone.MegviiCommonErrorCode;
import com.megvii.bbu.common.util.bone.MegviiException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import javax.net.ssl.*;
import java.io.File;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

;

@Slf4j
public class OkHttpUtil {

    private static final byte[] LOCKER = new byte[0];
    private static OkHttpUtil instance;
    private static OkHttpUtil httpsInstance;
    private OkHttpClient okHttpClient;

    private OkHttpClient getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            TrustAllManager trustAllManager = new TrustAllManager();
            TrustManager[] trustManagers = {trustAllManager};
            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustManagers, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, trustAllManager);
            builder.hostnameVerifier(new HostnameVerifier() {

                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            OkHttpClient okHttpClient = builder.build();
            return okHttpClient;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private OkHttpUtil(boolean https) {
        OkHttpClient.Builder builder;
        if (https) {
            builder = getUnsafeOkHttpClient().newBuilder();
        } else {
            builder = new OkHttpClient.Builder();
        }

        okHttpClient = builder
                // 10秒连接超时
                .connectTimeout(10, TimeUnit.SECONDS)
                // 写入超时
                .writeTimeout(900, TimeUnit.SECONDS)
                // 读取超时
                .readTimeout(900, TimeUnit.SECONDS).build();
    }

    public static OkHttpUtil getInstance() {
        if (instance == null) {
            synchronized (LOCKER) {
                if (instance == null) {
                    instance = new OkHttpUtil(false);
                }
            }
        }
        return instance;
    }

    /**
     * true -https
     * false -http
     *
     * @param https
     * @return
     */
    public static OkHttpUtil getInstance(boolean https) {
        if (!https) {
            return getInstance();
        }
        if (httpsInstance == null) {
            synchronized (LOCKER) {
                if (httpsInstance == null) {
                    httpsInstance = new OkHttpUtil(https);
                }
            }
        }
        return httpsInstance;
    }

    public String doPostFormMultipart(String targetUrl, String fileUrl, Map<String, String> headers) {
        if (isBlankUrl(targetUrl) || isBlankUrl(fileUrl)) {
            return null;
        }
        Request request = getRequestForPostFormMultipart(targetUrl, fileUrl, headers);
        return commonRequest(request);
    }

    private Boolean isBlankUrl(String url) {
        if (StringUtils.isBlank(url)) {
            log.info("url is not blank");
            return true;
        } else {
            return false;
        }
    }

    private String commonRequest(Request request) {
        String re = "";
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful()) {
                re = response.body().string();
                log.info("request url:{};response:{}", request.url().toString(), re);
            } else {
                log.info("request failure url:{};message:{}", request.url().toString(), response.message());
                throw new Exception("code:" + response.code() + "request failure url:" + request.url().toString()
                        + ";message:" + response.message());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("request execute failure", e);
            throw new MegviiException(MegviiCommonErrorCode.SYSTEM_ERROR);
        }
        return re;
    }

    private Request getRequestForPostFormMultipart(String serverUrl, String fileUrl, Map<String, String> headers) {
        if (headers == null) {
            headers = new HashMap<>();
        }
        File file = new File(fileUrl);//文件路径(本地)
        String filename = file.getName();
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        builder.addFormDataPart("file", filename, RequestBody.create(MediaType.parse("multipart/form-data"), file));
        Request request = new Request.Builder().url(serverUrl).post(builder.build())
                .addHeader("File-Length", String.valueOf(file.length())).addHeader("Content-Type", "multipart/form-data")
                .header("Connection", "close").header("Accept-Encoding", "identity")
                //签名
                .header("cappkey", headers.get("cappkey"))
                .header("ctimestamp", headers.get("ctimestamp"))
                .header("cnonce", headers.get("cnonce"))
                .header("csign", headers.get("csign"))
                .build();
        return request;
    }

    private Request getRequestForGet(String url, HashMap<String, String> params) {
        Request request = new Request.Builder().url(getUrlStringForGet(url, params)).build();
        return request;
    }

    private String getUrlStringForGet(String url, HashMap<String, String> params) {
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(url);
        urlBuilder.append("?");
        if (params != null && params.size() > 0) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                try {
                    urlBuilder.append("&").append(entry.getKey()).append("=")
                            .append(URLEncoder.encode(entry.getValue(), "UTF-8"));
                } catch (Exception e) {
                    urlBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue());
                }
            }
        }
        return urlBuilder.toString();
    }

    public static class TrustAllManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }


    public static void main(String[] args) {
        //服务端上传接口,假设鸿图服务器地址为:10.171.16.76,以图片上传接口为例,如下:
        String targetUrl = "http://10.171.16.76/v1/api/person/uploadImage";
        //本地要上传的文件
        String fileUrl = "C:\\Users\\work\\Desktop/2.jpg";
        //签名信息
        Map<String, String> files = new HashMap<>();
        files.put("cappkey", "appkey1");
        files.put("cnonce", "1234344");
        files.put("ctimestamp", "1234344");
        files.put("csign", "974228f6c7c56bb1320f8501c01aa991");
        //http 地址请求 ;false 表示
        String ret = OkHttpUtil.getInstance(false).doPostFormMultipart(targetUrl, fileUrl, files);
        System.out.println(ret);
        //https 地址请求 ;true 表示
        String rets = OkHttpUtil.getInstance(true).doPostFormMultipart(targetUrl, fileUrl, files);
        System.out.println(rets);
    }
}

1.2. AES加解密工具类

1.2.1. Java版本

密钥需要通过Web端【系统管理-全局参数配置-完全参数配置-加密因子配置】下查看

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;

/**
 * AES加密器
 */
public class AESUtil {

    public static final String CHAR_ENCODING = "UTF-8";

    public static final String AES_ALGORITHM = "AES";

    /**
     * 加密
     * 
     * @param data
     *            待加密内容
     * @param key
     *            加密秘钥
     * @return 十六进制字符串
     */
    public static String encrypt(String data, String key) {
        if (key.length() < 16) {
            throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
        } else if (key.length() > 16) {
            key = key.substring(0, 16);
        }
        try {
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);// 创建密码器
            byte[] byteContent = data.getBytes(CHAR_ENCODING);
            cipher.init(Cipher.ENCRYPT_MODE, genKey(key));// 初始化
            byte[] result = cipher.doFinal(byteContent);
            return parseByte2HexStr(result); // 加密
        } catch (Exception e) {
        }
        return null;

    }

    /**
     * 解密
     * 
     * @param data
     *            待解密内容(十六进制字符串)
     * @param key
     *            加密秘钥
     * @return
     */
    public static String decrypt(String data, String key) {
        if (key.length() < 16) {
            throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
        } else if (key.length() > 16) {
            key = key.substring(0, 16);
        }
        try {
            byte[] decryptFrom = parseHexStr2Byte(data);
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, genKey(key));// 初始化
            byte[] result = cipher.doFinal(decryptFrom);
            return new String(result, "utf-8"); // 加密
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 创建加密解密密钥
     * 
     * @param key
     *            加密解密密钥
     * @return
     */
    private static SecretKeySpec genKey(String key) {
        SecretKeySpec secretKey;
        try {
            secretKey = new SecretKeySpec(key.getBytes(CHAR_ENCODING), AES_ALGORITHM);
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec seckey = new SecretKeySpec(enCodeFormat, AES_ALGORITHM);
            return seckey;
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("genKey fail!", e);
        }
    }

    /**
     * 将二进制转换成16进制
     * 
     * @param buf
     * @return
     */
    private static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将16进制转换为二进制
     * 
     * @param hexStr
     * @return
     */
    private static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }
}

AES 使用demo:

public class AesDemo {

    public static void main(String[] args) {
        aesEncryptDemo();
        aesDecryptDemo();
    }

    /**
     * aes解密demo
     */
    public static void aesDecryptDemo() {
        // 加密因子:
        String key = "64d64143a0973fb8";
        // 从OpenAPI 获取到的密文身份证号
        String encryptIdentifyNumFromOpenAPI = "9397D1730FE8F05B391CDBADA3A2B0135DA552D20978757513C14BE3D57019D2";
        // 使用aes解密得到明文身份证号
        String identifyNumAfterDecrypt = AESUtil.decrypt(encryptIdentifyNumFromOpenAPI, key);
        System.out.println(identifyNumAfterDecrypt);
    }

    /**
     * aes加密demo
     */
    public static void aesEncryptDemo() {
        // 加密因子:
        String key = "64d64143a0973fb8";
        // 明文身份证号
        String identifyNum = "510222199809076543";
        // 使用aes加密得到密文身份证号
        String encryptIdentifyNum = AESUtil.encrypt(identifyNum, key);
        System.out.println(encryptIdentifyNum);
    }
}

1.2.2. Go版本

密钥需要通过Web端【系统管理-全局参数配置-完全参数配置-加密因子配置】下查看

package helper

import (
    "bytes"
    "crypto/aes"
    "encoding/hex"
    "strings"
)


//使用PKCS7进行填充,IOS也是7
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

func PKCS7UnPadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}


func AESDecrypt(data, key string) string {
    // 截取key的前16位
    if len(key) < 16 {
        panic("invalid key")
    }
    if len(key) > 16 {
        key = key[0 : 16]
    }
    // 将字符串都转换成小写
    data = strings.ToLower(data)
    // 将字符串从16进制转换成字节数组
    dataByte, err := hex.DecodeString(data)
    if err != nil {
        panic("hex decode error")
    }
    // 解密
    block, _ := aes.NewCipher([]byte(key))
    decrypted := make([]byte, len(dataByte))
    size := block.BlockSize()

    for bs, be := 0, size; bs < len(dataByte); bs, be = bs+size, be+size {
        block.Decrypt(decrypted[bs:be], dataByte[bs:be])
    }
    decrypted = PKCS7UnPadding(decrypted)
    // 将解密后的字节数组转换成字符串
    return string(decrypted)
}



func AESEncrypt(data, key string) string {
    // 截取key的前16位
    if len(key) < 16 {
        panic("invalid key")
    }
    if len(key) > 16 {
        key = key[0 : 16]
    }
    // 将data 转换成字节数组
    dataByte := []byte(data)
    // 加密
    block, _ := aes.NewCipher([]byte(key))
    dataByte = PKCS7Padding(dataByte, block.BlockSize())
    decrypted := make([]byte, len(dataByte))
    size := block.BlockSize()

    for bs, be := 0, size; bs < len(dataByte); bs, be = bs+size, be+size {
        block.Encrypt(decrypted[bs:be], dataByte[bs:be])
    }
    // 加密后转换成十六进制并都转换成大写
    return strings.ToUpper(hex.EncodeToString(decrypted))
}

AES 使用demo:

package main

import (
    "fmt"
    "practice/helper"
)

func main() {
    // 明文
    plaintext := "12300199809087766"
    // 秘钥
    key := "W8p102YW9AZQ117g4t4z241pr6IM9oF49Q3L4pwsuWRE0E7Z04GM1819A217"
    // 进行加密
    encrypt := helper.AESEncrypt(plaintext, key)
    fmt.Println("加密后:", encrypt)
    // 将密文进行解密
    decrypt := helper.AESDecrypt(encrypt, key)
    fmt.Println("解密后:", decrypt)
}

results matching ""

    No results matching ""