OpenNHP/opennhp · error

size incorrect

Error message

size incorrect

What it means

SM2Decrypt returns "size incorrect" when base64.StdEncoding.DecodeString fails on the private-key argument. The message is misleading: it is a base64 decoding failure of privateKeyBase64, not a ciphertext-size problem. (Note the hex.DecodeString error on the line above is also silently discarded — the guard only covers the base64 decode.)

Solutions

  1. Ensure the private key is standard base64 (StdEncoding, not URL-safe, no PEM headers) before calling SM2Decrypt.
  2. Trim whitespace/newlines and quotes from the key string loaded from config.
  3. If the source key is hex or PEM, convert: PEM -> DER -> raw/private bytes -> base64.
  4. Check whether the hex.DecodeString(message) error is the real failure — validate the ciphertext is valid hex too, since its error is currently swallowed.
  5. Prefer keygen-generated keys (`keygen --sm2`) whose export format matches this API.

Example fix

// before
plain, err := core.SM2Decrypt(cfg.SM2PrivateKeyHex, msg) // hex string passed
// after
keyBytes, _ := hex.DecodeString(cfg.SM2PrivateKeyHex)
b64Key := base64.StdEncoding.EncodeToString(keyBytes)
plain, err := core.SM2Decrypt(b64Key, msg)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := base64.StdEncoding.DecodeString(privateKeyB64); err != nil {
    return fmt.Errorf("SM2 private key is not valid base64: %w", err)
}
if _, err := hex.DecodeString(message); err != nil {
    return fmt.Errorf("SM2 ciphertext is not valid hex: %w", err)
}

Try / catch

plain, err := core.SM2Decrypt(keyB64, msg)
if err != nil && err.Error() == "size incorrect" {
    return fmt.Errorf("private key not valid base64: %w", err)
}

Prevention

When it happens

Trigger: Passing a privateKeyBase64 string that is not valid standard base64: raw hex, PEM-wrapped text, whitespace/newlines, URL-safe base64, or a key exported in a non-base64 format.

Common situations: Pasting an SM2 private key from a PEM file or hex dump into config; a config.toml value with trailing newline or quotes; keys generated by another tool that emits hex or DER instead of the expected base64.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/7a108ea5198da3cb. Report an issue: GitHub.

Appendix: source

Thrown at nhp/core/crypto.go:322

	rng := rand.Reader

	ciphertext, err := sm2.EncryptASN1(rng, sm2PublicKey, secretMessage)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
		return "", err
	}
	// Since encryption is a randomized function, ciphertext will be
	// different each time.
	fmt.Printf("Ciphertext: %x\n", ciphertext)
	return hex.EncodeToString(ciphertext), err
}

func SM2Decrypt(privateKeyBase64 string, message string) (string, error) {
	//ASN.1
	ciphertext, err := hex.DecodeString(message)
	privKeyBytes, err := base64.StdEncoding.DecodeString(privateKeyBase64)
	if err != nil {
		return "", fmt.Errorf("size incorrect")
	}

	testkey, err := sm2.NewPrivateKey(privKeyBytes)
	if err != nil {
		log.Fatalf("fail to new private key %v", err)
	}

	sourceText, err := testkey.Decrypt(nil, ciphertext, nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
		return "", err
	}
	return string(sourceText), err
}

// AESEncryption Function
func AESEncrypt(plainText []byte, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)

View on GitHub (pinned to 6e04ca5ff0)