http请求中简单的签名验证

安装

安装包文件

composer require "entere/sign:v1.0.0"

使用

php 实例:

<?php
require_once("./src/Sign.php");

use Entere\Sign\Sign;

$params = [
    'access_key'=>'7576762362',
    'timestamp'=>'1439279383630',
    'screen_name'=>'entere',
    'format'=>'json'
];
$secret = 'f827182b1051075e601c73ac1ae329fa';
$result = Sign::generateSign($params,$secret);
return $result;

?>

Laravel5 实例:

<?php 

namespace App\Http\Controllers;

use Entere\Sign\Sign;

class WelcomeController extends Controller {
    
    public function index()
    {
        $params = [
            'access_key'=>'7576762362',
            'timestamp'=>'1439279383630',
            'screen_name'=>'entere',
            'format'=>'json'
        ];
        $secret = 'f827182b1051075e601c73ac1ae329fa';
        $result = Sign::generateSign($params,$secret);
        return $result;

    }
}

?>

说明

客户端与服务端的数据交互,大部分应用都采用的 RESTful API 的方式,那么如何确保 API 接口的安全性呢?URL 签名的方式可以确保请求的过程中参数不被修改。

签名的机制是由开发者在 API 客户端计算出系列参数组合的哈希值,将产生的信息添加到 URL 请求的 sign 参数。

例如 API 请求参数如下:

{
    "access_key":"7576762362",
    "timestamp":"1439279383630",
    "screen_name":"entere",
    "format":"json"
}

1、按参数名进行升序排列

access_key, timestamp, screen_name, format 其中不包括空值参数

排序后的参数为:

{
    "access_key":"7576762362",
    "format":"json",
    "screen_name":"entere",
    "timestamp":"1438279283630",
    
}

2、构造签名串

以secret字符串开头,追加排序后参数名称和值,格式:

secretkey1value1key2value2...

假设 secret的值为 f827182b1051075e601c73ac1ae329fa 应用到上述示例得到签名串为:

f827182b1051075e601c73ac1ae329faaccess_key7576762362formatjsonscreen_nameenteretimestamp1438279283630

3、计算签名

对上面的签名串进行 md5 签名:

md5(f827182b1051075e601c73ac1ae329faaccess_key7576762362formatjsonscreen_nameenteretimestamp1438279283630)

并把值转成小写:

927c0fc11caaf98840ed7773b348685c

4、添加签名

将计算的签名值以 sign 参数名,附加到 URL 请求中。一个典型的 API 请求如下所示

https://xxx.com/xxx?access_key=7576762362&format=json&screen_name=entere&timestamp=1438279283630&sign=927c0fc11caaf98840ed7773b348685c

5、服务器验证

验证请求者的身份:简单判断 access_key。

防止重放攻击:服务器端首先验证时间戳 timestamp 是否有效,比如是服务器时间戳 5 分钟之前的请求视为无效。

保护传输中的数据:服务端收到请求时,将基于相同签名方法(去掉 sign 参数)重新计算哈希,并将其与请求中包括的哈希值进行匹配。如果哈希值不匹配,服务器将返回 401(未授权被拒绝)错误码。

License

MIT

在 Java 进行 HTTP 请求时,可以使用 HttpsURLConnection 来发送 HTTPS 请求。如果目标服务器使用自签名证书或者其他不受信任的证书,可能会遇到证书验证失败的问题。为了跳过证书验证,可以通过设置 SSLContext 来实现。 以下是一个示例代码: ```java import javax.net.ssl.*; import java.io.*; import java.net.*; public class HttpsClient { public static void main(String[] args) throws Exception { // 创建 SSLContext SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{new TrustAllManager()}, null); // 设置默认的 SSLSocketFactory 和 HostnameVerifier HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); // 创建 URLConnection URL url = new URL("https://example.com"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); // 发送请求 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } in.close(); } private static class TrustAllManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } } ``` 在上面的代码,我们创建了一个 TrustAllManager 类,它实现了 X509TrustManager 接口,用于跳过证书验证。我们还创建了一个 SSLContext,并将其设置为默认的 SSLSocketFactory 和 HostnameVerifier。这样,所有的 HTTPS 请求都会使用我们自己的 SSLContext 来进行验证。 需要注意的是,跳过证书验证可能会带来安全风险。在实际应用,应该谨慎考虑是否需要跳过证书验证
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值