找回密码
 加入
搜索
查看: 396|回复: 13

[系统综合] [已解决]如何实现MD5输出的不是16进制字符串,而是二进制字符串?

[复制链接]
发表于 2023-9-5 17:31:49 | 显示全部楼层 |阅读模式
本帖最后由 风过无痕 于 2023-9-6 23:03 编辑

不用AU3了,用C#加密了。

经过几天多次的测试,发现AU3的MD5都是16进制输出的字符串,不能输出二进制的字符串,所以使用AU3加密API报文的时候就会报错。因为输出MD5不对。
  • php md5加密函数参考详解

语法:md5(string,raw)

md5() 函数计算字符串的 MD5 散列

string必需,规定要计算的字符串

raw可选,规定十六进制或二进制输出格式.

TRUE - 原始 16 字符二进制格式

FALSE - 默认,32 字符十六进制数

比如 base64_encode(md5($content.$secret, true))
python里面也是这样,也可以控制MD5的输出,所以都能输出正确的结果
hash.digest()
返回摘要,作为二进制数据字符串值
hash.hexdigest()
返回摘要,作为十六进制数据字符串值
n=hashlib.md5((content+secretKey).encode('utf-8')).digest()
a = base64.b64encode(n)
data_digest = a.decode('utf-8')
print(data_digest)
下面这个用python和PHP都能得到正确的base64字符串

$content = '{"waybillNo":"6606002282568"}'
$secretkey = '123abc'
结果:N8jrMrujxlovfcE5BEF46Q==

以下是PHPMD5加密的结果

<?php
$content='{"waybillNo":"6606002282568"}';
$secret='123abc';
print(md5($content.$secret, true))
?>
MD5加密第二个参数设置为 true,结果如下

上面的这个结果也不一定对,但是php的md5加密就是这个结果。
如果将php的MD5加密第二参数设置为false,结果如下:
37c8eb32bba3c65a2f7dc139044178e9
这个结果使用AU3的MD5函数也可以得出
37c8eb32bba3c65a2f7dc139044178e9

不知道用AU3如何得出和上面php参数为true时的结果?

临时解决方案:
调用C#进行加密签名
将content内容填写到D:\content.txt内
将secretkey内容填写到D:secretkey.txt内
执行D:\cryptdata.exe 后会自动在D盘根目录下生成一个newCrypt.txt文件,里面就是加密的签名内容,与官方签名结果相同



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2023-9-5 18:59:40 | 显示全部楼层
先转换成二进制,传输过后再转回来是否可行???
 楼主| 发表于 2023-9-5 21:12:03 | 显示全部楼层
邪恶海盗 发表于 2023-9-5 18:59
先转换成二进制,传输过后再转回来是否可行???

不行,试过了,不知道其他语言处理的过程是什么样的
发表于 2023-9-5 21:28:34 | 显示全部楼层
风过无痕 发表于 2023-9-5 21:12
不行,试过了,不知道其他语言处理的过程是什么样的

举个栗子啊,不然谁知道到底是你一个人的问题还是普遍问题..
 楼主| 发表于 2023-9-5 21:47:05 | 显示全部楼层
邪恶海盗 发表于 2023-9-5 21:28
举个栗子啊,不然谁知道到底是你一个人的问题还是普遍问题..

应该是普遍的共性问题
发表于 2023-9-5 21:54:03 | 显示全部楼层
风过无痕 发表于 2023-9-5 21:47
应该是普遍的共性问题

人最大的弱点就是认识不到自己的错误,这是人本身的劣根性...
 楼主| 发表于 2023-9-6 08:23:35 | 显示全部楼层
邪恶海盗 发表于 2023-9-5 21:54
人最大的弱点就是认识不到自己的错误,这是人本身的劣根性...

一边呆着去吧,无意义的回复就不要刷了
发表于 2023-9-6 11:29:29 | 显示全部楼层
binarytostring
发表于 2023-9-6 15:52:42 | 显示全部楼层
上接口,我用au3试试
 楼主| 发表于 2023-9-6 17:07:17 | 显示全部楼层
本帖最后由 风过无痕 于 2023-9-6 21:41 编辑
haijie1223 发表于 2023-9-6 15:52
上接口,我用au3试试

申通的开放平台,https://open.sto.cn/#/help/tz5gl0
下面是官方的签名构造:
签名使用 MD5 结合 Base64 编码的算法,示例代码如下:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
/**
* 计算签名值
*
* @param content  请求报文体
* @param secretkey   from_appkey 配置的私钥
* @return
*/
public static String calculateDigest(String content, String secretKey) {
    String text = content + secretKey;
    byte[] md5 = DigestUtils.md5(text);
    return Base64.encodeBase64String(md5);
}
如果项目中未引入 Apache 工具类,可直接使用 JDK 内置对象 java.security.MessageDigest  和 java.util.Base64  实现类似逻辑。
如果项目使用PHP语言,请使用 base64_encode(md5($content . $secret, true)) 来进行签名

简单验证:假设 content 为 {"waybillNo":"6606002282568"},secretkey 为 123abc,则签名结果为 N8jrMrujxlovfcE5BEF46Q==

只要签名结果对上了,剩下就是POST了,那个用现成的可用。


这里还有其他语言的调用
https://open.sto.cn/#/help/dbgrw7
 楼主| 发表于 2023-9-6 17:13:00 | 显示全部楼层
加密这一段打算用C#写个程序,调用C#进行加密,得到结果后给AU3用,初步调试已经没问题了,就是感觉不爽,还得调用其它语言。19年那会这么整过,忘了C#的那段代码扔哪了,还得重新写下。
现在好多API接口都是这样的,但是AU3的MD5加密只有一个参数,很受伤。
发表于 2023-9-6 18:11:39 | 显示全部楼层
风过无痕 发表于 2023-9-6 17:07
申通的开放平台,https://open.sto.cn/#/help/tz5gl0
下面是官方的签名构造:
签名使用 MD5 结合 Base6 ...

有点事情,晚上看看
发表于 2023-9-6 23:02:51 | 显示全部楼层
风过无痕 发表于 2023-9-6 17:07
申通的开放平台,https://open.sto.cn/#/help/tz5gl0
下面是官方的签名构造:
签名使用 MD5 结合 Base6 ...

这个感觉也不是很麻烦,得不到正确结果,还要找找原因,非Au3之过也。
#NoTrayIcon
#RequireAdmin
#PRE_UseX64=n
#include <ACN_HASH.au3>
#include <Crypt.au3>
Local $secretKey = '123abc'
Local $from_appkey = 'CAKRVo*******'
Local $from_code = 'CAKRVo*******'
Local $to_appkey = 'sto_oms'
Local $to_code = 'sto_oms'
Local $api_name = 'OMS_EXPRESS_ORDER_CREATE'
Local $content = '{"waybillNo":"6606002282568"}'
Local $n = _Crypt_HashData($content & $secretKey, $CALG_MD5)
Local $data_digest = _Base64Encode($n)
ConsoleWrite($data_digest & @CRLF)
Local $postdata = "from_appkey=" & _StringToEncode($from_appkey, 4) & _
                "&from_code=" & _StringToEncode($from_code, 4) & _
                "&to_appkey=" & _StringToEncode($to_appkey, 4) & _
                "&to_code=" & _StringToEncode($to_code, 4) & _
                "&api_name=" & _StringToEncode($api_name, 4) & _
                "&content=" & _StringToEncode($content, 4) & _
                "&data_digest=" & _StringToEncode($data_digest, 4)
Local $http = ObjCreate('WINHTTP.WINHTTPREQUEST.5.1')
$http.Open('POST', 'http://cloudinter-linkgatewaytest.sto.cn/gateway/link.do', True)
$http.SetRequestHeader("Accept", "*/*")
$http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
$http.Send($postdata)
$http.WaitForResponse()
Local $oReturnWebS = BinaryToString($http.ResponseBody, 4)
ConsoleWrite($oReturnWebS & @CRLF)
Func _StringToEncode($str, $Encode = 1, $AllFlag = 0, $sPrefix = '%')
        ;afan 提示:转换字符串为ANSI;GB2312;URL;unicode等格式编码
        ;$str - 需转换的字符串
        ;$Encode - [可选参数]编码格式: 1(默认) = ANSI; 2 = UTF16 小; 3 = UTF16 大; 4 = UTF8
        ;$AllFlag - [可选参数] =0 不转换字母及数字(默认); =1 全部转换(字符头http://除外)
        ;$sPrefix - [可选参数]编码首字符
        ;返回值:成功 - 返回转换后的编码字符串; 失败 - 设置 @Error = 1
        Local $str_s = StringRegExpReplace($str, '^\s*(?i)(http://).+', '$1')
        If Not @extended Then $str_s = ''
        If @extended Then $str = StringRegExpReplace($str, '^\s*(?i)http://', '')
        Local $sOut, $i, $sS2B, $aSR
        If $AllFlag Then
                $sS2B = StringTrimLeft(StringToBinary($str, $Encode), 2)
                $sOut = StringRegExpReplace($sS2B, '..', $sPrefix & '$0')
        Else
                $sOut = $str
                $aSR = StringRegExp($str, '\W+', 3)
                If Not @error Then
                        For $i = 0 To UBound($aSR) - 1
                                $sS2B = StringTrimLeft(StringToBinary($aSR[$i], $Encode), 2)
                                $sOut = StringReplace($sOut, $aSR[$i], StringRegExpReplace($sS2B, '..', $sPrefix & '$0'), 1)
                        Next
                EndIf
        EndIf
        If $sPrefix = ' ' Then $sOut = StringRegExpReplace($sOut, "^\h+|\h+$", '')
        ;$sOut = StringReplace($sOut, '%20', '+') ;转换空格的编码为'+'号,也可不要此行
        Return $str_s & $sOut
EndFunc   ;==>_StringToEncode

 楼主| 发表于 2023-9-6 23:10:41 | 显示全部楼层
haijie1223 发表于 2023-9-6 23:02
这个感觉也不是很麻烦,得不到正确结果,还要找找原因,非Au3之过也。

厉害,之前我用的base64函数不对,一直以为是MD5的问题了,所以始终得不到正确结果,后来用C#实现这部分的。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-2 11:55 , Processed in 0.082036 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表