Open aomirun opened 2 years ago
请问是否有解决方案了?我看java和go在生成密钥时候就不一样,java的公钥是获取的Q,但是golang是获取的X、Y,还请有大佬解答下
@aomirun 请教下 SM2WITHSM3是怎么实现的啊
@sax1412 因国密PKCS7各服务端验证有所区别,根据对方pkcs7签名的ASN1结构,来修改PKCS7生成的参数.
@jiuerzhange 目前还没有,主要是国密签名机好像对C 系的uin8没有做支持,使得最终签名验证失败.
感觉某些地方不严谨, 没有与其它语言C、java做关联性验证。 导致自己加密解密,不能与其它语言兼容使用。 算法是正确的,就是细节问题。
sm2的加解密我拿java互通了,可签名验签没搞了,有大佬整一下吗
sm2的加解密我拿java互通了,可签名验签没搞了,有大佬整一下吗
求一下,java与go互通这块的资料。我java是用hutool生成的,在go这里一直通不了。
golang
大佬,有go的demo吗?我这边跟java的老是互通不了
解决了吗?我这也不通
解决了吗?我这也不通
我只是加解密可以了,签名没试过,你可以参考一下。https://blog.csdn.net/4color/article/details/127305555
解决了吗?我这也不通
我解决了、具体参考我写的博客https://blog.csdn.net/hahawangzi520/article/details/126187783
sm2的加解密我拿java互通了,可签名验签没搞了,有大佬整一下吗
我解决了、具体参考我写的博客https://blog.csdn.net/hahawangzi520/article/details/126187783
对接过招行,所以看了一下招行的java使用demo,使用的是hutool的加密库,签名曲线用的sm2p256v1,对SM2Signer生成的签名进行了自定义解析 我自己使用本库gm2的默认签名和验签进行了简单修改,以下仅包含签名的简单示例代码
// gmsm库的sm2签名
r, s, err := Sm2Sign(priv, msg, nil, random)
if err != nil {
return nil, err
}
return asn1.Marshal(sm2Signature{r, s})
最终返回的是asn1的结构体序列化,可以将r,s的[]byte添加到bytes.Buffer,[]byte长度为32不足前面补0
// 修改后的签名
rByte := r.Bytes()
sByte := s.Bytes()
if len(rByte) < 32 {
rByte = append([]byte{0}, rByte...)
}
if len(sByte) < 32 {
sByte = append([]byte{0}, sByte...)
}
var buffer bytes.Buffer
buffer.Write(rByte)
buffer.Write(sByte)
java的demo中的签名
ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(),spec.getH(),spec.getSeed());
ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters(new BigInteger(1, key), domainParameters);
ParametersWithID parameters = new ParametersWithID(privateKey, "1234567812345678".getBytes());
byte[] data = msg.getBytes();
SM2Signer signer = new SM2Signer();
signer.init(true, parameters);
signer.update(data, 0, data.length);
public byte[] signature=signer.generateSignature();
ASN1InputStream stream = new ASN1InputStream(new ByteArrayInputStream(signature));
try {
ASN1Sequence primitive = (ASN1Sequence)stream.readObject();
Enumeration enumeration = primitive.getObjects();
BigInteger R = ((ASN1Integer)enumeration.nextElement()).getValue();
BigInteger S = ((ASN1Integer)enumeration.nextElement()).getValue();
byte[] bytes = new byte[64];
byte[] r = format(R.toByteArray());
byte[] s = format(S.toByteArray());
System.arraycopy(r, 0, bytes, 0, 32);
System.arraycopy(s, 0, bytes, 32, 32);
return bytes;
} catch (Exception e) {
throw new Exception();
}
对接过招行,所以看了一下招行的java使用demo,使用的是hutool的加密库,签名曲线用的sm2p256v1,对SM2Signer生成的签名进行了自定义解析 我自己使用本库gm2的默认签名和验签进行了简单修改,以下仅包含签名的简单示例代码
// gmsm库的sm2签名 r, s, err := Sm2Sign(priv, msg, nil, random) if err != nil { return nil, err } return asn1.Marshal(sm2Signature{r, s})
最终返回的是asn1的结构体序列化,可以将r,s的[]byte添加到bytes.Buffer,[]byte长度为32不足前面补0
// 修改后的签名 rByte := r.Bytes() sByte := s.Bytes() if len(rByte) < 32 { rByte = append([]byte{0}, rByte...) } if len(sByte) < 32 { sByte = append([]byte{0}, sByte...) } var buffer bytes.Buffer buffer.Write(rByte) buffer.Write(sByte)
java的demo中的签名
ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); ECDomainParameters domainParameters = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(),spec.getH(),spec.getSeed()); ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters(new BigInteger(1, key), domainParameters); ParametersWithID parameters = new ParametersWithID(privateKey, "1234567812345678".getBytes()); byte[] data = msg.getBytes(); SM2Signer signer = new SM2Signer(); signer.init(true, parameters); signer.update(data, 0, data.length); public byte[] signature=signer.generateSignature(); ASN1InputStream stream = new ASN1InputStream(new ByteArrayInputStream(signature)); try { ASN1Sequence primitive = (ASN1Sequence)stream.readObject(); Enumeration enumeration = primitive.getObjects(); BigInteger R = ((ASN1Integer)enumeration.nextElement()).getValue(); BigInteger S = ((ASN1Integer)enumeration.nextElement()).getValue(); byte[] bytes = new byte[64]; byte[] r = format(R.toByteArray()); byte[] s = format(S.toByteArray()); System.arraycopy(r, 0, bytes, 0, 32); System.arraycopy(s, 0, bytes, 32, 32); return bytes; } catch (Exception e) { throw new Exception(); }
这是解决了吗,我看了 一下很多都是验签的问题,我现在也卡在这里
对接过招行,所以看了一下招行的java使用demo,使用的是hutool的加密库,签名曲线用的sm2p256v1,对SM2Signer生成的签名进行了自定义解析 我自己使用本库gm2的默认签名和验签进行了简单修改,以下仅包含签名的简单示例代码
// gmsm库的sm2签名 r, s, err := Sm2Sign(priv, msg, nil, random) if err != nil { return nil, err } return asn1.Marshal(sm2Signature{r, s})
最终返回的是asn1的结构体序列化,可以将r,s的[]byte添加到bytes.Buffer,[]byte长度为32不足前面补0
// 修改后的签名 rByte := r.Bytes() sByte := s.Bytes() if len(rByte) < 32 { rByte = append([]byte{0}, rByte...) } if len(sByte) < 32 { sByte = append([]byte{0}, sByte...) } var buffer bytes.Buffer buffer.Write(rByte) buffer.Write(sByte)
java的demo中的签名
ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); ECDomainParameters domainParameters = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(),spec.getH(),spec.getSeed()); ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters(new BigInteger(1, key), domainParameters); ParametersWithID parameters = new ParametersWithID(privateKey, "1234567812345678".getBytes()); byte[] data = msg.getBytes(); SM2Signer signer = new SM2Signer(); signer.init(true, parameters); signer.update(data, 0, data.length); public byte[] signature=signer.generateSignature(); ASN1InputStream stream = new ASN1InputStream(new ByteArrayInputStream(signature)); try { ASN1Sequence primitive = (ASN1Sequence)stream.readObject(); Enumeration enumeration = primitive.getObjects(); BigInteger R = ((ASN1Integer)enumeration.nextElement()).getValue(); BigInteger S = ((ASN1Integer)enumeration.nextElement()).getValue(); byte[] bytes = new byte[64]; byte[] r = format(R.toByteArray()); byte[] s = format(S.toByteArray()); System.arraycopy(r, 0, bytes, 0, 32); System.arraycopy(s, 0, bytes, 32, 32); return bytes; } catch (Exception e) { throw new Exception(); }
这是解决了吗,我看了 一下很多都是验签的问题,我现在也卡在这里
我这边是验签通过了的,Java端验签,具体得看Java端对签名值的解析方式,像我这边对接的他是要求128位长度的hex,但是本库的签名返回对象是ASN1的结构体,得到的一般是144位,偶尔长度不够,所以需要补0,单从长度上就不一致,看hutool工具类的验签实现,他是利用解析的两个大数,R和S来做的验证,所以他转成[]byte后直接截取[]byte的前32位 和后32位分别做R和S就通过了,所以我这边做了一下转换,两边统一了序列化对象应该没什么问题
我解决了java和go之间的国密算法签名问题、具体参考我写的博客、花了很多精力攻克的、虽然是付费的、也希望大佬能支持下原创。
https://blog.csdn.net/hahawangzi520/article/details/126187783
@ahKevinXy 我解决了java和go之间的国密算法签名问题、具体参考我写的博客、花了很多精力攻克的、虽然是付费的、也希望大佬能支持下原创。
https://blog.csdn.net/hahawangzi520/article/details/126187783
@ahKevinXy 我解决了java和go之间的国密算法签名问题、具体参考我写的博客、花了很多精力攻克的、虽然是付费的、也希望大佬能支持下原创。
https://blog.csdn.net/hahawangzi520/article/details/126187783
没事 我写了一个 Java 的sdk 解决了,付费就没有必要看了
成
这边 可以提供一下源码吗,最近我也是对接招商银行,就是验签不通
成
这边 可以提供一下源码吗,最近我也是对接招商银行,就是验签不通
上面的示例代码就可以,修改后的签名就是(验签同理),健壮性你自己保证
我用 Java 写了一个单独的验签了
我解决了java和go之间的国密算法签名问题、具体参考我写的博客、花了很多精力攻克的、虽然是付费的、也希望大佬能支持下原创。
https://blog.csdn.net/hahawangzi520/article/details/126187783
我就去看了,然而什么内容都没讲到,引用他的原文“(4)golang golang的sm2解密有时候成功,有时候失败,经过我反复测试,是testing依赖模块导致的,但是底层原因未知,我把代码放到run.go的main方法里,都是正常执行。如果有小伙伴懂的话,可以私信我。” 下面例子也是普通的例子,这就叫解决了?!
我解决了java和go之间的国密算法签名问题、具体参考我写的博客、花了很多精力攻克的、虽然是付费的、也希望大佬能支持下原创。 https://blog.csdn.net/hahawangzi520/article/details/126187783
我就去看了,然而什么内容都没讲到,引用他的原文“(4)golang golang的sm2解密有时候成功,有时候失败,经过我反复测试,是testing依赖模块导致的,但是底层原因未知,我把代码放到run.go的main方法里,都是正常执行。如果有小伙伴懂的话,可以私信我。” 下面例子也是普通的例子,这就叫解决了?!
源码发一下
@ahKevinXy 用 Golang 写了一个完整的示例 https://github.com/hxkjason/cmb_SM3withSM2_sign_demo, FYI。
@ahKevinXy 用 Golang 写了一个完整的示例 https://github.com/hxkjason/cmb_SM3withSM2_sign_demo, FYI。
试一下看看,我的java的一直不稳定
@ahKevinXy 用 Golang 写了一个完整的示例 https://github.com/hxkjason/cmb_SM3withSM2_sign_demo, FYI。
感谢啊,折腾了快一天,从你这搞定了
@yidashi 不谢~ 很高兴能够给你带来一点帮助~
@ahKevinXy 用 Golang 写了一个完整的示例 https://github.com/hxkjason/cmb_SM3withSM2_sign_demo, FYI。
感谢啊,折腾了快一天,从你这搞定了
你怎么成功的,为啥我的不行
package sm2
import (
"bytes"
"crypto/rand"
"encoding/hex"
"math/big"
"strings"
"github.com/tjfoc/gmsm/sm2"
)
func Sign(signContent, privateKey, userId string) string {
signContent = strings.ReplaceAll(signContent, `"`, `\"`)
priKey := TransHexToSm2PrivateKey(privateKey)
r, s, err := sm2.Sm2Sign(priKey, []byte(signContent), []byte(userId), rand.Reader)
if err != nil {
return ""
}
rBytes, sBytes := r.Bytes(), s.Bytes()
rLen, sLen := len(rBytes), len(sBytes)
regularSize := 32
if rLen < regularSize {
for i := 0; i < regularSize-rLen; i++ {
rBytes = append(rBytes, 0)
}
}
if sLen < regularSize {
for i := 0; i < regularSize-sLen; i++ {
sBytes = append(sBytes, 0)
}
}
var buffer bytes.Buffer
buffer.Write(rBytes)
buffer.Write(sBytes)
return strings.ToUpper(hex.EncodeToString(buffer.Bytes()))
}
// TransHexToSm2PrivateKey 将16进制私钥转换成sm2私钥实例
func TransHexToSm2PrivateKey(HexPrivateKey string) *sm2.PrivateKey {
d := new(big.Int)
d.SetString(HexPrivateKey, 16)
privateKey := new(sm2.PrivateKey)
privateKey.D = d
curve := sm2.P256Sm2()
privateKey.PublicKey.Curve = curve
privateKey.PublicKey.X, privateKey.PublicKey.Y = curve.ScalarBaseMult(d.Bytes())
return privateKey
}
@ahKevinXy 用 Golang 写了一个完整的示例 https://github.com/hxkjason/cmb_SM3withSM2_sign_demo, FYI。
感谢啊,折腾了快一天,从你这搞定了
你怎么成功的,为啥我的不行
package sm2 import ( "bytes" "crypto/rand" "encoding/hex" "math/big" "strings" "github.com/tjfoc/gmsm/sm2" ) func Sign(signContent, privateKey, userId string) string { signContent = strings.ReplaceAll(signContent, `"`, `\"`) priKey := TransHexToSm2PrivateKey(privateKey) r, s, err := sm2.Sm2Sign(priKey, []byte(signContent), []byte(userId), rand.Reader) if err != nil { return "" } rBytes, sBytes := r.Bytes(), s.Bytes() rLen, sLen := len(rBytes), len(sBytes) regularSize := 32 if rLen < regularSize { for i := 0; i < regularSize-rLen; i++ { rBytes = append(rBytes, 0) } } if sLen < regularSize { for i := 0; i < regularSize-sLen; i++ { sBytes = append(sBytes, 0) } } var buffer bytes.Buffer buffer.Write(rBytes) buffer.Write(sBytes) return strings.ToUpper(hex.EncodeToString(buffer.Bytes())) } // TransHexToSm2PrivateKey 将16进制私钥转换成sm2私钥实例 func TransHexToSm2PrivateKey(HexPrivateKey string) *sm2.PrivateKey { d := new(big.Int) d.SetString(HexPrivateKey, 16) privateKey := new(sm2.PrivateKey) privateKey.D = d curve := sm2.P256Sm2() privateKey.PublicKey.Curve = curve privateKey.PublicKey.X, privateKey.PublicKey.Y = curve.ScalarBaseMult(d.Bytes()) return privateKey }
这个确实可以通过招行java的验签,有个大坑,如果是非saas模式,不能加那个平台签 “paltsigdat”, 否则一直会提示 “签名信息无效” 大坑 最无语的是用官方提供的java demo ,同一套key, 加上平台签名是可以通过的,golang版本死活通过不了,去掉又可以
@ahKevinXy 用 Golang 写了一个完整的示例 https://github.com/hxkjason/cmb_SM3withSM2_sign_demo, FYI。
感谢啊,折腾了快一天,从你这搞定了
你怎么成功的,为啥我的不行
package sm2 import ( "bytes" "crypto/rand" "encoding/hex" "math/big" "strings" "github.com/tjfoc/gmsm/sm2" ) func Sign(signContent, privateKey, userId string) string { signContent = strings.ReplaceAll(signContent, `"`, `\"`) priKey := TransHexToSm2PrivateKey(privateKey) r, s, err := sm2.Sm2Sign(priKey, []byte(signContent), []byte(userId), rand.Reader) if err != nil { return "" } rBytes, sBytes := r.Bytes(), s.Bytes() rLen, sLen := len(rBytes), len(sBytes) regularSize := 32 if rLen < regularSize { for i := 0; i < regularSize-rLen; i++ { rBytes = append(rBytes, 0) } } if sLen < regularSize { for i := 0; i < regularSize-sLen; i++ { sBytes = append(sBytes, 0) } } var buffer bytes.Buffer buffer.Write(rBytes) buffer.Write(sBytes) return strings.ToUpper(hex.EncodeToString(buffer.Bytes())) } // TransHexToSm2PrivateKey 将16进制私钥转换成sm2私钥实例 func TransHexToSm2PrivateKey(HexPrivateKey string) *sm2.PrivateKey { d := new(big.Int) d.SetString(HexPrivateKey, 16) privateKey := new(sm2.PrivateKey) privateKey.D = d curve := sm2.P256Sm2() privateKey.PublicKey.Curve = curve privateKey.PublicKey.X, privateKey.PublicKey.Y = curve.ScalarBaseMult(d.Bytes()) return privateKey }
这个确实可以通过招行java的验签,有个大坑,如果是非saas模式,不能加那个平台签 “paltsigdat”, 否则一直会提示 “签名信息无效” 大坑 最无语的是用官方提供的java demo ,同一套key, 加上平台签名是可以通过的,golang版本死活通过不了,去掉又可以
有例子吗,我现在还是Java 验签 坑的我头发都掉完了
@ahKevinXy 用 Golang 写了一个完整的示例 https://github.com/hxkjason/cmb_SM3withSM2_sign_demo, FYI。
感谢啊,折腾了快一天,从你这搞定了
你怎么成功的,为啥我的不行
package sm2 import ( "bytes" "crypto/rand" "encoding/hex" "math/big" "strings" "github.com/tjfoc/gmsm/sm2" ) func Sign(signContent, privateKey, userId string) string { signContent = strings.ReplaceAll(signContent, `"`, `\"`) priKey := TransHexToSm2PrivateKey(privateKey) r, s, err := sm2.Sm2Sign(priKey, []byte(signContent), []byte(userId), rand.Reader) if err != nil { return "" } rBytes, sBytes := r.Bytes(), s.Bytes() rLen, sLen := len(rBytes), len(sBytes) regularSize := 32 if rLen < regularSize { for i := 0; i < regularSize-rLen; i++ { rBytes = append(rBytes, 0) } } if sLen < regularSize { for i := 0; i < regularSize-sLen; i++ { sBytes = append(sBytes, 0) } } var buffer bytes.Buffer buffer.Write(rBytes) buffer.Write(sBytes) return strings.ToUpper(hex.EncodeToString(buffer.Bytes())) } // TransHexToSm2PrivateKey 将16进制私钥转换成sm2私钥实例 func TransHexToSm2PrivateKey(HexPrivateKey string) *sm2.PrivateKey { d := new(big.Int) d.SetString(HexPrivateKey, 16) privateKey := new(sm2.PrivateKey) privateKey.D = d curve := sm2.P256Sm2() privateKey.PublicKey.Curve = curve privateKey.PublicKey.X, privateKey.PublicKey.Y = curve.ScalarBaseMult(d.Bytes()) return privateKey }
这个确实可以通过招行java的验签,有个大坑,如果是非saas模式,不能加那个平台签 “paltsigdat”, 否则一直会提示 “签名信息无效” 大坑 最无语的是用官方提供的java demo ,同一套key, 加上平台签名是可以通过的,golang版本死活通过不了,去掉又可以
有例子吗,我现在还是Java 验签 坑的我头发都掉完了
func (s *sZsyh) getUid() []byte {
ivStr := gstr.SubStr(s.Userid+"0000000000000000", 0, 16)
iv := []byte(ivStr)
return iv
}
// CMBSM2SignWithSM3 sign
func (s2 *sZsyh) CMBSM2SignWithSM3(forSignStr string) (string, error) {
privateKey := s2.GetSm2PrivateKey()
uid := s2.getUid()
r, s, err := sm2.Sm2Sign(privateKey, []byte(forSignStr), uid, rand.Reader)
if err != nil {
return "", err
}
rBytes, sBytes := r.Bytes(), s.Bytes()
rLen, sLen := len(rBytes), len(sBytes)
regularSize := 32
if rLen < regularSize {
for i := 0; i < regularSize-rLen; i++ {
rBytes = append(rBytes, 0)
}
}
if sLen < regularSize {
for i := 0; i < regularSize-sLen; i++ {
sBytes = append(sBytes, 0)
}
}
var buffer bytes.Buffer
buffer.Write(rBytes)
buffer.Write(sBytes)
return gbase64.EncodeToString(buffer.Bytes()), nil
}
// SM3Sum SM3摘要 Hex ToUpper
func SM3Sum(forSignStr string) string {
h := sm3.New()
h.Write([]byte(forSignStr))
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
// TransHexToSm2PrivateKey 将16进制私钥转换成sm2私钥实例
func (s *sZsyh) GetSm2PrivateKey() *sm2.PrivateKey {
privateKeyBytes, _ := gbase64.DecodeString(s.PrivateKey)
HexPrivateKey := hex.EncodeToString(privateKeyBytes)
d := new(big.Int)
d.SetString(HexPrivateKey, 16)
privateKey := new(sm2.PrivateKey)
privateKey.D = d
curve := sm2.P256Sm2()
privateKey.PublicKey.Curve = curve
privateKey.PublicKey.X, privateKey.PublicKey.Y = curve.ScalarBaseMult(d.Bytes())
return privateKey
}
func (s *sZsyh) CMBSM4EncryptWithCBC(data string) []byte {
// 16 字节的密钥
key := []byte(s.DuichenKey)
// 16 字节的 IV (初始向量)
ivStr := gstr.SubStr(s.Userid+"0000000000000000", 0, 16)
iv := []byte(ivStr)
// 待加密的数据
plaintext := []byte(data)
// 创建一个 SM4 分组密码块
block, err := sm4.NewCipher(key)
if err != nil {
panic(err)
}
// 创建 CBC 分组模式
mode := cipher.NewCBCEncrypter(block, iv)
// 对数据进行填充
paddedPlaintext := make([]byte, len(plaintext))
copy(paddedPlaintext, plaintext)
paddingLen := sm4.BlockSize - (len(paddedPlaintext) % sm4.BlockSize)
for i := 0; i < paddingLen; i++ {
paddedPlaintext = append(paddedPlaintext, byte(paddingLen))
}
// 加密数据
ciphertext := make([]byte, len(paddedPlaintext))
mode.CryptBlocks(ciphertext, paddedPlaintext)
//fmt.Printf("%x", ciphertext)
return ciphertext
}
func (s *sZsyh) CMBSM4DecryptWithCBC(ciphertext []byte) []byte {
// 16 字节的密钥
key := []byte(s.DuichenKey)
// 16 字节的 IV (初始向量)
ivStr := gstr.SubStr(s.Userid+"0000000000000000", 0, 16)
iv := []byte(ivStr)
// 待解密的数据
//ciphertext = PKCS7Padding(ciphertext, sm4.BlockSize)
block, err := sm4.NewCipher(key)
if err != nil {
panic(err)
}
mode := cipher.NewCBCDecrypter(block, iv)
plaintext := make([]byte, len(ciphertext))
mode.CryptBlocks(plaintext, ciphertext)
return plaintext
}
实在懒得整理了,有几个编码函数用的goframe的,改成原生的就行。能走通,签名和验签函数名都跟java那个sdk同名。大概就这些东西,但愿你改吧改吧能成功
终于解决了招商银行验签 谢谢大佬们
终于解决了招商银行验签 谢谢大佬们
怎么解决的能提供下源码吗 好想userid不对
终于解决了招商银行验签 谢谢大佬们
怎么解决的能提供下源码吗 好想userid不对
可以的 你加群 问一下,我这边线上跑起来了
你好怎么加群
终于解决了招商银行验签 谢谢大佬们
怎么解决的能提供下源码吗 好想userid不对
可以的 你加群 问一下,我这边线上跑起来了
你好怎么加群
你好怎么加群
终于解决了招商银行验签 谢谢大佬们
怎么解决的能提供下源码吗 好想userid不对
可以的 你加群 问一下,我这边线上跑起来了
你好怎么加群
我加你 qq微信了
有兴业搞定的吗 招商和兴业还不一样
我找到了一个可以互相计算hash值,可以对得上得库了
hxkjason
感谢!卡了一天,用这个过了
你好怎么加群
终于解决了招商银行验签 谢谢大佬们
怎么解决的能提供下源码吗 好想userid不对
可以的 你加群 问一下,我这边线上跑起来了
你好怎么加群
我加你 qq微信了
请问可以提供一下吗,qq:2396514849
终于解决了招商银行验签 谢谢大佬们
大佬,有空帮忙看下啥问题么,一直验签不过
type SZsyh struct {
PrivateKey string
}
// CMBSM2SignWithSM3 sign
func (s2 *SZsyh) CMBSM2SignWithSM3(forSignStr string, uid []byte) (string, error) {
privateKey := s2.GetSm2PrivateKey()
r, s, err := sm2.Sm2Sign(privateKey, []byte(forSignStr), uid, rand.Reader)
if err != nil {
return "", err
}
rBytes, sBytes := r.Bytes(), s.Bytes()
rLen, sLen := len(rBytes), len(sBytes)
regularSize := 32
if rLen < regularSize {
for i := 0; i < regularSize-rLen; i++ {
rBytes = append(rBytes, 0)
}
}
if sLen < regularSize {
for i := 0; i < regularSize-sLen; i++ {
sBytes = append(sBytes, 0)
}
}
var buffer bytes.Buffer
buffer.Write(rBytes)
buffer.Write(sBytes)
return base64.StdEncoding.EncodeToString(buffer.Bytes()), nil
}
// SM3Sum SM3摘要 Hex ToUpper
func SM3Sum(forSignStr string) string {
h := sm3.New()
h.Write([]byte(forSignStr))
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
// TransHexToSm2PrivateKey 将16进制私钥转换成sm2私钥实例
func (s *SZsyh) GetSm2PrivateKey() *sm2.PrivateKey {
privateKeyBytes, _ := base64.StdEncoding.DecodeString(s.PrivateKey)
d := new(big.Int)
d.SetBytes(privateKeyBytes)
privateKey := new(sm2.PrivateKey)
privateKey.D = d
curve := sm2.P256Sm2()
privateKey.PublicKey.Curve = curve
privateKey.PublicKey.X, privateKey.PublicKey.Y = curve.ScalarBaseMult(d.Bytes())
return privateKey
}
主页go-cmb 上有联系方式
java Hutool 和 go 之间 sm2 / sm4 互通可以参考下我的,调通了 https://programnotes.cn/crypto/ 主要是保持加密模式一致,ecb,c1c3c2...
fork代码修改后,可以正常做 SM2WITHSM3了,但是对方是JAVA服务端,验证签名失败. 正常的PKCS1祼签JAVA方也不能验证. 查看了一下ASN1的数据 GO生成的签名,R,S长度32,JAVA长度33
GO可以验证JAVA和GO自己的签名 JAVA不能验证GO生成的签名
GO
JAVA