Encryption 验证经典ASP中的条带Webhook签名

Encryption 验证经典ASP中的条带Webhook签名,encryption,asp-classic,stripe-payments,chilkat,Encryption,Asp Classic,Stripe Payments,Chilkat,Stripe建议使用他们的库来验证签名,但因为他们没有一个可以与Classic一起使用的库,所以我不得不手动进行验证,我真的很难做到这一点 () 步骤1:从拆分的头中提取时间戳和签名 标题,使用,字符作为分隔符,以获取 元素。然后分割每个元素,使用=字符作为 分隔符,以获取前缀和值对。前缀t的值 对应于时间戳,v1对应于签名。 您可以放弃所有其他元素 步骤2:准备签名的_有效负载字符串,您可以通过 连接:字符的时间戳(作为字符串)。实际的 JSON有效负载(即请求的主体) 步骤3:使用 SHA2

Stripe建议使用他们的库来验证签名,但因为他们没有一个可以与Classic一起使用的库,所以我不得不手动进行验证,我真的很难做到这一点

()

步骤1:从拆分的头中提取时间戳和签名 标题,使用,字符作为分隔符,以获取 元素。然后分割每个元素,使用=字符作为 分隔符,以获取前缀和值对。前缀t的值 对应于时间戳,v1对应于签名。 您可以放弃所有其他元素

步骤2:准备签名的_有效负载字符串,您可以通过 连接:字符的时间戳(作为字符串)。实际的 JSON有效负载(即请求的主体)

步骤3:使用 SHA256哈希函数。使用端点的签名密钥作为密钥, 并使用签名的_有效负载字符串作为消息

步骤4:比较签名将标头中的签名与 预期的签名。如果签名匹配,则计算差异 在当前时间戳和接收到的时间戳之间,然后决定 如果差异在您的容忍范围内。为了防止计时 攻击时,使用常量时间字符串比较来比较预期的 每个收到的签名的签名

我认为我的代码是正确的:

”键
如果strStripeMode=“live”,则
strSigningSecret=“”
其他的
strSigningSecret=“whsec_CIXV2..UR8Ta0”
如果结束
“1.有效载荷
LNGBytes=Request.TotalBytes
strPayload=BytesToStr(Request.BinaryRead(lngbytesunt))
“2.条纹签名
strStripeSignature=Request.ServerVariables(“HTTP\u STRIPE\u签名”)
arrStripeSignature=拆分(strStripeSignature,“,”)
intTimeStamp=REPLACE(arrStripeSignature(0),“t=”,“”)
STRV1签名=替换(arrStripeSignature(1),“v1=”,“”)
strSignedPayload=intTimeStamp&“&”和strv1签名&strPayload
'3.使用'signing secret'作为密钥进行哈希。
set crypt=Server.CreateObject(“Chilkat_9_5_0.Crypt2”)
crypt.HashAlgorithm=“sha256”
crypt.EncodingMode=“十六进制”
crypt.SetHmacKeyEncoded strSigningSecret,“ascii”
strHashedSignature=crypt.HmacStringENC(strSignedPayload)
set crypt=nothing
'4.比较这些值
如果strHashedSignature=strv1签名,则
“有效的
响应。状态=“200”
Response.Write(Response.Status)
’------做点什么------------
答复.完
其他的
“无效
响应。状态=“300”
Response.Write(Response.Status)
’------做点什么------------
答复.完
如果结束
'字节到字符串函数
函数BytesToStr(字节)
暗流
Set Stream=Server.CreateObject(“Adodb.Stream”)
Stream.Type=1'adTypeBinary
小溪,打开
流。写入字节
Stream.Position=0
Stream.Type=2'adTypeText
Stream.Charset=“iso-8859-1”
BytesToStr=Stream.ReadText
关闭
设置流=无
端函数

我遇到的第一个问题是,我不确定在步骤2中是否正确生成了有符号的#u有效负载字符串。第二个问题是,步骤#3中的strHashedSignature显示为空白,可能是因为没有正确生成已签名的#有效负载字符串(strSignedPayload)

我想我应该更新这个,以防将来有人遇到问题。解决方案有两个方面

首先,我在签名的_有效负载字符串上完全隔开,包括出于某种原因的v1Signature(我的借口是这是星期五的一天结束:)

它只应该是:

strSignedPayload = intTimeStamp & "." & strPayload

第二个是@karllekko所说的,编码需要是UTF-8

你对
v1
字符串做了一个假设,盲目地试图替换它,假设它在初始拆分中总是元素2,但文档说它还可以包括
v0
或更多的方案。首先,您可以根据
进行正确的拆分,但实际上您应该使用
=
再次拆分每个数组元素,或者执行类似于
InStr()
检查
v1=
的操作。在考虑散列计算错误之前,需要确保您首先组合了正确的值。
Replace()
函数需要记住的一点是,如果它没有找到
t=
v1=
它只会返回原始字符串,而不做任何更改。这意味着您组合了错误的值,散列将反映这一点。需要注意的一点是,Stripe以UTF-8编码字符串,因此您应该将其用作
流。Charset
(否则您可能无法读取Stripe发送的相同字符串,这将导致签名不匹配)@karllekko在某个地方被记录下来了,因为我确实查看了,但没有提到创建哈希时要使用什么编码?Lankymart很好,我不认为在任何地方都有明确的说明,但这是真的。如果你看看Stripe解码webhook事件的一些例子,它们总是使用UTF-8,例如。
strSignedPayload = intTimeStamp & "." & strPayload