kong笔记——使用hmac auth

kong笔记——目录导航

前言

通常所说的保证接口安全究竟是在说什么?首先没有绝对的安全,对于反编译逆向工程这里不做讨论。我们要解决的问题是,确保后端接口收到的请求是由我们自己的APP所发出, 中间传输过程中内容不能被篡改,不能有同行通过抓包分析接口的请求报文然后随意调用。 那么这个hmac认证能解决上述问题吗?https可以解决上述问题吗?https只能保证数据不被篡改,但是信源无法保证。 http协议是明文的文本协议,https会对数据包进行加密,但是https请求仍然可以被抓包,并解密其中的内容,只需要伪造一个自签名的根证书, 所有的抓包工具如果需要抓https请求必然要在手机安装一个证书。所以单纯的https并不能保证接口不暴露。 当使用hmac加密签名时,只要secret不泄露,该请求就不会被伪造,也就是即使知道接口地址和参数,但是也无法传递正确的参数,只能是一直在复用由app发出的请求参数, 并且由于hmac协议中clock skew配置,这些参数也不能一直复用下去。

hmac简述

hmac是Hashing for Message Authentication的简写,可以用来保证数据的完整,客户端把内容通过散列/哈希算法算出一个摘要,并把算法和内容以及摘要传送给服务端,服务端按照这个算法也算一遍,和摘要比一下如果一样就认为内容是完整的,如果不一样就认为内容被篡改了。

HMAC是一种利用密码学中的散列函数来进行消息认证的一种机制,所能提供的消息认证包括两方面内容:

①消息完整性认证:能够证明消息内容在传送过程没有被修改。

②信源身份认证:因为通信双方共享了认证的密钥,接收方能够认证发送该数据的信源与所宣称的一致,即能够可靠地确认接收的消息与发送的一致。

HMAC是当前许多安全协议所选用的提供认证服务的方式,应用十分广泛,并且经受住了多种形式攻击的考验。

HMAC与一般的加密重要的区别在于它具有“瞬时"性,即认证只在当时有效,而加密算法被破解后,以前的加密结果就可能被解密。

关于Kong的hmac说几点
  • Clock Skew
    使用Kong的hmac后,请求必须带有Date和x-date请求头,这个是防止重放攻击(Replay Attacks),默认的情况下,客户端传过来的时间和服务端的时间相差300s,Kong就认为这个请求是有问题的。这个值可以修改的,通过修改config.clock_skew的参数
  • Headers的完整性
    使用Kong的hmac来确保请求头的完整性。具体要确保那个头,这个也是可以配置的,下面会演示。官方推荐,最差应该是 request-line, host, and date这三个头,最好是全部的头。
  • Body的完整性
  • 使用Kong的hmac可以确保请求内容的完整性,下面会演示
确保请求头的完整性
  • 基础环境准备
    你要有一个正常的route和service,如果没有的话,可以参考https://blog.csdn.net/u014686399/article/details/100084613,我的试验也是基于这个博客的

  • 针对服务启用插件

/services/2fc52878-1fe9-48ba-bc45-146da3822851/plugins
{
	"name":"hmac-auth",
	"config": {
		"enforce_headers": ["testhamc"],
		"algorithms": ["hmac-sha1", "hmac-sha256"]
	}
}
  • 2fc52878-1fe9-48ba-bc45-146da3822851这个是服务的id,当然你可以针对route启用插件
  • hmac-auth这个是固定值, 插件的名字
  • config.enforce_headers这是指定你要校验的头,我这里用了一个testhamc,如果你是生产环境还是遵循一下官网的建议吧
  • 创建一个consumer
consumers/ POST
{
	"username":"xjj_user_01",
	"custom_id":"users_001"
}
  • 创建证书
/consumers/f4c713c0-6bf1-4079-83a0-135180d6ba53/hmac-auth  POST
{
	"username":"rita",
	"secret":"123.com"
}
  • f4c713c0-6bf1-4079-83a0-135180d6ba53这个是consumer的id
  • secret是用来做算法的key的,算法一般会用sha256或者sha1
  • 测试
    • 直接访问
      在这里插入图片描述
      可以看到直接访问不了了
    • 添加Authorization头
#  首先确定一下testhamc头,因为这是我自定义的头,所以值我就自定义为123456
#  做签名,我是通过java实现的

```text
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>
public static String sign(String secret, String message) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            mac.init(secretKey);
            return Base64.encodeBase64String(mac.doFinal(message.getBytes()));
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new IllegalArgumentException("签名错误:" + e.getMessage());
        }
    }
public static void main(String[] args) {
        String secret = "123.com";
        String message = "testhamc: 123456";
        String sign = sign(secret, message);
        System.out.println(sign);//cnKy69DPkd1rycOvz5biWTJ6rk/UObLAXrNzEOCF4TE=
    }

再次访问

curl -i -X GET http://172.16.0.92:31545/xjj_tv/main \
      -H "testhamc: 123456" \
      -H 'Authorization: hmac  username="rita", algorithm="hmac-sha256", headers="testhamc", signature="cnKy69DPkd1rycOvz5biWTJ6rk/UObLAXrNzEOCF4TE="'
  • username是证书的用户名
    在这里插入图片描述
    会提示我们添加一个DATE的头
  • 添加后再访问

    java版本获取时间

	/**
     * 获取当前GMT format 时间
     *
     * @return
     */
    public static String getGMTTime() {
        DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return dateFormat.format(Calendar.getInstance().getTime());
    }
curl -i -X GET http://172.16.0.92:31545/xjj_tv/main \
      -H "Date: Web, 28 Aug 2019 09:09:00 GMT" \
      -H "testhamc: 123456" \
      -H 'Authorization: hmac  username="rita", algorithm="hmac-sha256", headers="testhamc", signature="cnKy69DPkd1rycOvz5biWTJ6rk/UObLAXrNzEOCF4TE="'
  • DATE是 GMT格式的,和服务器上不能相差300秒
    在这里插入图片描述
    访问通过了
确保body的完整性

需要在kong的hmac插件上,打开validate request body = true的开关!!!!!

body数据签名验证需要增加另一个header:Digest,value为:Digest: SHA-256=base64(sha256()),例如:SHA-256=RgecWaKvMqh5T79Ps93OuyZ5CZuPnZ6dTgsh5i9xJUs=
注意有个前缀:SHA-256=!!!

  • 确定一个body
body肯定是事先确定的,我这里定的内容是 {“appkey”:"123"}
  • 制作body的签名,我是通过java实现的
public static String String2SHA256(String str) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] hash = messageDigest.digest(str.getBytes());
            return Base64.encodeBase64String(hash);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("签名错误:" + e.getMessage());
        }
    }
public static void main(String[] args) {
        Map<String, String> map = new HashMap<>(1);
        map.put("appkey", "123");
        String body = JSON.toJSONString(map);
        System.out.println(String2SHA256(body));//YKnEib/1qa6/suFFavmKF296fLlZ9sDJDv+zUGQM7q0=
    }
  • 测试
curl -i -X GET http://172.16.0.92:31545/xjj_tv/main   \
-H "Date: Web, 28 Aug 2019 10:20:00 GMT"  \
 -H "testhamc: 123456"   \     
 -H 'Authorization: hmac  username="rita", algorithm="hmac-sha256", headers="testhamc", signature="cnKy69DPkd1rycOvz5biWTJ6rk/UObLAXrNzEOCF4TE="'  \
 -H "Digest: SHA-256=l12ueyMM3AyCTH8uE9Cs3PVF1ZGR29rhi1l+SsuJzEI="  \
  -d '{"appkey":"123"}'

在这里插入图片描述测试通过

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言可以使用HMAC-SHA256算法对数据进行身份验证和完整性校验。HMAC是一种对称密钥算法,SHA256是一种哈希算法。 首先,我们需要引入相关的头文件。在C语言中,可以使用``<openssl/hmac.h>``头文件来包含HMAC相关的函数和结构体。 接下来,我们需要定义一个密钥,该密钥用于计算HMAC值。我们可以将密钥存储在一个字符数组中,例如``unsigned char key[] = "密钥";``。请注意,密钥的长度通常应为64字节,并采用随机值或者使用密码学安全伪随机数生成器生成。 然后,我们需要定义要计算HMAC-SHA256的数据。可以将待计算的数据存储在一个字符数组中,例如``unsigned char data[] = "待计算的数据";``。 接下来,我们需要使用``HMAC()``函数来计算HMAC-SHA256值。``HMAC()``函数接受五个参数:哈希算法类型、密钥、密钥长度、数据以及数据长度。我们可以使用``EVP_sha256()``选择SHA256算法。 然后,我们需要定义一个字符数组来存储计算得到的HMAC值。可以使用``unsigned char result[EVP_MAX_MD_SIZE]``来存储HMAC值,并指定最大大小。 最后,我们可以使用``HMAC()``函数来计算HMAC值。这个函数会将最终结果存储在``result``数组中,并返回结果的长度。我们可以将HMAC结果存储在字符数组中,例如``unsigned char hmacResult[SHA256_DIGEST_LENGTH]``。 整个过程如下所示: ```c #include <openssl/hmac.h> int main() { unsigned char key[] = "密钥"; unsigned char data[] = "待计算的数据"; unsigned char hmacResult[SHA256_DIGEST_LENGTH]; unsigned int hmacLength; HMAC(EVP_sha256(), key, strlen(key), data, strlen(data), hmacResult, &hmacLength); // 打印计算得到的HMAC结果 for (int i = 0; i < hmacLength; i++) { printf("%02x", hmacResult[i]); } return 0; } ``` 通过以上步骤,我们可以使用C语言计算出数据的HMAC-SHA256值。这种方法可以用于身份验证、完整性校验等安全领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值