{"record":{"id":"c566bcb233d55507","repo":"OpenNHP/opennhp","slug":"private-key-too-short-got-d-bytes-need-d-c566bc","errorCode":null,"errorMessage":"private key too short: got %d bytes, need %d","messagePattern":"private key too short: got (.+?) bytes, need (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/scheme/gmsm/gmsm.go","lineNumber":30,"sourceCode":")\n\nconst (\n\tPrivateKeySize = 32\n\tPublicKeySize  = 64\n)\n\ntype SM2ECDH struct {\n\tPrivKey       [PrivateKeySize]byte\n\tPubKey        [PublicKeySize]byte\n\tprvK          *ecdh.PrivateKey\n\tPrivKeyBase64 string\n\tPubKeyBase64  string\n\tBriefName     string\n}\n\nfunc (s *SM2ECDH) SetPrivateKey(prk []byte) (err error) {\n\tif len(prk) < PrivateKeySize {\n\t\treturn fmt.Errorf(\"private key too short: got %d bytes, need %d\", len(prk), PrivateKeySize)\n\t}\n\tcopy(s.PrivKey[:], prk[:PrivateKeySize])\n\ts.prvK, err = ecdh.P256().NewPrivateKey(prk)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcopy(s.PubKey[:], s.prvK.PublicKey().Bytes()[1:1+PublicKeySize])\n\ts.PrivKeyBase64 = base64.StdEncoding.EncodeToString(s.PrivKey[:])\n\ts.PubKeyBase64 = base64.StdEncoding.EncodeToString(s.PubKey[:])\n\ts.BriefName = fmt.Sprintf(\"%s...%s\", s.PubKeyBase64[0:4], s.PubKeyBase64[39:43])\n\n\treturn nil\n}\n\nfunc (s *SM2ECDH) PrivateKey() []byte {\n\treturn s.PrivKey[:]\n}\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/scheme/gmsm/gmsm.go#L12-L48","documentation":"SM2ECDH.SetPrivateKey requires at least 32 bytes of private key material before copying it into the fixed 32-byte PrivKey array and constructing an ecdh.P256 private key. Shorter input cannot be a valid 32-byte P-256/SM2 scalar, so the library fails fast with this error. It mirrors the curve25519 scheme's length guard for the SM cipher suite.","triggerScenarios":"Calling (*SM2ECDH).SetPrivateKey (directly or via ECDHFromKey) with a byte slice shorter than 32 bytes — e.g. a truncated base64-decoded key, a 31-byte raw scalar, or an empty slice when the key failed to load from config.","commonSituations":"Configuring the GMSM cipher scheme with a key generated by `keygen --curve` (wrong key type) whose stored text is shorter; missing or truncated value in config.toml's privateKey field; base64 decoding errors handled by ignoring partial output.","solutions":["Verify the key input is exactly 32 bytes (44-char standard base64) before calling SetPrivateKey.","Regenerate SM2 keys with `keygen --sm2` and use the full private key string from the output.","Confirm the key loaded from config is non-empty and not truncated (log its decoded length).","Use the scheme's Base64DecodeSM2ECDHPrivateKey helper, which enforces the same 32-byte check with a clearer boundary."],"exampleFix":"// before\nerr := ecdh.SetPrivateKey([]byte(cfg.PrivateKey)) // raw config text, wrong length\n// after\nraw, err := base64.StdEncoding.DecodeString(cfg.PrivateKey)\nif err != nil || len(raw) != gmsm.PrivateKeySize {\n\treturn fmt.Errorf(\"invalid SM2 private key: decoded %d bytes\", len(raw))\n}\nerr = ecdh.SetPrivateKey(raw)","handlingStrategy":"validation","validationCode":"// Go\nraw, err := base64.StdEncoding.DecodeString(keyStr)\nif err != nil || len(raw) != gmsm.PrivateKeySize { // 32\n\treturn fmt.Errorf(\"SM2 private key must decode to 32 bytes\")\n}\nerr = ecdhe.SetPrivateKey(raw)","typeGuard":null,"tryCatchPattern":"if err := ecdhe.SetPrivateKey(prk); err != nil {\n\tif strings.Contains(err.Error(), \"private key too short\") {\n\t\t// fall back to regenerating keys or abort startup with a clear config message\n\t}\n\treturn err\n}","preventionTips":["Keep curve and sm2 keys in separate config fields and never cross-assign them.","Assert the config key decodes to exactly 32 bytes at load time, before any SetPrivateKey call.","Use `keygen --sm2` (not --curve) when configuring the GMSM cipher scheme.","Log decoded key lengths (not contents) when initializing ECDH to catch truncation early."],"tags":["crypto","ecdh","sm2","key-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}