{"record":{"id":"14b891e6844a0334","repo":"OpenNHP/opennhp","slug":"size-incorrect-14b891","errorCode":null,"errorMessage":"size incorrect","messagePattern":"size incorrect","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/scheme/gmsm/gmsm.go","lineNumber":134,"sourceCode":"\n\tpKey, err := ecdh.P256().GenerateKey(rand.Reader)\n\tif err != nil {\n\t\treturn \"\", \"\"\n\t}\n\tcopy(privKey[:32], pKey.Bytes()[:32])             // Private Key 32 bytes\n\tcopy(pubKey[:64], pKey.PublicKey().Bytes()[1:65]) // Public Key 64 bytes\n\n\treturn base64.StdEncoding.EncodeToString(pubKey[:]),\n\t\tbase64.StdEncoding.EncodeToString(privKey[:])\n}\n\nfunc Base64DecodeSM2ECDHPrivateKey(privStr string) (*ecdh.PrivateKey, error) {\n\tprivKeyBytes, err := base64.StdEncoding.DecodeString(privStr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(privKeyBytes) != 32 {\n\t\treturn nil, fmt.Errorf(\"size incorrect\")\n\t}\n\tprivKey, err := ecdh.P256().NewPrivateKey(privKeyBytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn privKey, nil\n}\n\nfunc Base64DecodeSM2ECDHPublicKey(pubStr string) (*ecdh.PublicKey, error) {\n\tpubKeyBytes, err := base64.StdEncoding.DecodeString(pubStr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(pubKeyBytes) != 64 {\n\t\treturn nil, fmt.Errorf(\"size incorrect\")\n\t}\n\tbuf := make([]byte, 65)\n\tbuf[0] = 4 // public key first byte means uncompressed","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/scheme/gmsm/gmsm.go#L116-L152","documentation":"Base64DecodeSM2ECDHPrivateKey decodes a base64 string and requires the result to be exactly 32 bytes — the size of a raw P-256/SM2 private scalar for ecdh.P256().NewPrivateKey. Any other length is rejected with the terse 'size incorrect' error, preventing invalid scalars from reaching the crypto library.","triggerScenarios":"Calling Base64DecodeSM2ECDSAPrivateKey/... specifically Base64DecodeSM2ECDHPrivateKey with a string whose base64 decoding is not exactly 32 bytes: an empty string, a DER/PEM-encoded key, a base64 string with padding mistakes, or a hex-encoded key pasted where base64 is expected.","commonSituations":"Storing a key as hex ('a3f0...') instead of base64; including a '-----BEGIN...' header; trimming characters when copying the key from a terminal; an older serialized key format from a previous NHP version.","solutions":["Re-encode the 32-byte private scalar with base64.StdEncoding.EncodeToString and store that exact string.","Strip PEM headers/whitespace and ensure the payload is pure standard base64 (not URL-safe, no hex).","Check the decoded length at the call site: len(base64.StdEncoding.DecodeString(s)) == 32.","Regenerate the key pair with `keygen --sm2 --json` and use the emitted private key field directly."],"exampleFix":"// before\npriv, err := gmsm.Base64DecodeSM2ECDHPrivateKey(hexKey) // hex string, wrong format\n// after\nb, err := hex.DecodeString(hexKey)\nif err != nil {\n\treturn err\n}\npriv, err := gmsm.Base64DecodeSM2ECDHPrivateKey(base64.StdEncoding.EncodeToString(b))","handlingStrategy":"validation","validationCode":"// Go\nfunc isSM2ECDHPrivKeyStr(s string) bool {\n\tb, err := base64.StdEncoding.DecodeString(s)\n\treturn err == nil && len(b) == 32\n}\nif !isSM2ECDHPrivKeyStr(privStr) {\n\treturn errors.New(\"private key must be base64 of 32 raw bytes\")\n}","typeGuard":null,"tryCatchPattern":"priv, err := gmsm.Base64DecodeSM2ECDHPrivateKey(privStr)\nif err != nil {\n\tif err.Error() == \"size incorrect\" {\n\t\treturn fmt.Errorf(\"SM2 private key has wrong encoding (expected base64 of 32 bytes): %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Store keys as standard (not URL-safe) base64 with no PEM armor or whitespace.","Reject hex-encoded or DER-encoded key strings at config load time.","Round-trip check: encode-then-decode a stored key in tests to catch format drift.","Regenerate keys with the daemon's keygen so the emitted format always matches the parser."],"tags":["crypto","sm2","base64","key-deserialization"],"backgroundTag":"invalid-argument-format","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"}