github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/internal/runner/block_crypto.go (about) 1 // Copyright 2018-2020 (c) Cognizant Digital Business, Evolutionary AI. All rights reserved. Issued under the Apache 2.0 License. 2 3 package runner 4 5 import ( 6 "crypto/rand" 7 "io" 8 9 "github.com/go-stack/stack" 10 "github.com/jjeffery/kv" 11 12 "golang.org/x/crypto/nacl/secretbox" 13 ) 14 15 // This file contains code to enable the encryption and decryption of larger 16 // blocks of data than RSA encryption is suited for. These functions 17 // allow symetric key encryption on larger blocks of data with the expectation 18 // that the symmetric key will ne encrypted using an asymmetric RSA and placed 19 // at the front of a data block or file. 20 // 21 // This set of functions use the nacl compatible secretbox implementation to 22 // encrypt the contents of the payload with the secret key being obtained 23 // from an RSA encrypted header at the start of the bytes block. 24 // 25 // This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html. 26 // 27 // This package works using a 32 byte secret key, a 24 byte nonce, and then the payload. 28 29 // EncryptBlock will generate a nonce, and a secret and will encrypted the supplied 30 // data using the generated key bundling a 24 byte nonce with it returning the key, 31 // and the encoded data with the nonce prepended to it. 32 33 func EncryptBlock(data []byte) (key [32]byte, enc []byte, err kv.Error) { 34 key = [32]byte{} 35 if _, errGo := io.ReadFull(rand.Reader, key[:]); errGo != nil { 36 return key, nil, kv.Wrap(errGo, "secret could not be generated").With("stack", stack.Trace().TrimRuntime()) 37 } 38 39 nonce := [24]byte{} 40 if _, errGo := io.ReadFull(rand.Reader, nonce[:]); errGo != nil { 41 return key, nil, kv.Wrap(errGo, "nonce could not be generated").With("stack", stack.Trace().TrimRuntime()) 42 } 43 44 encrypted := secretbox.Seal(nonce[:], data, &nonce, &key) 45 46 return key, encrypted, nil 47 } 48 49 func DecryptBlock(key [32]byte, in []byte) (clear []byte, err kv.Error) { 50 51 decryptNonce := [24]byte{} 52 copy(decryptNonce[:], in[:24]) 53 54 decrypted, ok := secretbox.Open(nil, in[24:], &decryptNonce, &key) 55 if !ok { 56 return nil, kv.NewError("decryption failure").With("stack", stack.Trace().TrimRuntime()) 57 } 58 59 return decrypted, nil 60 }