PHP转Go:OPENSSL_ALGO_SHA1签名长数据不一致问题排查与解决
PHP与Go RSA SHA1签名一致性问题解决
原有PHP签名逻辑
使用openssl_sign结合OPENSSL_ALGO_SHA1算法完成签名后,执行标准Base64编码,代码如下:
$signature = ''; $data = strval($aMessage); if (!openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA1)) { return null; } $signature = base64_encode($signature);
初始Go迁移代码
迁移后的Go代码实现如下,测试发现短数据签名结果与PHP一致,但长数据时结果无法匹配:
var rpk *rsa.PrivateKey var bs []byte if rpk, err = c.getRSAPrivateKey(); err != nil { return } if bs, err = json.Marshal(c); err != nil { return } var hash = crypto.SHA1.New() hash.Write(bs) if bs, err = rsa.SignPKCS1v15(rand.Reader, rpk, crypto.SHA1, hash.Sum(nil)); err != nil { return } return base64.RawURLEncoding.EncodeToString(bs), err
问题排查与修复
经定位,差异源于Base64编码方式:PHP使用标准Base64编码,而初始Go代码采用了base64.RawURLEncoding(无填充的URL安全编码),导致字符映射规则不同。修正后的Base64编码逻辑如下:
var b64s = base64.URLEncoding.EncodeToString(bs) b64s = strings.ReplaceAll(b64s, "-", "+") b64s = strings.ReplaceAll(b64s, "_", "/")
修正后,无论数据长短,Go与PHP的签名结果均可保持完全一致。
内容的提问来源于stack exchange,提问作者danjian
相关产品推荐
相关产品推荐

