这段 Java 加密算法 HmacSHA1 怎么写成 PHP 的?

193 天前
 guanhui07

import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;

public class SignTest {

  public static void main(String[] args) {
    // 应用 ID
    String appId = "";
    // 应用 secret
    String appSecret = "";
    // 请求时间戳(发送请求的时间戳)
    String timestamp = "";
    // 随机字符串 (自定义随机字符串)
    String nonce = "";
    // 请求 body (请求 body , 需保证发送方与接收方的数据一致,建议在拦截器里做对应认证)
    String body = "";

    // 签名串
    String signContent = String.format("%s\n%s\n%s\n%s\n", appId, timestamp, nonce, body);
    // 签名值
    HMac hMac = new HMac(HmacAlgorithm.HmacSHA1, appSecret.getBytes());
    String signature = hMac.digestHex(signContent);
    System.out.println(signature);
  }

}
$sudAppId = '1719669845797171201';
$sudTimestamp = '1698912908000';
$sudNonce = 'lFM9MKckbGYiZAQG';
$body = '{"platform":2}';
$signContent = $sudAppId . '\n' . $sudTimestamp . '\n'
    . $sudNonce . '\n' . json_encode($body) .'\n';

$appSecret = 'test';
$signatureString = $signContent;
$sign = hash_hmac('sha1', $signatureString, $appSecret,false);
echo $sign;

880 次点击
所在节点    程序员
12 条回复
cian
193 天前
gptchat
guanhui07
193 天前
@cian #1 问过了 就我上面粘贴的那个 差不多的 就是生成的 签名和 java nodejs 的就是不一样
guanhui07
193 天前
```nodejs

const Crypto = require('crypto');

function signTest() {
let appId = '1719669845797171201';
let appSecret = 'test';
let timestamp = '1698912908000';
let nonce = 'lFM9MKckbGYiZAQG';
let body = '{"platform":2}';
let signContent = appId + '\n' + timestamp + '\n' + nonce + '\n' + body + '\n';
let hmac = Crypto.createHmac('sha1', appSecret);
let signature = hmac.update(signContent).digest('hex');
console.log(signature);
}
````

php 写出来了 结果 和 java 一样
guanhui07
193 天前
@guanhui07 #3 nodejs 写出来了,php 写的不行。。
flyqie
193 天前
@guanhui07 #4

所以你现在到底是啥问题。。
sujin190
193 天前
php 的 bode 为啥要 json_encode ,这肯定不一样了啊
dw2693734d
193 天前
我被你说晕了,你到底想干啥
dw2693734d
193 天前
json_encode($body) 这里错了
sl0000
193 天前
hmac 一般要做一个 key 排序
guanhui07
192 天前
@sujin190 #6 我的小例子 写错了

```php
<?php
$sudAppId = '1719669845797171201';
$sudTimestamp = '1698912908000';
$sudNonce = 'lFM9MKckbGYiZAQG';
$body = '{"platform":2}';
$signContent = $sudAppId . '\n' . $sudTimestamp . '\n'
. $sudNonce . '\n' . $body .'\n';

$appSecret = 'test';
$sign = hash_hmac('sha1', $signContent, $appSecret,false);
echo $sign;
```

这种也不行 , 试了下 sign 出来 和 java node golang 的 不一致


```golang

package main

import (
"crypto/hmac"
"crypto/sha1"
"fmt"
)

func main() {
// 应用 ID
var appId = "1719669845797171201"
// 应用 secret
var appSecret = "test"
// 请求时间戳(发送请求的时间戳)
var timestamp = "1698912908000"
// 随机字符串 (自定义随机字符串)
var nonce = "lFM9MKckbGYiZAQG"
// 请求 body (请求 body , 需保证发送方与接收方的数据一致,建议在拦截器里做对应认证)
var body = "{\"platform\":2}"

// 签名串
signContent := fmt.Sprintf("%s\n%s\n%s\n%s\n", appId, timestamp, nonce, body)
// 签名值
mac := hmac.New(sha1.New, []byte(appSecret))
mac.Write([]byte(signContent))
signature := mac.Sum(nil)
//t.Logf("signature:%x", signature)
test, _ := fmt.Printf("signature:%x", signature)
fmt.Println(test)
}



```

golang 的可以
guanhui07
192 天前
在某位大佬指点下解决了
sujin190
192 天前
@guanhui07 #10 php 单引号\n 是不表示转义吧,所有就是单纯的两个字符\和 n ,所以和 java 不一样了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/987990

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX