feat(db): 添加对达梦数据库的支持
- 在应用程序中新增对达梦数据库(DM)的配置和连接支持 - 实现 SetDmDB 函数以配置达梦数据库连接 - 更新数据库操作逻辑,支持达梦特有的 SQL 语法和功能 - 在相关文件中添加达梦数据库的处理逻辑,包括表创建、数据插入和查询 - 更新 go.mod 和 go.sum 文件以引入达梦数据库驱动 - 增强文档,详细说明达梦数据库的配置和使用方法
This commit is contained in:
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2018, 达梦数据库有限公司.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
package security
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type ThirdPartCipher struct {
|
||||
encryptType int // 外部加密算法id
|
||||
encryptName string // 外部加密算法名称
|
||||
hashType int
|
||||
key []byte
|
||||
cipherCount int // 外部加密算法个数
|
||||
//innerId int // 外部加密算法内部id
|
||||
blockSize int // 分组块大小
|
||||
khSize int // key/hash大小
|
||||
}
|
||||
|
||||
func NewThirdPartCipher(encryptType int, key []byte, cipherPath string, hashType int) (ThirdPartCipher, error) {
|
||||
var tpc = ThirdPartCipher{
|
||||
encryptType: encryptType,
|
||||
key: key,
|
||||
hashType: hashType,
|
||||
cipherCount: -1,
|
||||
}
|
||||
var err error
|
||||
err = initThirdPartCipher(cipherPath)
|
||||
if err != nil {
|
||||
return tpc, err
|
||||
}
|
||||
tpc.getCount()
|
||||
if err = tpc.getInfo(); err != nil {
|
||||
return tpc, err
|
||||
}
|
||||
return tpc, nil
|
||||
}
|
||||
|
||||
func (tpc *ThirdPartCipher) getCount() int {
|
||||
if tpc.cipherCount == -1 {
|
||||
tpc.cipherCount = cipherGetCount()
|
||||
}
|
||||
return tpc.cipherCount
|
||||
}
|
||||
|
||||
func (tpc *ThirdPartCipher) getInfo() error {
|
||||
var cipher_id, ty, blk_size, kh_size int
|
||||
//var strptr, _ = syscall.UTF16PtrFromString(tpc.encryptName)
|
||||
var strptr *uint16 = new(uint16)
|
||||
for i := 1; i <= tpc.getCount(); i++ {
|
||||
cipherGetInfo(uintptr(i), uintptr(unsafe.Pointer(&cipher_id)), uintptr(unsafe.Pointer(&strptr)),
|
||||
uintptr(unsafe.Pointer(&ty)), uintptr(unsafe.Pointer(&blk_size)), uintptr(unsafe.Pointer(&kh_size)))
|
||||
if tpc.encryptType == cipher_id {
|
||||
tpc.blockSize = blk_size
|
||||
tpc.khSize = kh_size
|
||||
tpc.encryptName = string(uintptr2bytes(uintptr(unsafe.Pointer(strptr))))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("ThirdPartyCipher: cipher id:%d not found", tpc.encryptType)
|
||||
}
|
||||
|
||||
func (tpc ThirdPartCipher) Encrypt(plaintext []byte, genDigest bool) []byte {
|
||||
var tmp_para uintptr
|
||||
cipherEncryptInit(uintptr(tpc.encryptType), uintptr(unsafe.Pointer(&tpc.key[0])), uintptr(len(tpc.key)), tmp_para)
|
||||
|
||||
ciphertextLen := cipherGetCipherTextSize(uintptr(tpc.encryptType), tmp_para, uintptr(len(plaintext)))
|
||||
|
||||
ciphertext := make([]byte, ciphertextLen)
|
||||
ret := cipherEncrypt(uintptr(tpc.encryptType), tmp_para, uintptr(unsafe.Pointer(&plaintext[0])), uintptr(len(plaintext)),
|
||||
uintptr(unsafe.Pointer(&ciphertext[0])), uintptr(len(ciphertext)))
|
||||
ciphertext = ciphertext[:ret]
|
||||
|
||||
cipherClean(uintptr(tpc.encryptType), tmp_para)
|
||||
// md5摘要
|
||||
if genDigest {
|
||||
digest := md5.Sum(plaintext)
|
||||
encrypt := ciphertext
|
||||
ciphertext = make([]byte, len(encrypt)+len(digest))
|
||||
copy(ciphertext[:len(encrypt)], encrypt)
|
||||
copy(ciphertext[len(encrypt):], digest[:])
|
||||
}
|
||||
return ciphertext
|
||||
}
|
||||
|
||||
func (tpc ThirdPartCipher) Decrypt(ciphertext []byte, checkDigest bool) ([]byte, error) {
|
||||
var ret []byte
|
||||
if checkDigest {
|
||||
var digest = ciphertext[len(ciphertext)-MD5_DIGEST_SIZE:]
|
||||
ret = ciphertext[:len(ciphertext)-MD5_DIGEST_SIZE]
|
||||
ret = tpc.decrypt(ret)
|
||||
var msgDigest = md5.Sum(ret)
|
||||
if !reflect.DeepEqual(msgDigest[:], digest) {
|
||||
return nil, errors.New("Decrypt failed/Digest not match\n")
|
||||
}
|
||||
} else {
|
||||
ret = tpc.decrypt(ciphertext)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (tpc ThirdPartCipher) decrypt(ciphertext []byte) []byte {
|
||||
var tmp_para uintptr
|
||||
|
||||
cipherDecryptInit(uintptr(tpc.encryptType), uintptr(unsafe.Pointer(&tpc.key[0])), uintptr(len(tpc.key)), tmp_para)
|
||||
|
||||
plaintext := make([]byte, len(ciphertext))
|
||||
ret := cipherDecrypt(uintptr(tpc.encryptType), tmp_para, uintptr(unsafe.Pointer(&ciphertext[0])), uintptr(len(ciphertext)),
|
||||
uintptr(unsafe.Pointer(&plaintext[0])), uintptr(len(plaintext)))
|
||||
plaintext = plaintext[:ret]
|
||||
|
||||
cipherClean(uintptr(tpc.encryptType), tmp_para)
|
||||
return plaintext
|
||||
}
|
||||
|
||||
func addBufSize(buf []byte, newCap int) []byte {
|
||||
newBuf := make([]byte, newCap)
|
||||
copy(newBuf, buf)
|
||||
return newBuf
|
||||
}
|
||||
|
||||
func uintptr2bytes(p uintptr) []byte {
|
||||
buf := make([]byte, 64)
|
||||
i := 0
|
||||
for b := (*byte)(unsafe.Pointer(p)); *b != 0; i++ {
|
||||
if i > cap(buf) {
|
||||
buf = addBufSize(buf, i*2)
|
||||
}
|
||||
buf[i] = *b
|
||||
// byte占1字节
|
||||
p++
|
||||
b = (*byte)(unsafe.Pointer(p))
|
||||
}
|
||||
return buf[:i]
|
||||
}
|
||||
Reference in New Issue
Block a user