V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
guanhui07
V2EX  ›  程序员

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

  •  
  •   guanhui07 · 2023-11-02 19:14:33 +08:00 · 1002 次点击
    这是一个创建于 385 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
    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;
    
    
    cian
        1
    cian  
       2023-11-02 20:18:13 +08:00 via Android
    gptchat
    guanhui07
        2
    guanhui07  
    OP
       2023-11-02 20:43:46 +08:00
    @cian #1 问过了 就我上面粘贴的那个 差不多的 就是生成的 签名和 java nodejs 的就是不一样
    guanhui07
        3
    guanhui07  
    OP
       2023-11-02 20:45:44 +08:00
    ```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
        4
    guanhui07  
    OP
       2023-11-02 20:47:04 +08:00
    @guanhui07 #3 nodejs 写出来了,php 写的不行。。
    flyqie
        5
    flyqie  
       2023-11-02 20:53:13 +08:00 via Android
    @guanhui07 #4

    所以你现在到底是啥问题。。
    sujin190
        6
    sujin190  
       2023-11-02 21:08:40 +08:00 via Android   ❤️ 1
    php 的 bode 为啥要 json_encode ,这肯定不一样了啊
    dw2693734d
        7
    dw2693734d  
       2023-11-02 21:12:26 +08:00
    我被你说晕了,你到底想干啥
    dw2693734d
        8
    dw2693734d  
       2023-11-02 21:15:15 +08:00   ❤️ 1
    json_encode($body) 这里错了
    sl0000
        9
    sl0000  
       2023-11-02 22:29:01 +08:00
    hmac 一般要做一个 key 排序
    guanhui07
        10
    guanhui07  
    OP
       2023-11-03 09:34:16 +08:00
    @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
        11
    guanhui07  
    OP
       2023-11-03 09:54:59 +08:00
    在某位大佬指点下解决了
    sujin190
        12
    sujin190  
       2023-11-03 11:51:33 +08:00   ❤️ 1
    @guanhui07 #10 php 单引号\n 是不表示转义吧,所有就是单纯的两个字符\和 n ,所以和 java 不一样了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1551 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 17:02 · PVG 01:02 · LAX 09:02 · JFK 12:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.