跳到主要内容

Cryptox

cryptox 包提供统一的加密/解密和数字签名接口,支持多种算法。

接口

Cipher

用于加密和解密:

type Cipher interface {
Encrypt(plaintext string) (string, error)
Decrypt(ciphertext string) (string, error)
}

Signer

用于签名和验证:

type Signer interface {
Sign(data string) (signature string, err error)
Verify(data, signature string) (bool, error)
}

CipherSigner

组合加密和签名:

type CipherSigner interface {
Cipher
Signer
}

FixedIVDecrypter

FixedIVDecrypter 由能够使用调用方固定 IV 解密外部 ciphertext 的 block-cipher 模式实现:

type FixedIVDecrypter interface {
DecryptWithFixedIV(ciphertext string) (string, error)
}

VEF 原生 ciphertext 会携带每次生成的新随机 IV,应使用 Cipher.DecryptDecryptWithFixedIV 是 AES-CBC/SM4-CBC 互操作场景的 escape hatch:外部对端发送 未前置 IV 的 base64 ciphertext 时,解密会使用构造时通过 WithAESIvWithSM4Iv 配置的固定 IV。

支持的算法

所有构造函数返回框架的 Cipher / Signer / CipherSigner 接口。编码辅助构造器按算法提供:AES 和 SM4 提供 *FromHex / *FromBase64;RSA、SM2、ECDSA 提供 *FromPEM / *FromHex / *FromBase64;ECIES 提供 bytes、hex 和 base64 构造器。

AES(对称加密)

import "github.com/coldsmirk/vef-framework-go/cryptox"

// key 必须是 16 / 24 / 32 字节,默认 GCM 模式(带认证,IV 自动生成)。
cipher, err := cryptox.NewAES(key)

// 切到 CBC 模式;Encrypt 会生成随机 IV 并前置到 ciphertext。
cbcCipher, err := cryptox.NewAES(key,
cryptox.WithAESMode(cryptox.AesModeCbc),
)

encrypted, err := cipher.Encrypt("hello world")
plaintext, err := cipher.Decrypt(encrypted)

变体:cryptox.NewAESFromHex(keyHex, ...)cryptox.NewAESFromBase64(keyBase64, ...)

如果要和发送 bare ciphertext(未前置 IV)的 AES-CBC 外部系统互操作, 需要配置固定 IV,并调用 FixedIVDecrypter.DecryptWithFixedIV

fixedCipher, err := cryptox.NewAES(key,
cryptox.WithAESMode(cryptox.AesModeCbc),
cryptox.WithAESIv(iv), // 16 字节
)
plaintext, err := fixedCipher.(cryptox.FixedIVDecrypter).DecryptWithFixedIV(peerCiphertext)

RSA(非对称加密 + 签名)

// 私钥在前。
cipher, err := cryptox.NewRSAFromPEM(privatePEM, publicPEM)

encrypted, err := cipher.Encrypt("sensitive data")
plaintext, err := cipher.Decrypt(encrypted)

signature, err := cipher.Sign("important message")
valid, err := cipher.Verify("important message", signature)

变体:cryptox.NewRSA(privateKey, publicKey)(直接接收 *rsa.PrivateKey / *rsa.PublicKey)、cryptox.NewRSAFromHexcryptox.NewRSAFromBase64

RSA 默认加密模式是 RsaModeOAEP;默认签名模式是 RsaSignModePSSRsaModePKCS1v15RsaSignModePKCS1v15 是显式选择的 legacy interop 模式。

SM2(国密 — 非对称)

// 私钥在前。
cipher, err := cryptox.NewSM2FromPEM(privatePEM, publicPEM)

encrypted, err := cipher.Encrypt("data")
plaintext, err := cipher.Decrypt(encrypted)

signature, err := cipher.Sign("data")
valid, err := cipher.Verify("data", signature)

变体:cryptox.NewSM2(privateKey, publicKey)cryptox.NewSM2FromHexcryptox.NewSM2FromBase64

SM4(国密 — 对称)

// key:16 字节。默认模式为 GCM(带认证;每次调用生成 IV)。
cipher, err := cryptox.NewSM4(key)

// 改用 CBC。Encrypt 会生成随机 IV 并前置到 ciphertext。
cbcCipher, err := cryptox.NewSM4(key,
cryptox.WithSM4Mode(cryptox.Sm4ModeCbc),
)

encrypted, err := cipher.Encrypt("data")
plaintext, err := cipher.Decrypt(encrypted)

变体:cryptox.NewSM4FromHexcryptox.NewSM4FromBase64

:::caution SM4 默认使用 GCM NewSM4 默认使用 GCM(与 AES 对齐),而不是 CBC。要解密以 CBC 模式 产生的 SM4 密文,需要显式构造 cryptox.WithSM4Mode(cryptox.Sm4ModeCbc)。 :::

如果要和发送 bare ciphertext(未前置 IV)的 SM4-CBC 外部系统互操作, 需要配置固定 IV,并调用 FixedIVDecrypter.DecryptWithFixedIV(固定 IV 只 作用于这条互操作解密路径,绝不影响 Encrypt):

fixedCipher, err := cryptox.NewSM4(key,
cryptox.WithSM4Mode(cryptox.Sm4ModeCbc),
cryptox.WithSM4Iv(iv), // 16 字节
)
plaintext, err := fixedCipher.(cryptox.FixedIVDecrypter).DecryptWithFixedIV(peerCiphertext)

ECDSA(仅签名)

// 私钥在前。
signer, err := cryptox.NewECDSAFromPEM(privatePEM, publicPEM)

signature, err := signer.Sign("data to sign")
valid, err := signer.Verify("data to sign", signature)

变体:cryptox.NewECDSA(privateKey, publicKey)cryptox.NewECDSAFromHexcryptox.NewECDSAFromBase64

ECIES(仅加密)

ECIES 额外需要曲线参数:

// 私钥字节在前,公钥字节在后,再传曲线。
cipher, err := cryptox.NewECIESFromBytes(privateKeyBytes, publicKeyBytes, cryptox.EciesCurveP256)

encrypted, err := cipher.Encrypt("secret data")
plaintext, err := cipher.Decrypt(encrypted)

变体:cryptox.NewECIES(privateKey, publicKey)(接收 *ecdh.PrivateKey / *ecdh.PublicKey)、cryptox.NewECIESFromHex(..., curve)cryptox.NewECIESFromBase64(..., curve)。支持的曲线:EciesCurveP256EciesCurveP384EciesCurveP521EciesCurveX25519

GenerateECIESKey(curve) 和 ECIES byte parser 会使用传入的 ECIESCurve; 未知 curve 值会 fallback 到 P-256。GenerateECDSAKeyECDSACurve 也是同样规则。

算法对比

算法类型加密签名标准
AES对称国际
RSA非对称国际
ECDSA非对称国际
ECIES非对称国际
SM2非对称国密
SM4对称国密

集成密钥加密

集成引擎(见 Integration)使用对称加密算法 密封存储的密钥。算法通过 vef.integration.secret_algorithm 配置:

加密算法模式
"aes"(默认)AESGCM
"sm4"SM4GCM

配置键的类型是 config.IntegrationSecretAlgorithm;其常量包括 config.IntegrationSecretAlgorithmAES"aes")和 config.IntegrationSecretAlgorithmSM4"sm4")。无法识别的值在配置校验 时会以 config.ErrInvalidIntegrationSecretAlgorithm 失败。

选项、常量和密钥辅助函数

范围公开 API
AES modes/optionsAESMode, AesModeGcm, AesModeCbc, WithAESMode(mode), WithAESIv(iv)
RSA modes/optionsRSAMode, RSASignMode, RsaModeOAEP, RsaModePKCS1v15, RsaSignModePSS, RsaSignModePKCS1v15, WithRSAMode(mode), WithRSASignMode(mode)
SM4 modes/optionsSM4Mode, Sm4ModeGcm, Sm4ModeCbc, WithSM4Mode(mode), WithSM4Iv(iv)
ECDSA curvesECDSACurve, EcdsaCurveP224, EcdsaCurveP256, EcdsaCurveP384, EcdsaCurveP521
ECIES curvesECIESCurve, EciesCurveP256, EciesCurveP384, EciesCurveP521, EciesCurveX25519
key helpersGenerateECDSAKey(curve), GenerateECIESKey(curve)
option typesAESOption, RSAOption, SM4Option

错误哨兵

分组错误
key availabilityErrAtLeastOneKeyRequired, ErrPublicKeyRequiredForEncrypt, ErrPrivateKeyRequiredForDecrypt, ErrPrivateKeyRequiredForSign, ErrPublicKeyRequiredForVerify
key parsing/typeErrFailedDecodePEMBlock, ErrUnsupportedPEMType, ErrNotRSAPrivateKey, ErrNotRSAPublicKey, ErrNotECDSAPrivateKey, ErrNotECDSAPublicKey
symmetric cryptoErrInvalidAESKeySize, ErrInvalidSM4KeySize, ErrInvalidIVSizeCBC, ErrCiphertextNotMultipleOfBlock, ErrCiphertextTooShort, ErrInvalidPadding
input/signatureErrDataEmpty, ErrInvalidSignature