因为项目接入腾讯IM,需要在服务端生成sig签名。废话不多说,直接上码。(文档中所涉及到的文件和工具请在文章底部下载)

第一步 申请腾讯云通信应用:

1.腾讯云申请IM,创建一个云通信应用。获取到一下资料

1.SDKAPPID

2.公私钥(public_key、private_key)

3.账号管理员id

2.点击应用配置设置账号集成模式

3.保存更改,下载公私钥

第二步 准备开发资料:

1.使用openssl 将私钥文件(private_key)做转换格式

我的文件目录

打开cmd切换到openssl目录下面执行命令,出现warning不用管它  执行完会生成p8_priv.pem 打开文件里面的内容一会需要用到

2.需要的jar包:

bcpkix-jdk15on-152.jar

bcprov-jdk15on-152.jar

commons-codec-1.10.jar

gson-2.3.1.jar

json.jar

tls_sig_api.jar

3.在项目中导入上面的jar包

4.新建tls_sigature.java

把tls_sigature类中main方法的privStr换成刚刚使用openssl转换后的私钥,pubStr换成你自己的应用生成public_key文件内容。

同样也要把SDKAPPID和identifier换成你自己的 然后运行main方法就可以生成usersig了!

package com.tls.tls_sigature;import java.io.CharArrayReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.nio.charset.Charset;import java.security.Signature;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.util.Arrays;
import org.json.JSONObject;import com.tls.base64_url.base64_url;public class tls_sigature {public static class GenTLSSignatureResult{public String errMessage;public String urlSig;public int expireTime;public int initTime;public GenTLSSignatureResult(){errMessage = "";urlSig = "";}}public static class CheckTLSSignatureResult{public String errMessage;public boolean verifyResult;public int expireTime;public int initTime;public CheckTLSSignatureResult(){errMessage = "";verifyResult = false;}}public static void main(String[] args) {try{         //Use pemfile keys to testString privStr = "-----BEGIN PRIVATE KEY-----\n" +"MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgiBPYMVTjspLfqoq46oZd\n" +"j9A0C8p7aK3Fi6/4zLugCkehRANCAATU49QhsAEVfIVJUmB6SpUC6BPaku1g/dzn\n" +"0Nl7iIY7W7g2FoANWnoF51eEUb6lcZ3gzfgg8VFGTpJriwHQWf5T\n" +"-----END PRIVATE KEY-----";//change public pem string to public stringString pubStr = "-----BEGIN PUBLIC KEY-----\n"+"MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1OPUIbABFXyFSVJgekqVAugT2pLtYP3c\n"+"59DZe4iGO1u4NhaADVp6BedXhFG+pXGd4M34IPFRRk6Sa4sB0Fn+Uw==\n"+"-----END PUBLIC KEY-----";            // generate signatureGenTLSSignatureResult result = GenTLSSignatureEx(1400000955, "xiaojun", privStr);if (0 == result.urlSig.length()) {System.out.println("GenTLSSignatureEx failed: " + result.errMessage);return;}System.out.println("---\ngenerate sig:\n" + result.urlSig + "\n---\n");// check signatureCheckTLSSignatureResult checkResult = CheckTLSSignatureEx(result.urlSig, 1400000955, "xiaojun", pubStr);if(checkResult.verifyResult == false) {System.out.println("CheckTLSSignature failed: " + result.errMessage);return;}System.out.println("\n---\ncheck sig ok -- expire time " + checkResult.expireTime + " -- init time " + checkResult.initTime + "\n---\n");}catch(Exception e){e.printStackTrace();}}/*** @brief 生成 tls 票据* @param expire 有效期,单位是秒,推荐一个月* @param strAppid3rd 填写与 sdkAppid 一致字符串形式的值* @param skdAppid 应用的 appid* @param identifier 用户 id* @param accountType 创建应用后在配置页面上展示的 acctype* @param privStr 生成 tls 票据使用的私钥内容* @return 如果出错,GenTLSSignatureResult 中的 urlSig为空,errMsg 为出错信息,成功返回有效的票据* @throws IOException*/@Deprecatedpublic static GenTLSSignatureResult GenTLSSignature(long expire, String strAppid3rd, long skdAppid, String identifier, long accountType, String privStr ) throws IOException{GenTLSSignatureResult result = new GenTLSSignatureResult();Security.addProvider(new BouncyCastleProvider());Reader reader = new CharArrayReader(privStr.toCharArray());JcaPEMKeyConverter converter = new JcaPEMKeyConverter();PEMParser parser = new PEMParser(reader);Object obj = parser.readObject();parser.close();PrivateKey privKeyStruct = converter.getPrivateKey((PrivateKeyInfo) obj);//Create Json string and serialization String String jsonString = "{" + "\"TLS.account_type\":\"" + accountType +"\","+"\"TLS.identifier\":\"" + identifier +"\","+"\"TLS.appid_at_3rd\":\"" + strAppid3rd +"\","+"\"TLS.sdk_appid\":\"" + skdAppid +"\","+"\"TLS.expire_after\":\"" + expire +"\""+"}";//System.out.println("#jsonString : \n" + jsonString);String time = String.valueOf(System.currentTimeMillis()/1000);String SerialString = "TLS.appid_at_3rd:" + strAppid3rd + "\n" +"TLS.account_type:" + accountType + "\n" +"TLS.identifier:" + identifier + "\n" + "TLS.sdk_appid:" + skdAppid + "\n" + "TLS.time:" + time + "\n" +"TLS.expire_after:" + expire +"\n";//System.out.println("#SerialString : \n" + SerialString);//System.out.println("#SerialString Hex: \n" + Hex.encodeHexString(SerialString.getBytes()));try{//Create Signature by SerialStringSignature signature = Signature.getInstance("SHA256withECDSA", "BC");signature.initSign(privKeyStruct);signature.update(SerialString.getBytes(Charset.forName("UTF-8")));byte[] signatureBytes = signature.sign();String sigTLS = Base64.encodeBase64String(signatureBytes);//System.out.println("#sigTLS : " + sigTLS);//Add TlsSig to jsonStringJSONObject jsonObject= new JSONObject(jsonString);jsonObject.put("TLS.sig", (Object)sigTLS);jsonObject.put("TLS.time", (Object)time);jsonString = jsonObject.toString();// System.out.println("#jsonString : \n" + jsonString);//compressionDeflater compresser = new Deflater();compresser.setInput(jsonString.getBytes(Charset.forName("UTF-8")));compresser.finish();byte [] compressBytes = new byte [512];int compressBytesLength = compresser.deflate(compressBytes);compresser.end();//System.out.println("#compressBytes "+ compressBytesLength+": " + Hex.encodeHexString(Arrays.copyOfRange(compressBytes,0,compressBytesLength)));//String userSig = Base64.encodeBase64URLSafeString(Arrays.copyOfRange(compressBytes,0,compressBytesLength));String userSig = new String(base64_url.base64EncodeUrl(Arrays.copyOfRange(compressBytes,0,compressBytesLength)));result.urlSig = userSig;//System.out.println("urlSig: "+ userSig);}catch(Exception e){e.printStackTrace();result.errMessage = "generate usersig failed";}return result;}/*** @brief 校验 tls 票据* @param urlSig 返回 tls 票据* @param strAppid3rd 填写与 sdkAppid 一致的字符串形式的值* @param skdAppid 应的 appid* @param identifier 用户 id* @param accountType 创建应用后在配置页面上展示的 acctype* @param publicKey 用于校验 tls 票据的公钥内容,但是需要先将公钥文件转换为 java 原生 api 使用的格式,下面是推荐的命令*         openssl pkcs8 -topk8 -in ec_key.pem -outform PEM -out p8_priv.pem -nocrypt* @return 如果出错 CheckTLSSignatureResult 中的 verifyResult 为 false,错误信息在 errMsg,校验成功为 true* @throws DataFormatException*/@Deprecatedpublic static CheckTLSSignatureResult CheckTLSSignature( String urlSig,String strAppid3rd, long skdAppid, String identifier, long accountType, String publicKey ) throws DataFormatException{CheckTLSSignatureResult result = new CheckTLSSignatureResult();  Security.addProvider(new BouncyCastleProvider());//DeBaseUrl64 urlSig to jsonBase64 decoder = new Base64();//byte [] compressBytes = decoder.decode(urlSig.getBytes());byte [] compressBytes = base64_url.base64DecodeUrl(urlSig.getBytes(Charset.forName("UTF-8")));//System.out.println("#compressBytes Passing in[" + compressBytes.length + "] " + Hex.encodeHexString(compressBytes));//DecompressionInflater decompression =  new Inflater();decompression.setInput(compressBytes, 0, compressBytes.length);byte [] decompressBytes = new byte [1024];int decompressLength = decompression.inflate(decompressBytes);decompression.end();String jsonString = new String(Arrays.copyOfRange(decompressBytes, 0, decompressLength));//System.out.println("#Json String passing in : \n" + jsonString);//Get TLS.Sig from jsonJSONObject jsonObject= new JSONObject(jsonString);String sigTLS = jsonObject.getString("TLS.sig");//debase64 TLS.Sig to get serailStringbyte[] signatureBytes = decoder.decode(sigTLS.getBytes(Charset.forName("UTF-8")));try{String sigTime = jsonObject.getString("TLS.time");String sigExpire = jsonObject.getString("TLS.expire_after");//checkTime//System.out.println("#time check: "+ System.currentTimeMillis()/1000 + "-" //+ Long.parseLong(sigTime) + "-" + Long.parseLong(sigExpire));if( System.currentTimeMillis()/1000 - Long.parseLong(sigTime) > Long.parseLong(sigExpire)){result.errMessage = new String("TLS sig is out of date ");System.out.println("Timeout");return result;}//Get Serial String from jsonString SerialString = "TLS.appid_at_3rd:" + strAppid3rd + "\n" +"TLS.account_type:" + accountType + "\n" +"TLS.identifier:" + identifier + "\n" + "TLS.sdk_appid:" + skdAppid + "\n" + "TLS.time:" + sigTime + "\n" + "TLS.expire_after:" + sigExpire + "\n";//System.out.println("#SerialString : \n" + SerialString);Reader reader = new CharArrayReader(publicKey.toCharArray());PEMParser  parser = new PEMParser(reader);JcaPEMKeyConverter converter = new JcaPEMKeyConverter();Object obj = parser.readObject();parser.close();PublicKey pubKeyStruct  = converter.getPublicKey((SubjectPublicKeyInfo) obj);Signature signature = Signature.getInstance("SHA256withECDSA","BC");signature.initVerify(pubKeyStruct);signature.update(SerialString.getBytes(Charset.forName("UTF-8")));boolean bool = signature.verify(signatureBytes);//System.out.println("#jdk ecdsa verify : " + bool);result.verifyResult = bool;}catch(Exception e){e.printStackTrace();result.errMessage = "Failed in checking sig";}return result;}/*** @brief 生成 tls 票据,精简参数列表,有效期默认为 180 天* @param skdAppid 应用的 sdkappid* @param identifier 用户 id* @param privStr 私钥文件内容* @return* @throws IOException*/public static GenTLSSignatureResult GenTLSSignatureEx(long skdAppid,String identifier,String privStr) throws IOException {return GenTLSSignatureEx(skdAppid, identifier, privStr, 3600*24*180);}/*** @brief 生成 tls 票据,精简参数列表* @param skdAppid 应用的 sdkappid* @param identifier 用户 id* @param privStr 私钥文件内容* @param expire 有效期,以秒为单位,推荐时长一个月* @return* @throws IOException*/public static GenTLSSignatureResult GenTLSSignatureEx(long skdAppid,String identifier,String privStr,long expire) throws IOException {GenTLSSignatureResult result = new GenTLSSignatureResult();Security.addProvider(new BouncyCastleProvider());Reader reader = new CharArrayReader(privStr.toCharArray());JcaPEMKeyConverter converter = new JcaPEMKeyConverter();PEMParser parser = new PEMParser(reader);Object obj = parser.readObject();parser.close();PrivateKey privKeyStruct = converter.getPrivateKey((PrivateKeyInfo) obj);String jsonString = "{" + "\"TLS.account_type\":\"" + 0 +"\","+"\"TLS.identifier\":\"" + identifier +"\","+"\"TLS.appid_at_3rd\":\"" + 0 +"\","+"\"TLS.sdk_appid\":\"" + skdAppid +"\","+"\"TLS.expire_after\":\"" + expire +"\","+"\"TLS.version\": \"201512300000\""+"}";String time = String.valueOf(System.currentTimeMillis()/1000);String SerialString = "TLS.appid_at_3rd:" + 0 + "\n" +"TLS.account_type:" + 0 + "\n" +"TLS.identifier:" + identifier + "\n" + "TLS.sdk_appid:" + skdAppid + "\n" + "TLS.time:" + time + "\n" +"TLS.expire_after:" + expire +"\n";try {//Create Signature by SerialStringSignature signature = Signature.getInstance("SHA256withECDSA", "BC");signature.initSign(privKeyStruct);signature.update(SerialString.getBytes(Charset.forName("UTF-8")));byte[] signatureBytes = signature.sign();String sigTLS = Base64.encodeBase64String(signatureBytes);//Add TlsSig to jsonStringJSONObject jsonObject= new JSONObject(jsonString);jsonObject.put("TLS.sig", (Object)sigTLS);jsonObject.put("TLS.time", (Object)time);jsonString = jsonObject.toString();//compressionDeflater compresser = new Deflater();compresser.setInput(jsonString.getBytes(Charset.forName("UTF-8")));compresser.finish();byte [] compressBytes = new byte [512];int compressBytesLength = compresser.deflate(compressBytes);compresser.end();String userSig = new String(base64_url.base64EncodeUrl(Arrays.copyOfRange(compressBytes,0,compressBytesLength)));result.urlSig = userSig;}catch(Exception e){e.printStackTrace();result.errMessage = "generate usersig failed";}return result;}public static CheckTLSSignatureResult CheckTLSSignatureEx(String urlSig,long sdkAppid, String identifier, String publicKey ) throws DataFormatException {CheckTLSSignatureResult result = new CheckTLSSignatureResult();    Security.addProvider(new BouncyCastleProvider());//DeBaseUrl64 urlSig to jsonBase64 decoder = new Base64();byte [] compressBytes = base64_url.base64DecodeUrl(urlSig.getBytes(Charset.forName("UTF-8")));//DecompressionInflater decompression =  new Inflater();decompression.setInput(compressBytes, 0, compressBytes.length);byte [] decompressBytes = new byte [1024];int decompressLength = decompression.inflate(decompressBytes);decompression.end();String jsonString = new String(Arrays.copyOfRange(decompressBytes, 0, decompressLength));//Get TLS.Sig from jsonJSONObject jsonObject= new JSONObject(jsonString);String sigTLS = jsonObject.getString("TLS.sig");//debase64 TLS.Sig to get serailStringbyte[] signatureBytes = decoder.decode(sigTLS.getBytes(Charset.forName("UTF-8")));try {String strSdkAppid = jsonObject.getString("TLS.sdk_appid");String sigTime = jsonObject.getString("TLS.time");String sigExpire = jsonObject.getString("TLS.expire_after");if (Integer.parseInt(strSdkAppid) != sdkAppid){result.errMessage = new String(    "sdkappid "+ strSdkAppid+ " in tls sig not equal sdkappid "+ sdkAppid+ " in request");return result;}if ( System.currentTimeMillis()/1000 - Long.parseLong(sigTime) > Long.parseLong(sigExpire)) {result.errMessage = new String("TLS sig is out of date");return result;}//Get Serial String from jsonString SerialString = "TLS.appid_at_3rd:" + 0 + "\n" +"TLS.account_type:" + 0 + "\n" +"TLS.identifier:" + identifier + "\n" + "TLS.sdk_appid:" + sdkAppid + "\n" + "TLS.time:" + sigTime + "\n" + "TLS.expire_after:" + sigExpire + "\n";Reader reader = new CharArrayReader(publicKey.toCharArray());PEMParser  parser = new PEMParser(reader);JcaPEMKeyConverter converter = new JcaPEMKeyConverter();Object obj = parser.readObject();parser.close();PublicKey pubKeyStruct  = converter.getPublicKey((SubjectPublicKeyInfo) obj);Signature signature = Signature.getInstance("SHA256withECDSA","BC");signature.initVerify(pubKeyStruct);signature.update(SerialString.getBytes(Charset.forName("UTF-8")));boolean bool = signature.verify(signatureBytes);result.expireTime = Integer.parseInt(sigExpire);result.initTime = Integer.parseInt(sigTime);result.verifyResult = bool;}catch(Exception e){e.printStackTrace();result.errMessage = "Failed in checking sig";}return result;}}
base64_url.java

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.util.Arrays;public class base64_url {static  byte base64_table_url[] ={ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M','N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm','n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z','0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '-', '\0'};static  byte base64_pad_url = '_';static  short base64_reverse_table_url[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, 63, -1, -1,52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};public static int unsignedToBytes(int b){return b & 0xFF;}//int base64_encode_url(const unsigned char *in_str, int length, char *out_str,int *ret_length)public static byte [] base64EncodeUrl(byte [] in_str){byte [] out_str = new byte [1024] ;int out_current = 0;int current = 0;int length = in_str.length;while (length > 2) { /* keep going until we have less than 24 bits */out_str[out_current++] = base64_table_url[unsignedToBytes((unsignedToBytes(in_str[current]) >>> 2))];out_str[out_current++] = base64_table_url[unsignedToBytes(unsignedToBytes(unsignedToBytes(in_str[current]) & 0x03) << 4) + unsignedToBytes((unsignedToBytes(in_str[current+1]) >>> 4))];out_str[out_current++] = base64_table_url[(unsignedToBytes((unsignedToBytes(in_str[current+1]) & 0x0f)) << 2) + unsignedToBytes((unsignedToBytes(in_str[current+2]) >>> 6))];out_str[out_current++] = base64_table_url[unsignedToBytes((unsignedToBytes(in_str[current+2]) & 0x3f))];current += 3;length -= 3; /* we just handle 3 octets of data */}/* now deal with the tail end of things */if (length != 0) {out_str[out_current++] = base64_table_url[unsignedToBytes(in_str[current]) >>> 2];if (length > 1) {out_str[out_current++] = base64_table_url[unsignedToBytes((unsignedToBytes(in_str[current]) & 0x03) << 4) + unsignedToBytes(unsignedToBytes(in_str[current+1]) >>> 4)];out_str[out_current++] = base64_table_url[unsignedToBytes((unsignedToBytes(in_str[current + 1]) & 0x0f) << 2)];out_str[out_current++] = base64_pad_url;} else {out_str[out_current++] = base64_table_url[unsignedToBytes((unsignedToBytes(in_str[current]) & 0x03) << 4)];out_str[out_current++] = base64_pad_url;out_str[out_current++] = base64_pad_url;}}//System.out.println("length in base64EncodeUrl: " + out_current );byte [] out_bytes = new String(out_str).getBytes(); return Arrays.copyOfRange(out_bytes, 0, out_current);}//int base64_decode_url(const unsigned char *in_str, int length, char *out_str, int *ret_length)public static byte [] base64DecodeUrl(byte [] in_str){//        const unsigned char *current = in_str;int ch, i = 0, j = 0, k;int current  = 0;int result = 0;byte [] out_str = new byte [1024] ;int length = in_str.length;/* this sucks for threaded environments *//* run through the whole string, converting as we go *///while ((ch = in_str[current++]) != '\0' && length-- > 0) {ch = in_str[0];while(length-- > 0){ch = in_str[current++];if (ch == base64_pad_url) break;/* When Base64 gets POSTed, all pluses are interpreted as spaces.This line changes them back.  It's not exactly the Base64 spec,but it is completely compatible with it (the spec says thatspaces are invalid).  This will also save many people considerableheadache.  - Turadg Aleahmad <turadg@wise.berkeley.edu>*/if (ch == ' ') ch = '*'; //never using '+'ch = base64_reverse_table_url[ch];if (ch < 0) continue;switch(i % 4) {case 0:out_str[j] = (byte) unsignedToBytes( unsignedToBytes(ch) << 2);break;case 1:out_str[j++] |= (byte) unsignedToBytes(unsignedToBytes(ch) >>> 4);out_str[j] = (byte) unsignedToBytes(unsignedToBytes(unsignedToBytes(ch) & 0x0f) << 4);break;case 2:out_str[j++] |= (byte) unsignedToBytes(unsignedToBytes(ch) >>> 2);out_str[j] = (byte) unsignedToBytes(unsignedToBytes(unsignedToBytes(ch) & 0x03) << 6);break;case 3:out_str[j++] |= (byte) unsignedToBytes(ch);break;}i++;}k = j;/* mop things up if we ended on a boundary */if (ch == base64_pad_url) {   switch(i % 4) {case 0:case 1:byte [] error =  new byte [1];error[0] = '\0';return error;case 2:k++;case 3:out_str[k++] = 0;}}return Arrays.copyOfRange(out_str, 0, j);}public static void main(String[] args) throws DecoderException {//String hexString = "5095";String hexString = "789c6d8d4d4f83401884ff0b578c5dba0bbb98782015b1a1f8059a7222743fc8da96aecbdbdad6f8dfa5046fce6de6c9cc7c3bc522bfeec4baaa8dd1c2b9713c822e0a7ddfb91aa03c1a6d65552b90b6e794d2a0e7231c5a550d15b6ff96416fe590e38051c2281d732d640b5ae96172ea051c29be524c62e463e57382e854a08020a578c8febe38dfed5ba8e0642e9b98e21174bae97d16bfcde633299e0f49c81f27a26490b97665d7675dd0fdc35df1de994d23bc4301db349fbb918ea3e36b509878f7956d84dbb44b4ed23287b454f7119c12fea4968b64927d7c962179b9757e7e01ed1059d9";byte [] test = Hex.decodeHex(hexString.toCharArray());byte [] compressBytes = base64EncodeUrl(test);System.out.println("compress : " + new String(compressBytes));byte [] uncompressBytes = base64DecodeUrl(compressBytes);System.out.println("uncompress: " + Hex.encodeHexString(uncompressBytes));}
}

下载

点击下载jar包和sig工具

java服务端集成腾讯IM 腾讯云通讯生成usersig的方法相关推荐

  1. java服务端集成信鸽推送

    java服务端集成信鸽推送 最近项目需要集成推送功能,突发奇想的选了信鸽推送(可能是最近一直在用阿里的东西),没想到这坑不是一般的多,而且关于详细的集成案例,度娘上真是没一个能入眼的.算了,别的不多说 ...

  2. java服务端集成极光消息推送--详细开发步骤

    1.极光推送账号准备 要使用极光消息推送必须先在官方网站上注册账号,并添加应用. 产品介绍:https://docs.jiguang.cn/jpush/guideline/intro/ 注册开发者账号 ...

  3. 详解个推java服务端集成

    随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) 一.简介 个推是商用级的移动应用消息推送云服务解决方案,客户端SDK支持Android和iOS两大平台,云端支 ...

  4. 微信小程序支付java服务端集成采坑总结

    先上个微信小程序支付官方文档地址: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7&index=8 重点看 ...

  5. java服务端集成极光消息推送

    极光推送官网地址:https://www.jiguang.cn/ api文档:https://docs.jiguang.cn/jpush/server/push/server_overview/ 1. ...

  6. Java服务端集成支付宝支付SDK

    文章目录 文档 流程说明 添加依赖 集成步骤 常见问题 文档 蚂蚁金服官方文档 https://docs.open.alipay.com/54/103419/https://docs.open.ali ...

  7. JAVA服务端的解码

    JAVA服务端的解码        引起乱码问题的缘由是编码与解码方法的不对称,为了能和客户端正确的交互,需要了解下服务端是何时,何处以及如何对内容进行编解码的.按照请求处理的过程,我们先来一一分析一 ...

  8. Java服务端集成环信IM

    由于业务需求,需要在系统中集成环信,所以去看了下官方文档,写篇博客分享一下. 在开始之前,我们需要了解一下什么是REST. REST(Representational State Transfer)是 ...

  9. 支付宝APP支付Java服务端

    支付宝APP支付Java服务端: 公司项目要求对接支付宝进行支付功能,这边做出整理方便以后使用(支付宝的支付对接还是很简单的). 1):去支付宝开放平台,-1.注册账号,2.创建应用 3.配置应用 4 ...

  10. java服务端是什么,持续更新~

    Java反射机制是什么?Java反射机制是Java语言的一个重要特性.在学习Java反射机制前,大家应该先了解两个概念,编译期和运行期.编译期是指把源码交给编译器 Java反射机制在服务器程序和中间件 ...

最新文章

  1. 【原创】如何在 Linux 下调整可打开文件/文件描述符数目
  2. python获取数据库查询的元数据_Python数据库、MySQL存储引擎、使用分区表、更改表结构、获取数据库元数据...
  3. 页游开发_小花仙即将出手游,敬童年一起玩过的7K7K和4399
  4. pure tornado -- table
  5. day4 java中print,printf,println的区别
  6. 这届年轻人,没到35岁就开始准备退休了
  7. DX中材质不能正确显示的问题(要么黑色,要么白色)
  8. bzoj 1821: [JSOI2010]Group 部落划分
  9. bp神经网络模型的优缺点,什么是BP神经网络模型?
  10. Tomcat 服务详解
  11. 决策树分类算法(包含隐形眼镜分类的代码)
  12. python交并补_python开发学习- ( 字典的相关函数 集合中的交差并补 集合相关的函数 冰冻集合)...
  13. 网络通信,IP地址, 端口,socket
  14. 水溶性羧基化 CdSe/ZnS 量子的特点
  15. kubeadm构建k8s之Prometheus-operated监控(0.18.1)
  16. Matlab人形机器人建模与仿真
  17. ServiceWorker 缓存与 HTTP 缓存
  18. java编程成绩评分分等级_java编写成绩等级,最高分为best
  19. vbs脚本实现Ping功能
  20. 一图看懂:信号的时域、频域、相位 ​​​​

热门文章

  1. android不透明度对应的值
  2. Self-Supervised 3D Face Reconstruction via Conditional Estimation
  3. 怎么查询显卡hdmi接口版本_HDMI接口基础知识大扫盲
  4. “程序员年薪50万到底有多累、多辛苦?”,句句扎心
  5. eclipse的优缺点
  6. 《居里夫人自传》读后感
  7. SPSS——描述性统计分析——探索性分析
  8. 【数学建模】二手房房价影响因素分析(描述性统计+推断统计综合应用、线性回归预测分析)
  9. java得到日期相减的天数_java得到日期相减的天数
  10. Android 真实 简历