根据火山引擎的签名算法,生成签名,下面是链接可以阅读一下,接下来直接上代码。
https://www.volcengine.com/docs/6369/67269#%E6%AD%A5%E9%AA%A4%E5%85%AD%EF%BC%9A%E5%B0%86%E7%AD%BE%E5%90%8D%E6%B7%BB%E5%8A%A0%E8%87%B3%E8%AF%B7%E6%B1%82

需要特别注意的是 你的appid 和appkey 并不是SecretAccessKey和AccessKeyID我被卡了一下午就是因为把appid和key当成acckey和keyID了。

public class Sign {

    private static final BitSet URLENCODER = new BitSet(256);

    private static final String CONST_ENCODE = "0123456789ABCDEF";
    public static final Charset UTF_8 = StandardCharsets.UTF_8;

    private final String region;
    private final String service;
    private final String schema;
    private final String host;
    private final String path;
    private final String ak;
    private final String sk;

    static {
        int i;
        for (i = 97; i <= 122; ++i) {
            URLENCODER.set(i);
        }

        for (i = 65; i <= 90; ++i) {
            URLENCODER.set(i);
        }

        for (i = 48; i <= 57; ++i) {
            URLENCODER.set(i);
        }
        URLENCODER.set('-');
        URLENCODER.set('_');
        URLENCODER.set('.');
        URLENCODER.set('~');
    }

    public Sign(String region, String service, String schema, String host, String path, String ak, String sk) {
        this.region = region;
        this.service = service;
        this.host = host;
        this.schema = schema;
        this.path = path;
        this.ak = ak;
        this.sk = sk;
    }

//    public static void main(String[] args) throws Exception {
//        String SecretAccessKey = 你的accKey;
//        String AccessKeyID = 你的accId;
//        // 请求地址 //替换为你火山业务的请求地址 必填
//        String endpoint = "rtc.volcengineapi.com";
//        String path = "/"; // 路径,不包含 Query// 请求接口信息
          //业务名称 必填
//        String service = "rtc";
//        String region = "cn-beijing";
//        String schema = "https";
          //签名
//        Sign sign = new Sign(region, service, schema, endpoint, path, AccessKeyID, SecretAccessKey,你的roomid);
//        //什么业务,我的业务是rtc的查房 必填
//        String action = "GetRoomOnlineUsers";
          //版本 必填
//        String version = "2023-11-01";
//
//        Date date = new Date();
//        HashMap<String, String> queryMap = new HashMap<>();
//
//
//        String result = sign.doRequest("GET", queryMap, null, date, action, version);
           GetRoomOnlineUsersResponse response = JSONObject.parseObject(result, GetRoomOnlineUsersResponse.class);
//    }

    public String doRequest(String method, Map<String, String> queryList, byte[] body, Date date, String action, String version,String roomId) throws Exception {
        if (body == null) {
            body = new byte[0];
        }
        String xContentSha256 = hashSHA256(body);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        String xDate = sdf.format(date);
        String shortXDate = xDate.substring(0, 8);
        String contentType = "application/x-www-form-urlencoded";

        String signHeader = "host;x-date;x-content-sha256;content-type";


        SortedMap<String, String> realQueryList = new TreeMap<>(queryList);
        realQueryList.put("Action", action);
        realQueryList.put("Version", version);
        realQueryList.put("RoomId", roomId);
        System.out.println("room:"+roomId);
        realQueryList.put("AppId", "你的appid");
        StringBuilder querySB = new StringBuilder();
        for (String key : realQueryList.keySet()) {
            querySB.append(signStringEncoder(key)).append("=").append(signStringEncoder(realQueryList.get(key))).append("&");
        }
        querySB.deleteCharAt(querySB.length() - 1);

        String canonicalStringBuilder = method + "\n" + path + "\n" + querySB + "\n" +
                "host:" + host + "\n" +
                "x-date:" + xDate + "\n" +
                "x-content-sha256:" + xContentSha256 + "\n" +
                "content-type:" + contentType + "\n" +
                "\n" +
                signHeader + "\n" +
                xContentSha256;

        System.out.println(canonicalStringBuilder);

        String hashcanonicalString = hashSHA256(canonicalStringBuilder.getBytes());
        String credentialScope = shortXDate + "/" + region + "/" + service + "/request";
        String signString = "HMAC-SHA256" + "\n" + xDate + "\n" + credentialScope + "\n" + hashcanonicalString;


        byte[] signKey = genSigningSecretKeyV4(sk, shortXDate, region, service);
        String signature = bytesToHex(hmacSHA256(signKey, signString));


        URL url = new URL(schema + "://" + host + path + "?" + querySB);
        System.out.println(url);


        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setRequestProperty("Host", host);
        conn.setRequestProperty("X-Date", xDate);
        conn.setRequestProperty("X-Content-Sha256", xContentSha256);
        conn.setRequestProperty("Content-Type", contentType);
        conn.setRequestProperty("Authorization", "HMAC-SHA256" + " Credential=" + ak + "/" + credentialScope +
                ", SignedHeaders=" + signHeader +
                ", Signature=" + signature);
        if (!Objects.equals(conn.getRequestMethod(), "GET")) {
            conn.setDoOutput(true);
            OutputStream os = conn.getOutputStream();
            os.write(body);
            os.flush();
            os.close();
        }
        conn.connect();

        int responseCode = conn.getResponseCode();

        InputStream is;
        if (responseCode == 200) {
            is = conn.getInputStream();
        } else {
            is = conn.getErrorStream();
        }
        String responseBody = readInputStream(is);
        is.close();
        is.close();

        System.out.println(responseCode);
        System.out.println(responseBody);
        return responseBody;
    }
    // 替换原来的读取输入流的方法
    private String readInputStream(InputStream is) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[16384];
        while ((nRead = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        buffer.flush();
        return new String(buffer.toByteArray(), StandardCharsets.UTF_8);
    }

    private String signStringEncoder(String source) {
        if (source == null) {
            return null;
        }
        StringBuilder buf = new StringBuilder(source.length());
        ByteBuffer bb = UTF_8.encode(source);
        while (bb.hasRemaining()) {
            int b = bb.get() & 255;
            if (URLENCODER.get(b)) {
                buf.append((char) b);
            } else if (b == 32) {
                buf.append("%20");
            } else {
                buf.append("%");
                char hex1 = CONST_ENCODE.charAt(b >> 4);
                char hex2 = CONST_ENCODE.charAt(b & 15);
                buf.append(hex1);
                buf.append(hex2);
            }
        }

        return buf.toString();
    }

    public static String hashSHA256(byte[] content) throws Exception {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            return bytesToHex(md.digest(content));  // 使用自定义的 bytesToHex 方法
        } catch (Exception e) {
            throw new Exception(
                    "Unable to compute hash while signing request: "
                            + e.getMessage(), e);
        }
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    public static byte[] hmacSHA256(byte[] key, String content) throws Exception {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(key, "HmacSHA256"));
            return mac.doFinal(content.getBytes());
        } catch (Exception e) {
            throw new Exception(
                    "Unable to calculate a request signature: "
                            + e.getMessage(), e);
        }
    }

    private byte[] genSigningSecretKeyV4(String secretKey, String date, String region, String service) throws Exception {
        byte[] kDate = hmacSHA256((secretKey).getBytes(), date);
        byte[] kRegion = hmacSHA256(kDate, region);
        byte[] kService = hmacSHA256(kRegion, service);
        return hmacSHA256(kService, "request");
    }
}
package com.rzico.modules.entity;

import java.util.List;

public class GetRoomOnlineUsersResponse {
    private ResponseMetadata responseMetadata;
    private Result result;

    // Getter and Setter methods

    public ResponseMetadata getResponseMetadata() {
        return responseMetadata;
    }

    public void setResponseMetadata(ResponseMetadata responseMetadata) {
        this.responseMetadata = responseMetadata;
    }

    public Result getResult() {
        return result;
    }

    public void setResult(Result result) {
        this.result = result;
    }

}
package com.rzico.modules.entity;

public class ResponseMetadata {
    private String requestId;
    private String action;
    private String version;
    private String service;
    private String region;

    // Getter and Setter methods

    public String getRequestId() {
        return requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getService() {
        return service;
    }

    public void setService(String service) {
        this.service = service;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }
}
package com.rzico.modules.entity;

import java.util.List;

public class Result {
    private boolean roomExists;
    private int totalUser;
    private int totalInvisibleUser;
    private List<String> visibleUserList;
    private List<String> invisibleUserList;

    // Getter and Setter methods

    public boolean isRoomExists() {
        return roomExists;
    }

    public void setRoomExists(boolean roomExists) {
        this.roomExists = roomExists;
    }

    public int getTotalUser() {
        return totalUser;
    }

    public void setTotalUser(int totalUser) {
        this.totalUser = totalUser;
    }

    public int getTotalInvisibleUser() {
        return totalInvisibleUser;
    }

    public void setTotalInvisibleUser(int totalInvisibleUser) {
        this.totalInvisibleUser = totalInvisibleUser;
    }

    public List<String> getVisibleUserList() {
        return visibleUserList;
    }

    public void setVisibleUserList(List<String> visibleUserList) {
        this.visibleUserList = visibleUserList;
    }

    public List<String> getInvisibleUserList() {
        return invisibleUserList;
    }

    public void setInvisibleUserList(List<String> invisibleUserList) {
        this.invisibleUserList = invisibleUserList;
    }
}

Logo

火山引擎视频云技术社区,是面向 AI 音视频开发者的技术交流平台。这里汇聚源自抖音、豆包等亿级 DAU 产品的 RTC、直播、点播、AI 媒体处理、音视频互动技术,提供接入指南、最佳实践、性能调优、场景案例、Demo 代码、开源项目、白皮书和 API 文档。社区汇聚官方工程师与一线开发者,为 AI 视频通话、数字人、AI 视频处理等应用的开发与落地提供技术支持。

更多推荐