研发必备:轻松玩转开放接口API签名和验签

一、简介

开放接口API的签名和验签是一种常见的安全机制,用于确保接口请求的完整性和真实性。

1.1、对称加密和非对称加密

 对称加密:加密和解密使用的是同一把密钥。常用的对称加密算法:DES,AES,3DES。

非对称加密:加密和解密使用的是不同的密钥,一把作为公开分享给加密方的叫做公钥,另一把不分享作为解密的私钥。公钥加密的密文只有私钥能进行解密;私钥加密的密文也只有公钥能进行解密。常见的非对称加密算法:RSA,ECC。

总之:在效率上来说,对称加密的效率显然更高,但是非对称加密的安全性更高。所以一般在实际的HTTPS加密过程中,首次连接使用的是公钥加密算法(非对称加密)来传输数据加密所要使用的对称加密的密钥,之后传输中使用的都是对称加密算法。

1.2、生成非对称秘钥对

第三方系统作为调用方(客户端),与接口服务方(服务端)约定好加密算法和客户端名称(clientID),便于在服务方系统中来唯一标识调用方系统。约定好以后,服务方为每一个调用方系统专门生成一个专属的非对称密钥对(RSA密钥对)。私钥颁发给调用方系统(客户端),公钥由服务方持有。

图片

注意:调用方(客户端)系统需要保管好私钥(存到调用方系统的后端)。因为对于服务方系统而言,调用方系统是消息的发送方,其持有的私钥唯一标识了它的身份是服务方系统受信任的调用方。调用方系统的私钥一旦泄露,调用方对原系统毫无信任可言。

1.3 开放接口API

不需要登录凭证就允许被第三方系统调用的接口,必须要考虑接口数据的安全性问题。比如:数据是否被篡改?数据是否已过时?数据是否可以重复提交?等问题。为了防止开放接口被恶意调用,开放接口一般都需要验签才能被调用。

 1.4、 签名和验签

签名:是第三方系统在调用接口API前,需按照接口API提供方的规则根据所有请求参数生成一个签名(字符串),在调用接口时携带该签名的。

特别注意:为了确保生成签名的处理细节与服务方系统的验签逻辑是匹配的,服务方系统一般都提供jar包或者代码片段给调用方来生成签名,否则可能会因为一些处理细节不一致导致生成的签名是无效的

 验签:接口提供方会验证签名的有效性,只有签名验证有效才能正常调用接口,否则请求会被驳回。

图片

二、应用案例

图片

核心代码:

/**
 * @Description: TODO:使用RSA完成签名验签
 * @Author: yyalin
 * @CreateDate: 2023/3/28 14:37
 * @Version: V1.0
 */
@Slf4j
public class RSAUtils {
    public static final String SIGNATURE_INSTANCE = "SHA256withRSA";  //签名
    public static final String KEYPAIR_INSTANCE = "RSA";  //秘钥类型
    /**
     * 功能描述:RSA公私钥生成器
     * @MethodName: genKey
     * @MethodParam: []
     * @Return: Map
     * @Author: yyalin
     * @CreateDate: 2023/12/18 15:34
     */
    public static Map genKey() throws Exception{
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEYPAIR_INSTANCE);
        kpg.initialize(1024);
        KeyPair kep = kpg.generateKeyPair();
        PrivateKey pkey = kep.getPrivate();
        PublicKey pubkey = kep.getPublic();
        Map<String,Object> param=new HashMap<String,Object>();
        param.put("publicKey", new String(Base64Utils.encode(pubkey.getEncoded())));
        param.put("privateKey", new String(Base64Utils.encode(pkey.getEncoded())));
        return param;
    }
    /**
     * 功能描述:RSA签名
     * @MethodName: sign
     * @MethodParam: [content:需要签名的字符串, privateKey:RSA私钥]
     * @Return: java.lang.String
     * @Author: yyalin
     * @CreateDate: 2023/12/18 16:10
     */
    public static String sign(String content, String privateKey) throws Exception {
        byte[] str= Base64Utils.decode(privateKey.getBytes("UTF-8"));
        PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(str);
        KeyFactory keyf = KeyFactory.getInstance(KEYPAIR_INSTANCE);
        PrivateKey priKey = keyf.generatePrivate(priPKCS8);
        java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_INSTANCE);
        signature.initSign(priKey);
        signature.update(content.getBytes("UTF-8"));
        byte[] signed = signature.sign();
        return new String(Base64Utils.encode(signed),"UTF-8");
    }
    /**
     * 功能描述:RSA验签
     * @MethodName: verify
     * @MethodParam: [content:原文内容, sign:待验证的签名, public_key:RSA公钥]
     * @Return: boolean 签名结果
     * @Author: yyalin
     * @CreateDate: 2023/12/18 16:11
     */
    public static boolean verify(String content, String sign, String public_key)
            throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(KEYPAIR_INSTANCE);
        byte[] encodedKey = Base64Utils.decode(public_key.getBytes("UTF-8"));
        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
        java.security.Signature signature = java.security.Signature.getInstance(SIGNATURE_INSTANCE);
        signature.initVerify(pubKey);
        signature.update(content.getBytes("UTF-8"));
        boolean bverify = signature.verify(Base64Utils.decode(sign.getBytes("UTF-8")));
        return bverify;
    }
}

测试内容:

//测试使用
    public static void main(String[] args) throws Exception {
        //1、获取公私钥匙 请求方获取公钥私钥后,传私钥发送请求
        Map<String,Object> param=RSAUtils.genKey();
        log.info("输出的公钥私钥param:"+param);
        String publicKey= (String) param.get("publicKey");
        String privateKey= (String) param.get("privateKey");
        //2、签名 获取私钥,获取请求后对内容进行加标签返回
        String cnotallow="您好!";
        String sign=RSAUtils.sign(content, privateKey);
        log.info("使用私钥输出的标签sign:"+sign);
        //3、验签
//        String cnotallow="您好!";
        boolean verify=RSAUtils.verify(content, sign,  publicKey);
        log.info("使用公钥验签结果verify:"+verify);


    }

测试结果:

图片

请求体内容被篡改了:

图片

图片

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/128244.html<

(0)
运维的头像运维
上一篇2025-02-25 01:34
下一篇 2025-02-25 01:35

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注