package model_test import ( "crypto/sha256" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.yandata.net/iod/iod/go-trustlog/api/model" ) // TestSM2RequiresHash 测试SM2是否要求预先hash数据 // 根据文档,SM2.SignASN1期望接收hash值,而不是原始数据 // 但文档也提到:如果opts是*SM2SignerOption且ForceGMSign为true,则hash会被视为原始消息. func TestSM2RequiresHash(t *testing.T) { t.Parallel() // 生成SM2密钥对 keyPair, err := model.GenerateSM2KeyPair() require.NoError(t, err) // 测试数据 originalData := []byte("test data for SM2 signing") // 1. 直接对原始数据签名(当前实现的方式) // go-crpt 库会自动使用 SM3 计算摘要 signature1, err := keyPair.SignMessage(originalData) require.NoError(t, err) require.NotNil(t, signature1) // 2. 验证签名(使用原始数据) valid1, err := keyPair.VerifyMessage(originalData, signature1) require.NoError(t, err) t.Logf("直接使用原始数据签名和验证结果: %v", valid1) assert.True(t, valid1, "当前实现:直接对原始数据签名和验证应该成功") // 3. 先hash再签名(文档推荐的方式) hashBytesReal := sha256.Sum256(originalData) signature2, err := keyPair.SignMessage(hashBytesReal[:]) require.NoError(t, err) require.NotNil(t, signature2) // 4. 验证签名(使用hash值) valid2, err := keyPair.VerifyMessage(hashBytesReal[:], signature2) require.NoError(t, err) t.Logf("先hash再签名和验证结果: %v", valid2) assert.True(t, valid2, "先hash再签名和验证应该成功") // 5. 交叉验证:用原始数据验证hash后的签名 valid3, err := keyPair.VerifyMessage(originalData, signature2) require.NoError(t, err) t.Logf("用原始数据验证hash后的签名结果: %v", valid3) // 6. 交叉验证:用hash值验证原始数据的签名 valid4, err := keyPair.VerifyMessage(hashBytesReal[:], signature1) require.NoError(t, err) t.Logf("用hash值验证原始数据的签名结果: %v", valid4) // 结论: // - 如果valid1=true且valid4=false,说明SM2内部可能处理了hash,或者有某种兼容性 // - 如果valid1=true且valid4=true,说明SM2可能接受原始数据(不符合文档) // - 如果valid1=false,说明SM2确实需要hash值 t.Logf("\n结论分析:") t.Logf("- 直接对原始数据签名和验证: %v", valid1) t.Logf("- 先hash再签名和验证: %v", valid2) t.Logf("- 交叉验证1(原始数据 vs hash签名): %v", valid3) t.Logf("- 交叉验证2(hash数据 vs 原始签名): %v", valid4) switch { case valid1 && !valid4: t.Logf("✓ SM2库可能内部处理了hash,或者有兼容性机制") t.Logf("✓ 当前实现(直接使用原始数据)可能是可行的") case valid1 && valid4: t.Logf("⚠ SM2库可能接受原始数据,与文档不符") t.Logf("⚠ 但当前实现可以工作") default: t.Logf("✗ SM2确实需要hash值,当前实现可能有问题") } }