github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/encrypt/crypto/option.go (about) 1 package crypto 2 3 import ( 4 "encoding/base32" 5 "encoding/base64" 6 ) 7 8 type options struct { 9 // encode will be called to transform the encrypted data 10 encoder func([]byte) ([]byte, error) 11 12 // decode will be called before data being decrypted 13 decoder func([]byte) ([]byte, error) 14 15 // use custom nonce size for AES GCM mode, default: 12 16 nonceSize int 17 18 // key size of new key for AES GCM mode, must be 16, 24 or 32, default: 32 19 keySize int 20 21 // specify additional data for AES GCM mode, default: nil 22 additionalData []byte 23 } 24 25 // Option may be used to customize the encrypt and decrypt functions behavior. 26 type Option func(opt *options) 27 28 func (p *options) apply(opts ...Option) *options { 29 for _, opt := range opts { 30 opt(p) 31 } 32 return p 33 } 34 35 func (p *options) encode(data []byte) ([]byte, error) { 36 if p.encoder != nil { 37 return p.encoder(data) 38 } 39 return data, nil 40 } 41 42 func (p *options) decode(data []byte) ([]byte, error) { 43 if p.decoder != nil { 44 return p.decoder(data) 45 } 46 return data, nil 47 } 48 49 // NonceSize optionally specifies the size of nonce, it returns an Option. 50 func NonceSize(size int) Option { 51 return func(opt *options) { opt.nonceSize = size } 52 } 53 54 // KeySize optionally specifies a key size to use with GCMEncryptNewKey, 55 // it returns an Option. 56 func KeySize(size int) Option { 57 return func(opt *options) { opt.keySize = size } 58 } 59 60 // AdditionalData optionally specifies the additional data to use with 61 // GCM mode, it returns an Option. 62 func AdditionalData(data []byte) Option { 63 return func(opt *options) { opt.additionalData = data } 64 } 65 66 // Encoder optionally specifies an encoder function to encode the encrypted 67 // ciphertext, it returns an Option. 68 // 69 // The encoder function may transform arbitrary bytes to a new byte slice 70 // of some form. 71 func Encoder(f func([]byte) ([]byte, error)) Option { 72 return func(opt *options) { opt.encoder = f } 73 } 74 75 // Decoder optionally specifies a decoder function to decode the encrypted 76 // ciphertext, it returns an Option. 77 // 78 // The decoder function should transform bytes returned by the corresponding 79 // encoder function to its original bytes. 80 func Decoder(f func([]byte) ([]byte, error)) Option { 81 return func(opt *options) { opt.decoder = f } 82 } 83 84 // Base64 specifies the encoder and decoder to use the provided base64 85 // encoding, it returns an Option. 86 // 87 // If enc is nil, it uses base64.StdEncoding. 88 func Base64(enc *base64.Encoding) Option { 89 if enc == nil { 90 enc = base64.StdEncoding 91 } 92 return func(opt *options) { 93 opt.encoder = func(src []byte) ([]byte, error) { 94 dst := make([]byte, enc.EncodedLen(len(src))) 95 enc.Encode(dst, src) 96 return dst, nil 97 } 98 opt.decoder = func(src []byte) ([]byte, error) { 99 dst := make([]byte, enc.DecodedLen(len(src))) 100 n, err := enc.Decode(dst, src) 101 if err != nil { 102 return nil, err 103 } 104 return dst[:n], nil 105 } 106 } 107 } 108 109 // Base32 specifies the encoder and decoder to use the provided base32 110 // encoding, it returns an Option. 111 // 112 // If enc is nil, it uses base32.StdEncoding. 113 func Base32(enc *base32.Encoding) Option { 114 if enc == nil { 115 enc = base32.StdEncoding 116 } 117 return func(opt *options) { 118 opt.encoder = func(src []byte) ([]byte, error) { 119 dst := make([]byte, enc.EncodedLen(len(src))) 120 enc.Encode(dst, src) 121 return dst, nil 122 } 123 opt.decoder = func(src []byte) ([]byte, error) { 124 dst := make([]byte, enc.DecodedLen(len(src))) 125 n, err := enc.Decode(dst, src) 126 if err != nil { 127 return nil, err 128 } 129 return dst[:n], nil 130 } 131 } 132 }