init: v1.0.0
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
// Package blockmodes 使用BlockEncrypter接口封装GCM、CCM等加密模式。
|
||||
// 适用于将密码机、ukey的ECB加密模式封装为GCM、CCM等加密模式。
|
||||
package blockmode
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
)
|
||||
|
||||
// var errorCodeBase = gcl.ErrorCodeBaseMap[PACKAGE_NAME]
|
||||
|
||||
// EcbBlockMode 是对多组数据进行加密/解密运算。可以对密码机等的ECB加密进行封装后得到。
|
||||
// GCM模式、CTR等模式将基于EcbBlockMode进行计算。
|
||||
// 注:由于Cipher.NewGCM的入参是cipher.Block, 针对单组数据进行的运算,不适合密码机等,
|
||||
// 否则每个分组都要调用密码机或ukey,调用消耗巨大。所以这里使用多组加密接口进行GCM、CTR、CCM
|
||||
// 等封装。
|
||||
type EcbBlockMode interface {
|
||||
// 每个分组长度
|
||||
BlockSize() int
|
||||
|
||||
// CryptBlocks 加密多组数据。传入src保证是BlockSize()的整数倍,len(dst) >= len(src)
|
||||
// 加密完成后dst[:len(src)]为(ECB)密文。
|
||||
// 如果src非常大,BlockEncrypter负责进行分组调用密码机, 可能因为网络等原因会返回错误。
|
||||
// 本函数为阻塞函数
|
||||
EcbEncCryptBlocks(dst, src []byte) error
|
||||
EcbDecCryptBlocks(dst, src []byte) error
|
||||
}
|
||||
|
||||
// CbcBlockMode CBC计算。BlockEncrypter对象也可以做CBC,但是,如果每次分组都去调密码卡或ukey,会非常慢。
|
||||
type CbcBlockMode interface {
|
||||
// 分组长度
|
||||
BlockSize() int
|
||||
|
||||
// CBCEncrypt CBC加密多组数据。传入src保证是BlockSize()的整数倍,len(dst) >= len(src)
|
||||
// iv是BlockSize()大小。 dst和src要么完全重合,要么完全不相交
|
||||
// 返回时:如果正常则填充dst[:len(src)]为密文。iv返回时不作要求,可以保持不变,也可以为最后一个分组内容。
|
||||
// 如果src非常大,CBCEncrypter负责进行分组调用密码机, 可能因为网络等原因会返回错误。
|
||||
// 本函数为阻塞函数
|
||||
CbcEncCryptBlocks(dst, iv, src []byte) error
|
||||
CbcDecCryptBlocks(dst, iv, src []byte) error
|
||||
}
|
||||
|
||||
type EcbCbcBlockMode interface {
|
||||
EcbBlockMode
|
||||
CbcBlockMode
|
||||
}
|
||||
|
||||
// 三段式加解密接口
|
||||
type TernaryCrypter interface {
|
||||
// 三段式加密
|
||||
// Init an BlockUpdater. Set nonce as iv and additional data.
|
||||
EncryptInit(iv []byte) error
|
||||
|
||||
// Encrypt 单组加密,等价于调用EncryptUpdate后EncryptFinal
|
||||
Encrypt(dst []byte, in []byte) ([]byte, error)
|
||||
|
||||
// Update appends the encrypted/decrypted result to dst and return it
|
||||
EncryptUpdate(dst []byte, in []byte) ([]byte, error)
|
||||
// Final 将剩余密文和tag append到out上并返回。返回结果的最后16字节为tag.
|
||||
EncryptFinal(dst []byte) ([]byte, error)
|
||||
|
||||
// 三段式解密
|
||||
DecryptInit(iv []byte) error
|
||||
Decrypt(dst []byte, in []byte) ([]byte, error)
|
||||
DecryptUpdate(dst []byte, in []byte) ([]byte, error)
|
||||
DecryptFinal(dst []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
// TernaryGCM 标准库cipher.AEAD和SDF/SKF的三段式用法。
|
||||
// 在三段式调用中,若某次返回错误(比如某个大文件已经EncryptUpdate多次了,但如果某次网络原因
|
||||
// EncryptUpdate返回错误),则保证内部状态不变, 可以重复该次返错的调用。
|
||||
type TernaryGCM interface {
|
||||
// 保留标准库用法,AEAD.Seal和AEAD.Open前无需调用EncryptInit/DecryptInit
|
||||
cipher.AEAD
|
||||
|
||||
// SpecifyADD 在三段式调用中必须在调用EncryptInit后调用
|
||||
ADDSpecifier
|
||||
TernaryCrypter
|
||||
}
|
||||
|
||||
type ADDSpecifier interface {
|
||||
SpecifyADD(additionalData []byte)
|
||||
}
|
||||
|
||||
type ADDAndDataLenSpecifier interface {
|
||||
SpecifyADDAndDataLen(ad []byte, dataLen int)
|
||||
}
|
||||
|
||||
// Stream for ctr mode
|
||||
type TernaryStream interface {
|
||||
cipher.Stream
|
||||
TernaryCrypter
|
||||
}
|
||||
|
||||
// Wrapper 将一个cipher.Block接口包装为EcbCbcEncBlockMode接口
|
||||
type wrapper struct {
|
||||
cipher.Block
|
||||
}
|
||||
|
||||
func Wrap(b cipher.Block) EcbCbcBlockMode {
|
||||
// If b is also an EcbCbcBlockMode interface.
|
||||
if bm, ok := b.(EcbCbcBlockMode); ok {
|
||||
return bm
|
||||
}
|
||||
return wrapper{b}
|
||||
}
|
||||
|
||||
func (w wrapper) BlockSize() int {
|
||||
return w.Block.BlockSize()
|
||||
}
|
||||
|
||||
func (w wrapper) EcbEncCryptBlocks(dst, src []byte) error {
|
||||
for len(src) > 0 {
|
||||
w.Encrypt(dst, src)
|
||||
dst = dst[w.BlockSize():]
|
||||
src = src[w.BlockSize():]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w wrapper) CbcEncCryptBlocks(dst, iv, src []byte) error {
|
||||
cbc := cipher.NewCBCEncrypter(w.Block, iv)
|
||||
cbc.CryptBlocks(dst, src)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w wrapper) EcbDecCryptBlocks(dst, src []byte) error {
|
||||
for len(src) > 0 {
|
||||
w.Decrypt(dst, src)
|
||||
dst = dst[w.BlockSize():]
|
||||
src = src[w.BlockSize():]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w wrapper) CbcDecCryptBlocks(dst, iv, src []byte) error {
|
||||
cbc := cipher.NewCBCDecrypter(w.Block, iv)
|
||||
cbc.CryptBlocks(dst, src)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user