请问如何使用PHP 实现以下JAVA代码中的签名算法

如何通过PHP实现 JAVA代码如下

请问如何使用PHP 实现以下JAVA代码中的签名算法

package com.example.helloworld.apps;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class SignatureVerifyController {

    private static final String SECRET_KEY = "V87ACv859dWMOUZKM/AoXSZaikAG4Etqq7mMF4A1yTYUlvJRZznA3UomC92lV7vyN0WKJdiczpHnxCwo6Gtijw==";

    private static final String APP_KEY = "1ba7d192-ecdf-414a-bb68-c106850852aa";
//    private static final String policyId = "20210c73-cf9f-4651-b50b-dce6a39058a3";
//    private static final String name = "“特提斯地球动力系统”重大研究计划";
//    private static final String categoryName = "科研立项,重大项目";
//    private static final String applyCondition = "一、研究方向\n" +
//            "本计划2021年度拟资助以下研究方向:\n" +
//            "(一)重点支持项目。\n" +
//            "1.特提斯演化过程中的古环境效应与生物演化。\n" +
//            "主要研究特提斯洋及其周边大陆裂解与汇聚而引发的重大生物与环境事件,分别聚焦于早古生代和晚古生代末两个时间段,着重研究这些重大生物与环境事件之间的联系,以及它们发生的古地理环境、地球深部制约和发生的具体机制。本方向拟重点资助项目2项。\n" +
//            "2.特提斯构造域大陆裂解-聚合动力学。\n" +
//            "通过地球动力学模拟方法,定性识别和定量计算海底扩张、俯冲板片拖拽、地幔上涌等在特提斯大陆裂解-聚会过程中的各自贡献,推动板块构造源动力争议问题的研究。本方向拟重点资助项目1项。\n" +
//            "(二)集成项目。\n" +
//            "1.特提斯演化过程中特征性岩浆-变质作用及其动力学指示。\n" +
//            "特提斯构造域不仅出露不同热梯度下形成的变质岩,而且发育不同时代大陆裂解和大洋俯冲形成的岩浆岩。古大洋俯冲带受到大陆碰撞及碰撞后过程的叠加改造,结果变质作用和岩浆作用呈现出显著的时空不均一性。本集成项目将综合研究这些不同时代不同类型的变质岩和岩浆岩,厘定它们的形成和演化与超大陆裂解/汇聚之间的关系,为特提斯地球动力学总结提供系统证据和约束。\n" +
//            "2.特提斯构造域深部结构及动力学指示。\n" +
//            "综合特提斯构造域地球物理深部探测资料,构建特提斯构造域统一地壳及全地幔物性结构参考模型,及洋陆俯冲-碰撞转换带等关键地区的高分辨率地壳和上地幔物性结构模型,并基于深部物性结构模型开展地球动力数值模拟研究,探索特提斯构造域动力学演化过程及其对板块构造理论的指示意义。\n" +
//            "3.特提斯演化过程中的优势及特色矿产资源。\n" +
//            "特提斯在单向裂解汇聚的演化过程中形成了多种独具特色的资源,如铜、金、铅锌、铬铁矿以及新近发现的锂铍等稀有金属。不过,为何古/新特提斯洋有相似的构造演化历史,但矿化类型却明显不同?为何新特提斯洋经历了漫长的俯冲过程,却鲜有俯冲阶段的成矿记录?特提斯在单向裂解汇聚过程中对于成矿作用,有何种深层次的控制作用?目前都尚未得到较好的理解。本项目通过梳理不同类型的矿产资源,试图回答特提斯演化过程中的资源效应。\n" +
//            "二、申报要求\n" +
//            "(一)申请条件。\n" +
//            "本重大研究计划项目申请人应当具备以下条件:\n" +
//            "1. 具有承担基础研究课题的经历;\n" +
//            "2. 具有高级专业技术职务(职称)。\n" +
//            "在站博士后研究人员、正在攻读研究生学位以及无工作单位或者所在单位不是依托单位的人员不得作为申请人进行申请。\n" +
//            "(二)限项申请规定。\n" +
//            "执行《2021年度国家自然科学基金项目指南》“申请规定”中限项申请规定的相关要求。";
//    private static final String support = "2021度拟资助重点支持项目3项,资助期限为4年,直接费用资助强度约为330万元/项,优先支持围绕特提斯地球动力系统已有较好工作基础、有望在特提斯地球动力系统研究方面取得重要突破的项目申请,重点支持项目申请书中研究期限应填写“2022年1月1日-2025年12月31日”;拟资助集成项目3项,资助期限为4年,直接费用资助强度约为500万元/项,优先支持已有扎实工作基础且较好掌握特提斯构造域构造沉积古地理领域资料的项目申请,集成项目申请书中研究期限应填写“2022年1月1日-2025年12月31日”。";
//    private static final String applyMaterials = "本重大研究计划项目实行无纸化申请。\n" +
//            "(1)申请人应当按照科学基金网络信息系统中重大研究计划项目的填报说明与撰写提纲要求在线填写和提交电子申请书及附件材料。\n" +
//            "(2)本重大研究计划旨在紧密围绕核心科学问题,将对多学科相关研究进行战略性的方向引导和优势整合,成为一个项目集群。申请人应根据本重大研究计划拟解决的具体科学问题和项目指南公布的拟资助研究方向,自行拟定项目名称、科学目标、研究内容、技术路线和相应的研究经费等。\n" +
//            "(3)申请书中的资助类别选择“重大研究计划”,亚类说明选择“集成项目”或“重点支持项目”,附注说明选择“特提斯地球动力系统”,根据申请的具体研究内容选择相应的申请代码。\n" +
//            "集成项目的合作研究单位不得超过4个,重点支持项目的合作研究单位不得超过2个。\n" +
//            "(4)申请人在申请书“立项依据与研究内容”部分,应当首先明确说明申请符合本项目指南中的重点资助研究方向,以及对解决本重大研究计划核心科学问题、实现本重大研究计划科学目标的贡献。\n" +
//            "如果申请人已经承担与本重大研究计划相关的其他科技计划项目,应当在申请书正文的“研究基础与工作条件”部分论述申请项目与其他相关项目的区别与联系。";
//    private static final String source = "关于发布特提斯地球动力系统重大研究计划2021年度项目指南的通告\n" +
//            "http://www.nsfc.gov.cn/publish/portal0/tab442/info80005.htm";
//    private static final String startDate = "2021-04-12";
//    private static final String endDate = "2021-04-16";
//    private static final String enterpriseList = "500201488,500200951";
    public static void main(String[] args) {
        Map<String, String> params = new HashMap<>();
        params.put("appKey", APP_KEY);
//        params.put("policyId", policyId);
//        params.put("name", name);
//        params.put("categoryName", categoryName);
//        params.put("applyCondition", applyCondition);
//        params.put("support", support);
//        params.put("applyMaterials", applyMaterials);
//        params.put("source", source);
//        params.put("startDate", startDate);
//        params.put("endDate", endDate);
//        params.put("enterpriseList", enterpriseList);

//        System.out.println(params);
        // params.put("value", "value");
        // 9ySMIhL-pvdvs6fRiOl8I2Iw4Po
        System.out.println(computeSignatureUrlSafe(params, SECRET_KEY));
    }
    public static String computeSignatureUrlSafe(Map<String, String> params, String secretKey) {
        try {
            byte[] encryptedBytes = getEncryptedBytes(params, secretKey);
            return Base64.encodeBase64URLSafeString(encryptedBytes);
        } catch (InvalidKeyException var3) {
            throw new InvalidParameterException("Invalid secretKey for signing");
        } catch (NoSuchAlgorithmException var4) {
            throw new RuntimeException("NoSuchAlgorithmException for HmacSHA1", var4);
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("UnsupportedEncodingException for UTF-8", var5);
        }
    }
    private static byte[] getEncryptedBytes(Map<String, String> params, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        Mac mac = Mac.getInstance("HmacSHA1");
        byte[] rawKey = Base64.decodeBase64(secretKey);
        SecretKeySpec keySpec = new SecretKeySpec(rawKey, "HmacSHA1");
        mac.init(keySpec);
        List<String> keyList = new ArrayList();
        CollectionUtils.addAll(keyList, params.keySet().iterator());
        Collections.sort(keyList);
        Iterator var6 = keyList.iterator();
        while(var6.hasNext()) {
            String key = (String)var6.next();
            mac.update(key.getBytes("UTF-8"));
            String val = (String)params.get(key);
            if (val != null && !val.isEmpty()) {
                mac.update(val.getBytes("UTF-8"));
            }
        }
        return mac.doFinal();
    }
}
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

数组按字母sort排序,HmacSHA1签名,该说是这样,utf-8编码,最后返回用base64编码下,安全的base64编码,该说就是去掉生成后面加的=符号。基本就是这样吧

2年前 评论
deatil (作者) 2年前
kai_wang (楼主) 2年前
讨论数量: 3

没有相关文档吗?一般是由对方提供生成签名过程的说明文档,或者根据例子来一步步实现

2年前 评论
kai_wang (楼主) 2年前

数组按字母sort排序,HmacSHA1签名,该说是这样,utf-8编码,最后返回用base64编码下,安全的base64编码,该说就是去掉生成后面加的=符号。基本就是这样吧

2年前 评论
deatil (作者) 2年前
kai_wang (楼主) 2年前

我也对接了不少java接口,加解密都是用php弄得,都要不了几行代码

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!