Files
encryptx/desx/desx.go
T
2026-09-30 15:49:12 +08:00

215 lines
7.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package desx 提供 DES 分组密码的加解密封装,支持 ECB/CBC/CFB/OFB/CTR。
//
// # 安全警告
//
// DES 的有效密钥长度只有 56 位,早已可被专用硬件在数小时内暴力破解,
// **不应用于保护任何机密数据**。本包仅为兼容无法改动的既有系统(老银行接口、
// 老式终端、遗留数据库字段)而保留,新系统请使用 AES-GCM 或
// ChaCha20-Poly1305。
//
// 此外,本包所有模式都**不提供完整性保护**:攻击者可以篡改密文而不被发现
// (CFB/OFB/CTR 甚至可以直接翻转明文的任意比特)。若必须使用 DES,请额外
// 配合 HMAC 做「先加密后认证」。
package desx
import (
"crypto/des"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"code.yun.ink/pkg/encryptx/cipherx"
)
const (
// KeySize 是 DES 的密钥长度(字节)。56 位有效强度,已不安全。
KeySize = 8
// BlockSize 是 DES 的分组长度(字节)。
BlockSize = des.BlockSize
)
// Suite 绑定 DES 的分组构造方式与合法密钥长度,模式实现由 cipherx 提供。
//
// 导出它是为了让调用方能够以统一方式驱动任意模式,而无需在本包与 cipherx
// 之间写 switch。
var Suite = cipherx.NewSuite("DES", des.NewCipher, BlockSize, KeySize)
// GenerateKey 用 crypto/rand 生成 8 字节 DES 密钥。
//
// 注意:DES 密钥中的每第 8 位是奇偶校验位,不参与加密,因此实际强度只有
// 56 位。该函数生成的密钥未做校验位设置,可直接使用。
func GenerateKey() ([]byte, error) {
key := make([]byte, KeySize)
if _, err := io.ReadFull(rand.Reader, key); err != nil {
return nil, fmt.Errorf("desx: 生成密钥失败: %w", err)
}
return key, nil
}
// GenerateKeyHex 生成 DES 密钥并以十六进制字符串返回。
//
// 注意:返回值是**编码后的文本**,不能直接当密钥使用。读回后必须先解码
// (encoding/hex 的 DecodeString,或本库的 hexx.Decode),再传给 Encrypt/Decrypt。
func GenerateKeyHex() (string, error) {
key, err := GenerateKey()
if err != nil {
return "", err
}
return hex.EncodeToString(key), nil
}
// ---- ECB ----
//
// 警告:ECB 不具备语义安全性,相同的明文分组会产生相同的密文分组。
// EncryptECB 使用 DES-ECB 加密并做 PKCS#7 填充。
func EncryptECB(plaintext, key []byte) ([]byte, error) {
return Suite.Encrypt(cipherx.ECB, plaintext, key)
}
// DecryptECB 解密 DES-ECB 密文。
func DecryptECB(ciphertext, key []byte) ([]byte, error) {
return Suite.Decrypt(cipherx.ECB, ciphertext, key)
}
// EncryptECBHex 与 EncryptECB 相同,返回大写十六进制字符串。
func EncryptECBHex(plaintext, key []byte) (string, error) {
return Suite.EncryptHex(cipherx.ECB, plaintext, key)
}
// DecryptECBHex 解密十六进制 DES-ECB 密文,大小写均可。
func DecryptECBHex(ciphertextHex string, key []byte) ([]byte, error) {
return Suite.DecryptHex(cipherx.ECB, ciphertextHex, key)
}
// ---- CBC ----
// EncryptCBC 使用 DES-CBC 加密,随机 IV 前置在密文之前。
func EncryptCBC(plaintext, key []byte) ([]byte, error) {
return Suite.Encrypt(cipherx.CBC, plaintext, key)
}
// DecryptCBC 解密 DES-CBC 密文(IV 前置格式)。
func DecryptCBC(ciphertext, key []byte) ([]byte, error) {
return Suite.Decrypt(cipherx.CBC, ciphertext, key)
}
// EncryptCBCHex 与 EncryptCBC 相同,返回大写十六进制字符串。
func EncryptCBCHex(plaintext, key []byte) (string, error) {
return Suite.EncryptHex(cipherx.CBC, plaintext, key)
}
// DecryptCBCHex 解密十六进制 DES-CBC 密文。
func DecryptCBCHex(ciphertextHex string, key []byte) ([]byte, error) {
return Suite.DecryptHex(cipherx.CBC, ciphertextHex, key)
}
// EncryptCBCWithIV 使用调用方指定的 IV 加密,返回值不含 IV。
//
// 仅用于与规定了固定 IV 的既有系统互操作。
func EncryptCBCWithIV(plaintext, key, iv []byte) ([]byte, error) {
return Suite.EncryptWithIV(cipherx.CBC, plaintext, key, iv)
}
// DecryptCBCWithIV 使用调用方指定的 IV 解密。
func DecryptCBCWithIV(ciphertext, key, iv []byte) ([]byte, error) {
return Suite.DecryptWithIV(cipherx.CBC, ciphertext, key, iv)
}
// ---- CFB ----
// EncryptCFB 使用 DES-CFB 加密,随机 IV 前置在密文之前。
func EncryptCFB(plaintext, key []byte) ([]byte, error) {
return Suite.Encrypt(cipherx.CFB, plaintext, key)
}
// DecryptCFB 解密 DES-CFB 密文(IV 前置格式)。
func DecryptCFB(ciphertext, key []byte) ([]byte, error) {
return Suite.Decrypt(cipherx.CFB, ciphertext, key)
}
// EncryptCFBHex 与 EncryptCFB 相同,返回大写十六进制字符串。
func EncryptCFBHex(plaintext, key []byte) (string, error) {
return Suite.EncryptHex(cipherx.CFB, plaintext, key)
}
// DecryptCFBHex 解密十六进制 DES-CFB 密文。
func DecryptCFBHex(ciphertextHex string, key []byte) ([]byte, error) {
return Suite.DecryptHex(cipherx.CFB, ciphertextHex, key)
}
// EncryptCFBWithIV 使用调用方指定的 IV 加密,返回值不含 IV。
func EncryptCFBWithIV(plaintext, key, iv []byte) ([]byte, error) {
return Suite.EncryptWithIV(cipherx.CFB, plaintext, key, iv)
}
// DecryptCFBWithIV 使用调用方指定的 IV 解密。
func DecryptCFBWithIV(ciphertext, key, iv []byte) ([]byte, error) {
return Suite.DecryptWithIV(cipherx.CFB, ciphertext, key, iv)
}
// ---- OFB ----
// EncryptOFB 使用 DES-OFB 加密,随机 IV 前置在密文之前。
func EncryptOFB(plaintext, key []byte) ([]byte, error) {
return Suite.Encrypt(cipherx.OFB, plaintext, key)
}
// DecryptOFB 解密 DES-OFB 密文(IV 前置格式)。
func DecryptOFB(ciphertext, key []byte) ([]byte, error) {
return Suite.Decrypt(cipherx.OFB, ciphertext, key)
}
// EncryptOFBHex 与 EncryptOFB 相同,返回大写十六进制字符串。
func EncryptOFBHex(plaintext, key []byte) (string, error) {
return Suite.EncryptHex(cipherx.OFB, plaintext, key)
}
// DecryptOFBHex 解密十六进制 DES-OFB 密文。
func DecryptOFBHex(ciphertextHex string, key []byte) ([]byte, error) {
return Suite.DecryptHex(cipherx.OFB, ciphertextHex, key)
}
// EncryptOFBWithIV 使用调用方指定的 IV 加密,返回值不含 IV。
func EncryptOFBWithIV(plaintext, key, iv []byte) ([]byte, error) {
return Suite.EncryptWithIV(cipherx.OFB, plaintext, key, iv)
}
// DecryptOFBWithIV 使用调用方指定的 IV 解密。
func DecryptOFBWithIV(ciphertext, key, iv []byte) ([]byte, error) {
return Suite.DecryptWithIV(cipherx.OFB, ciphertext, key, iv)
}
// ---- CTR ----
// EncryptCTR 使用 DES-CTR 加密,随机 IV 前置在密文之前。
func EncryptCTR(plaintext, key []byte) ([]byte, error) {
return Suite.Encrypt(cipherx.CTR, plaintext, key)
}
// DecryptCTR 解密 DES-CTR 密文(IV 前置格式)。
func DecryptCTR(ciphertext, key []byte) ([]byte, error) {
return Suite.Decrypt(cipherx.CTR, ciphertext, key)
}
// EncryptCTRHex 与 EncryptCTR 相同,返回大写十六进制字符串。
func EncryptCTRHex(plaintext, key []byte) (string, error) {
return Suite.EncryptHex(cipherx.CTR, plaintext, key)
}
// DecryptCTRHex 解密十六进制 DES-CTR 密文。
func DecryptCTRHex(ciphertextHex string, key []byte) ([]byte, error) {
return Suite.DecryptHex(cipherx.CTR, ciphertextHex, key)
}
// EncryptCTRWithIV 使用调用方指定的 IV 加密,返回值不含 IV。
func EncryptCTRWithIV(plaintext, key, iv []byte) ([]byte, error) {
return Suite.EncryptWithIV(cipherx.CTR, plaintext, key, iv)
}
// DecryptCTRWithIV 使用调用方指定的 IV 解密。
func DecryptCTRWithIV(ciphertext, key, iv []byte) ([]byte, error) {
return Suite.DecryptWithIV(cipherx.CTR, ciphertext, key, iv)
}